Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 22 Apr 2010 14:50:11 +0000 (07:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 22 Apr 2010 14:50:11 +0000 (07:50 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] bnx2i: Bug fixes related to MTU change issue when there are active iscsi sessions
  [SCSI] ibmvscsi: fix DMA API misuse
  [SCSI] wd7000: fix reset handler typo spin_unlock_irq() => spin_lock_irq()
  [SCSI] zfcp: Fix tracing of requests with error status
  [SCSI] zfcp: Update MAINTAINERS entry
  [SCSI] iscsi_tcp: fix relogin/shutdown hang
  [SCSI] qla2xxx: fix lock imbalance
  [SCSI] lpfc: fix lock imbalances
  [SCSI] be2iscsi: fix lock imbalance
  [SCSI] dpt_i2o: several use after free issues

410 files changed:
Documentation/DocBook/tracepoint.tmpl
Documentation/RCU/NMI-RCU.txt
Documentation/RCU/checklist.txt
Documentation/RCU/lockdep.txt
Documentation/RCU/whatisRCU.txt
Documentation/block/biodoc.txt
Documentation/input/multi-touch-protocol.txt
Documentation/kernel-parameters.txt
Documentation/networking/timestamping.txt
MAINTAINERS
Makefile
arch/arm/boot/compressed/head.S
arch/arm/include/asm/highmem.h
arch/arm/include/asm/kmap_types.h
arch/arm/include/asm/ucontext.h
arch/arm/include/asm/user.h
arch/arm/kernel/signal.c
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/pm_slowclock.S
arch/arm/mach-bcmring/dma.c
arch/arm/mach-ep93xx/gpio.c
arch/arm/mach-mx3/Kconfig
arch/arm/mach-mx3/clock-imx31.c
arch/arm/mach-mx3/devices.c
arch/arm/mach-mx3/devices.h
arch/arm/mach-mx3/mach-armadillo5x0.c
arch/arm/mach-mx3/mach-mx31_3ds.c
arch/arm/mach-mx3/mach-pcm037.c
arch/arm/mach-mx3/mx31lite-db.c
arch/arm/mach-mx5/clock-mx51.c
arch/arm/mach-mx5/cpu.c
arch/arm/mach-mx5/mm.c
arch/arm/mm/copypage-v6.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/flush.c
arch/arm/mm/highmem.c
arch/arm/mm/mmu.c
arch/arm/plat-mxc/include/mach/board-mx31_3ds.h [moved from arch/arm/plat-mxc/include/mach/board-mx31pdk.h with 93% similarity]
arch/arm/plat-mxc/include/mach/mx51.h
arch/arm/plat-mxc/include/mach/uncompress.h
arch/arm/vfp/vfpmodule.c
arch/ia64/kvm/kvm-ia64.c
arch/m68k/include/asm/atomic_mm.h
arch/m68k/include/asm/mcfuart.h
arch/m68k/include/asm/sigcontext.h
arch/m68knommu/Makefile
arch/m68knommu/kernel/entry.S
arch/m68knommu/platform/68360/ints.c
arch/mips/alchemy/devboards/db1200/setup.c
arch/mips/ar7/platform.c
arch/mips/bcm63xx/boards/board_bcm963xx.c
arch/mips/bcm63xx/cpu.c
arch/mips/bcm63xx/dev-uart.c
arch/mips/bcm63xx/gpio.c
arch/mips/cavium-octeon/setup.c
arch/mips/cavium-octeon/smp.c
arch/mips/configs/bigsur_defconfig
arch/mips/include/asm/abi.h
arch/mips/include/asm/elf.h
arch/mips/include/asm/fpu_emulator.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h [new file with mode: 0644]
arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h
arch/mips/include/asm/mach-sibyte/war.h
arch/mips/include/asm/mmu.h
arch/mips/include/asm/mmu_context.h
arch/mips/include/asm/page.h
arch/mips/include/asm/processor.h
arch/mips/include/asm/stackframe.h
arch/mips/include/asm/uasm.h
arch/mips/include/asm/vdso.h [new file with mode: 0644]
arch/mips/kernel/Makefile
arch/mips/kernel/cpufreq/loongson2_clock.c
arch/mips/kernel/process.c
arch/mips/kernel/signal-common.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mips/kernel/smtc.c
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/vdso.c [new file with mode: 0644]
arch/mips/lib/delay.c
arch/mips/lib/libgcc.h
arch/mips/mm/cache.c
arch/mips/mm/tlbex.c
arch/mips/mm/uasm.c
arch/mips/pci/ops-loongson2.c
arch/mips/sibyte/sb1250/setup.c
arch/powerpc/kvm/book3s.c
arch/s390/defconfig
arch/s390/include/asm/pgtable.h
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/topology.c
arch/s390/mm/vmem.c
arch/sparc/Kconfig
arch/sparc/Kconfig.debug
arch/sparc/include/asm/cpudata_64.h
arch/sparc/include/asm/irqflags_64.h
arch/sparc/include/asm/thread_info_64.h
arch/sparc/kernel/Makefile
arch/sparc/kernel/ftrace.c
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/kgdb_64.c
arch/sparc/kernel/kstack.h
arch/sparc/kernel/nmi.c
arch/sparc/kernel/pci_common.c
arch/sparc/kernel/pcr.c
arch/sparc/kernel/rtrap_64.S
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/time_64.c
arch/sparc/kernel/traps_64.c
arch/sparc/kernel/unaligned_64.c
arch/sparc/kernel/vmlinux.lds.S
arch/sparc/lib/mcount.S
arch/x86/ia32/ia32entry.S
arch/x86/include/asm/amd_iommu_types.h
arch/x86/include/asm/lguest_hcall.h
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/crash.c
arch/x86/kernel/dumpstack.h
arch/x86/kernel/pci-gart_64.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/lguest/boot.c
arch/x86/lguest/i386_head.S
block/Kconfig
block/blk-settings.c
block/blk-sysfs.c
block/cfq-iosched.c
block/elevator.c
drivers/acpi/acpica/exprep.c
drivers/base/memory.c
drivers/block/DAC960.c
drivers/block/drbd/drbd_actlog.c
drivers/block/drbd/drbd_bitmap.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
drivers/block/loop.c
drivers/block/paride/pcd.c
drivers/block/paride/pf.c
drivers/block/paride/pt.c
drivers/block/virtio_blk.c
drivers/char/agp/intel-agp.c
drivers/char/pcmcia/cm4000_cs.c
drivers/firewire/core-cdev.c
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_debug.c
drivers/gpu/drm/i915/i915_gem_tiling.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dvo.c
drivers/gpu/drm/i915/intel_fb.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_modes.c
drivers/gpu/drm/i915/intel_overlay.c
drivers/gpu/drm/i915/intel_sdvo.c
drivers/gpu/drm/i915/intel_tv.c
drivers/gpu/drm/nouveau/Makefile
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_bios.h
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_debugfs.c
drivers/gpu/drm/nouveau/nouveau_dp.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_encoder.h
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_irq.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv40_fifo.c
drivers/gpu/drm/nouveau/nv40_graph.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nv50_display.h
drivers/gpu/drm/nouveau/nv50_fbcon.c
drivers/gpu/drm/nouveau/nv50_gpio.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_grctx.c
drivers/gpu/drm/nouveau/nv50_instmem.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r100_track.h
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r600_audio.c
drivers/gpu/drm/radeon/r600_hdmi.c
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_combios.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_family.h
drivers/gpu/drm/radeon/radeon_legacy_encoders.c
drivers/gpu/drm/radeon/reg_srcs/r300
drivers/gpu/drm/radeon/reg_srcs/r420
drivers/gpu/drm/radeon/reg_srcs/rs600
drivers/gpu/drm/radeon/reg_srcs/rv515
drivers/gpu/drm/radeon/rs600.c
drivers/hwmon/applesmc.c
drivers/hwmon/it87.c
drivers/hwmon/sht15.c
drivers/i2c/busses/i2c-imx.c
drivers/i2c/busses/i2c-omap.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-stu300.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/hw/mlx4/mr.c
drivers/infiniband/hw/nes/nes_verbs.c
drivers/input/input.c
drivers/input/keyboard/matrix_keypad.c
drivers/input/mouse/alps.c
drivers/input/mouse/bcm5974.c
drivers/input/serio/i8042.c
drivers/input/sparse-keymap.c
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/gigaset/capi.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/proc.c
drivers/isdn/gigaset/ser-gigaset.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/lguest/lguest_device.c
drivers/lguest/x86/core.c
drivers/md/raid5.c
drivers/net/cnic.c
drivers/net/e1000e/netdev.c
drivers/net/forcedeth.c
drivers/net/igb/igb_ethtool.c
drivers/net/igb/igb_main.c
drivers/net/myri10ge/myri10ge.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/qlcnic/qlcnic_hw.c
drivers/net/r6040.c
drivers/net/stmmac/stmmac_main.c
drivers/net/tun.c
drivers/net/virtio_net.c
drivers/net/wan/hdlc_ppp.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-calib.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/pcmcia/cistpl.c
drivers/pcmcia/db1xxx_ss.c
drivers/pcmcia/ds.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/regulator/mc13783-regulator.c
drivers/s390/char/sclp_async.c
drivers/scsi/sd.c
drivers/serial/mcf.c
drivers/serial/serial_cs.c
drivers/ssb/driver_pcicore.c
drivers/staging/dt3155/dt3155_drv.c
drivers/vhost/vhost.c
drivers/virtio/virtio_balloon.c
drivers/watchdog/Kconfig
drivers/watchdog/booke_wdt.c
drivers/watchdog/max63xx_wdt.c
fs/afs/mntpt.c
fs/binfmt_flat.c
fs/bio.c
fs/btrfs/extent-tree.c
fs/btrfs/volumes.c
fs/ceph/addr.c
fs/ceph/caps.c
fs/ceph/dir.c
fs/ceph/inode.c
fs/ceph/messenger.c
fs/ceph/osdmap.c
fs/ceph/osdmap.h
fs/ceph/rados.h
fs/ceph/snap.c
fs/ceph/super.h
fs/cifs/cifsfs.c
fs/cifs/cifssmb.c
fs/cifs/file.c
fs/ecryptfs/crypto.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/inode.c
fs/ecryptfs/mmap.c
fs/ecryptfs/super.c
fs/ext2/symlink.c
fs/ext3/symlink.c
fs/fs-writeback.c
fs/jfs/inode.c
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.h
fs/jfs/jfs_inode.h
fs/jfs/namei.c
fs/jfs/resize.c
fs/jfs/symlink.c
fs/logfs/gc.c
fs/logfs/journal.c
fs/logfs/logfs.h
fs/logfs/readwrite.c
fs/logfs/segment.c
fs/logfs/super.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/inode.c
fs/nfs/nfs4proc.c
fs/nfs/write.c
fs/nilfs2/alloc.c
fs/nilfs2/btree.c
fs/nilfs2/ioctl.c
fs/quota/Kconfig
fs/quota/dquot.c
fs/udf/balloc.c
fs/udf/file.c
fs/udf/inode.c
fs/udf/namei.c
fs/udf/udfdecl.h
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/xfs_log.c
include/drm/drm_pciids.h
include/linux/blkdev.h
include/linux/drbd.h
include/linux/drbd_nl.h
include/linux/firewire-cdev.h
include/linux/firewire-constants.h
include/linux/genhd.h
include/linux/i2o.h
include/linux/input/matrix_keypad.h
include/linux/kvm_host.h
include/linux/lcm.h [new file with mode: 0644]
include/linux/nfs_fs_sb.h
include/linux/radix-tree.h
include/linux/rcupdate.h
include/linux/regulator/consumer.h
include/linux/slab.h
include/linux/writeback.h
include/net/x25.h
include/trace/events/block.h
kernel/cred.c
kernel/power/user.c
kernel/rcupdate.c
lib/Kconfig.debug
lib/Makefile
lib/dma-debug.c
lib/lcm.c [new file with mode: 0644]
lib/radix-tree.c
lib/vsprintf.c
mm/backing-dev.c
mm/mmap.c
mm/rmap.c
mm/slab.c
mm/slub.c
mm/util.c
net/bridge/br_multicast.c
net/can/raw.c
net/core/dev.c
net/ipv4/fib_trie.c
net/ipv4/ip_output.c
net/ipv4/udp.c
net/ipv6/ip6_output.c
net/ipv6/udp.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/packet/af_packet.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/x25/af_x25.c
net/x25/x25_facilities.c
net/x25/x25_in.c
security/inode.c
security/selinux/ss/avtab.h
sound/arm/aaci.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_via.c
sound/soc/codecs/wm2000.c
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-pcm-fiq.c
sound/soc/imx/imx-ssi.c
sound/usb/usbmidi.c
virt/kvm/kvm_main.c

index 8bca1d5..e8473ea 100644 (file)
      </address>
     </affiliation>
    </author>
+   <author>
+    <firstname>William</firstname>
+    <surname>Cohen</surname>
+    <affiliation>
+     <address>
+      <email>wcohen@redhat.com</email>
+     </address>
+    </affiliation>
+   </author>
   </authorgroup>
 
   <legalnotice>
 !Iinclude/trace/events/signal.h
   </chapter>
 
+  <chapter id="block">
+   <title>Block IO</title>
+!Iinclude/trace/events/block.h
+  </chapter>
 </book>
index a6d32e6..a8536cb 100644 (file)
@@ -34,7 +34,7 @@ NMI handler.
                cpu = smp_processor_id();
                ++nmi_count(cpu);
 
-               if (!rcu_dereference(nmi_callback)(regs, cpu))
+               if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
                        default_do_nmi(regs);
 
                nmi_exit();
@@ -47,12 +47,13 @@ function pointer.  If this handler returns zero, do_nmi() invokes the
 default_do_nmi() function to handle a machine-specific NMI.  Finally,
 preemption is restored.
 
-Strictly speaking, rcu_dereference() is not needed, since this code runs
-only on i386, which does not need rcu_dereference() anyway.  However,
-it is a good documentation aid, particularly for anyone attempting to
-do something similar on Alpha.
+In theory, rcu_dereference_sched() is not needed, since this code runs
+only on i386, which in theory does not need rcu_dereference_sched()
+anyway.  However, in practice it is a good documentation aid, particularly
+for anyone attempting to do something similar on Alpha or on systems
+with aggressive optimizing compilers.
 
-Quick Quiz:  Why might the rcu_dereference() be necessary on Alpha,
+Quick Quiz:  Why might the rcu_dereference_sched() be necessary on Alpha,
             given that the code referenced by the pointer is read-only?
 
 
@@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
 
 Answer to Quick Quiz
 
-       Why might the rcu_dereference() be necessary on Alpha, given
+       Why might the rcu_dereference_sched() be necessary on Alpha, given
        that the code referenced by the pointer is read-only?
 
        Answer: The caller to set_nmi_callback() might well have
-               initialized some data that is to be used by the
-               new NMI handler.  In this case, the rcu_dereference()
-               would be needed, because otherwise a CPU that received
-               an NMI just after the new handler was set might see
-               the pointer to the new NMI handler, but the old
-               pre-initialized version of the handler's data.
-
-               More important, the rcu_dereference() makes it clear
-               to someone reading the code that the pointer is being
-               protected by RCU.
+               initialized some data that is to be used by the new NMI
+               handler.  In this case, the rcu_dereference_sched() would
+               be needed, because otherwise a CPU that received an NMI
+               just after the new handler was set might see the pointer
+               to the new NMI handler, but the old pre-initialized
+               version of the handler's data.
+
+               This same sad story can happen on other CPUs when using
+               a compiler with aggressive pointer-value speculation
+               optimizations.
+
+               More important, the rcu_dereference_sched() makes it
+               clear to someone reading the code that the pointer is
+               being protected by RCU-sched.
index cbc180f..790d1a8 100644 (file)
@@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome!
        The reason that it is permissible to use RCU list-traversal
        primitives when the update-side lock is held is that doing so
        can be quite helpful in reducing code bloat when common code is
-       shared between readers and updaters.
+       shared between readers and updaters.  Additional primitives
+       are provided for this case, as discussed in lockdep.txt.
 
 10.    Conversely, if you are in an RCU read-side critical section,
        and you don't hold the appropriate update-side lock, you -must-
@@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome!
        requiring SRCU's read-side deadlock immunity or low read-side
        realtime latency.
 
-       Note that, rcu_assign_pointer() and rcu_dereference() relate to
-       SRCU just as they do to other forms of RCU.
+       Note that, rcu_assign_pointer() relates to SRCU just as they do
+       to other forms of RCU.
 
 15.    The whole point of call_rcu(), synchronize_rcu(), and friends
        is to wait until all pre-existing readers have finished before
index fe24b58..d7a49b2 100644 (file)
@@ -32,9 +32,20 @@ checking of rcu_dereference() primitives:
        srcu_dereference(p, sp):
                Check for SRCU read-side critical section.
        rcu_dereference_check(p, c):
-               Use explicit check expression "c".
+               Use explicit check expression "c".  This is useful in
+               code that is invoked by both readers and updaters.
        rcu_dereference_raw(p)
                Don't check.  (Use sparingly, if at all.)
+       rcu_dereference_protected(p, c):
+               Use explicit check expression "c", and omit all barriers
+               and compiler constraints.  This is useful when the data
+               structure cannot change, for example, in code that is
+               invoked only by updaters.
+       rcu_access_pointer(p):
+               Return the value of the pointer and omit all barriers,
+               but retain the compiler constraints that prevent duplicating
+               or coalescsing.  This is useful when when testing the
+               value of the pointer itself, for example, against NULL.
 
 The rcu_dereference_check() check expression can be any boolean
 expression, but would normally include one of the rcu_read_lock_held()
@@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla
 RCU read-side critical sections, in case (2) the ->file_lock prevents
 any change from taking place, and finally, in case (3) the current task
 is the only task accessing the file_struct, again preventing any change
-from taking place.
+from taking place.  If the above statement was invoked only from updater
+code, it could instead be written as follows:
+
+       file = rcu_dereference_protected(fdt->fd[fd],
+                                        lockdep_is_held(&files->file_lock) ||
+                                        atomic_read(&files->count) == 1);
+
+This would verify cases #2 and #3 above, and furthermore lockdep would
+complain if this was used in an RCU read-side critical section unless one
+of these two cases held.  Because rcu_dereference_protected() omits all
+barriers and compiler constraints, it generates better code than do the
+other flavors of rcu_dereference().  On the other hand, it is illegal
+to use rcu_dereference_protected() if either the RCU-protected pointer
+or the RCU-protected data that it points to can change concurrently.
 
 There are currently only "universal" versions of the rcu_assign_pointer()
 and RCU list-/tree-traversal primitives, which do not (yet) check for
index 1dc00ee..cfaac34 100644 (file)
@@ -840,6 +840,12 @@ SRCU:      Initialization/cleanup
        init_srcu_struct
        cleanup_srcu_struct
 
+All:  lockdep-checked RCU-protected pointer access
+
+       rcu_dereference_check
+       rcu_dereference_protected
+       rcu_access_pointer
+
 See the comment headers in the source code (or the docbook generated
 from them) for more information.
 
index 6fab97e..508b5b2 100644 (file)
@@ -1162,8 +1162,8 @@ where a driver received a request ala this before:
 
 As mentioned, there is no virtual mapping of a bio. For DMA, this is
 not a problem as the driver probably never will need a virtual mapping.
-Instead it needs a bus mapping (pci_map_page for a single segment or
-use blk_rq_map_sg for scatter gather) to be able to ship it to the driver. For
+Instead it needs a bus mapping (dma_map_page for a single segment or
+use dma_map_sg for scatter gather) to be able to ship it to the driver. For
 PIO drivers (or drivers that need to revert to PIO transfer once in a
 while (IDE for example)), where the CPU is doing the actual data
 transfer a virtual mapping is needed. If the driver supports highmem I/O,
index 8490480..c0fc1c7 100644 (file)
@@ -68,6 +68,22 @@ like:
    SYN_MT_REPORT
    SYN_REPORT
 
+Here is the sequence after lifting one of the fingers:
+
+   ABS_MT_POSITION_X
+   ABS_MT_POSITION_Y
+   SYN_MT_REPORT
+   SYN_REPORT
+
+And here is the sequence after lifting the remaining finger:
+
+   SYN_MT_REPORT
+   SYN_REPORT
+
+If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
+ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
+last SYN_REPORT will be dropped by the input core, resulting in no
+zero-finger event reaching userland.
 
 Event Semantics
 ---------------
@@ -217,11 +233,6 @@ where examples can be found.
 difference between the contact position and the approaching tool position
 could be used to derive tilt.
 [2] The list can of course be extended.
-[3] The multi-touch X driver is currently in the prototyping stage. At the
-time of writing (April 2009), the MT protocol is not yet merged, and the
-prototype implements finger matching, basic mouse support and two-finger
-scrolling. The project aims at improving the quality of current multi-touch
-functionality available in the Synaptics X driver, and in addition
-implement more advanced gestures.
+[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
 [4] See the section on event computation.
 [5] See the section on finger tracking.
index e4cbca5..e2202e9 100644 (file)
@@ -320,11 +320,6 @@ and is between 256 and 4096 characters. It is defined in the file
        amd_iommu=      [HW,X86-84]
                        Pass parameters to the AMD IOMMU driver in the system.
                        Possible values are:
-                       isolate - enable device isolation (each device, as far
-                                 as possible, will get its own protection
-                                 domain) [default]
-                       share - put every device behind one IOMMU into the
-                               same protection domain
                        fullflush - enable flushing of IO/TLB entries when
                                    they are unmapped. Otherwise they are
                                    flushed before they will be reused, which
index 0e58b45..e8c8f4f 100644 (file)
@@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE:     return system time stamp generated in
 SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
 SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
 following control message:
-    struct scm_timestamping {
-           struct timespec systime;
-           struct timespec hwtimetrans;
-           struct timespec hwtimeraw;
-    };
+
+struct scm_timestamping {
+       struct timespec systime;
+       struct timespec hwtimetrans;
+       struct timespec hwtimeraw;
+};
 
 recvmsg() can be used to get this control message for regular incoming
 packets. For send time stamps the outgoing packet is looped back to
@@ -87,12 +88,13 @@ by the network device and will be empty without that support.
 SIOCSHWTSTAMP:
 
 Hardware time stamping must also be initialized for each device driver
-that is expected to do hardware time stamping. The parameter is:
+that is expected to do hardware time stamping. The parameter is defined in
+/include/linux/net_tstamp.h as:
 
 struct hwtstamp_config {
-    int flags;           /* no flags defined right now, must be zero */
-    int tx_type;         /* HWTSTAMP_TX_* */
-    int rx_filter;       /* HWTSTAMP_FILTER_* */
+       int flags;      /* no flags defined right now, must be zero */
+       int tx_type;    /* HWTSTAMP_TX_* */
+       int rx_filter;  /* HWTSTAMP_FILTER_* */
 };
 
 Desired behavior is passed into the kernel and to a specific device by
@@ -139,42 +141,56 @@ enum {
        /* time stamp any incoming packet */
        HWTSTAMP_FILTER_ALL,
 
-        /* return value: time stamp all packets requested plus some others */
-        HWTSTAMP_FILTER_SOME,
+       /* return value: time stamp all packets requested plus some others */
+       HWTSTAMP_FILTER_SOME,
 
        /* PTP v1, UDP, any kind of event packet */
        HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
 
-        ...
+       /* for the complete list of values, please check
+        * the include file /include/linux/net_tstamp.h
+        */
 };
 
 
 DEVICE IMPLEMENTATION
 
 A driver which supports hardware time stamping must support the
-SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
-in the skb with skb_hwtstamp_set().
+SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
+the actual values as described in the section on SIOCSHWTSTAMP.
+
+Time stamps for received packets must be stored in the skb. To get a pointer
+to the shared time stamp structure of the skb call skb_hwtstamps(). Then
+set the time stamps in the structure:
+
+struct skb_shared_hwtstamps {
+       /* hardware time stamp transformed into duration
+        * since arbitrary point in time
+        */
+       ktime_t hwtstamp;
+       ktime_t syststamp; /* hwtstamp transformed to system time base */
+};
 
 Time stamps for outgoing packets are to be generated as follows:
-- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
-  returns non-zero. If yes, then the driver is expected
-  to do hardware time stamping.
+- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
+  If yes, then the driver is expected to do hardware time stamping.
 - If this is possible for the skb and requested, then declare
-  that the driver is doing the time stamping by calling
-  skb_hwtstamp_tx_in_progress(). A driver not supporting
-  hardware time stamping doesn't do that. A driver must never
-  touch sk_buff::tstamp! It is used to store how time stamping
-  for an outgoing packets is to be done.
+  that the driver is doing the time stamping by setting the field
+  skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
+  to the associated skb for the next step and not free the skb. A driver
+  not supporting hardware time stamping doesn't do that. A driver must
+  never touch sk_buff::tstamp! It is used to store software generated
+  time stamps by the network subsystem.
 - As soon as the driver has sent the packet and/or obtained a
   hardware time stamp for it, it passes the time stamp back by
   calling skb_hwtstamp_tx() with the original skb, the raw
-  hardware time stamp and a handle to the device (necessary
-  to convert the hardware time stamp to system time). If obtaining
-  the hardware time stamp somehow fails, then the driver should
-  not fall back to software time stamping. The rationale is that
-  this would occur at a later time in the processing pipeline
-  than other software time stamping and therefore could lead
-  to unexpected deltas between time stamps.
-- If the driver did not call skb_hwtstamp_tx_in_progress(), then
+  hardware time stamp. skb_hwtstamp_tx() clones the original skb and
+  adds the timestamps, therefore the original skb has to be freed now.
+  If obtaining the hardware time stamp somehow fails, then the driver
+  should not fall back to software time stamping. The rationale is that
+  this would occur at a later time in the processing pipeline than other
+  software time stamping and therefore could lead to unexpected deltas
+  between time stamps.
+- If the driver did not call set skb_tx(skb)->in_progress, then
   dev_hard_start_xmit() checks whether software time stamping
   is wanted as fallback and potentially generates the time stamp.
index e149665..a2d9254 100644 (file)
@@ -485,8 +485,8 @@ S:  Maintained
 F:     drivers/input/mouse/bcm5974.c
 
 APPLE SMC DRIVER
-M:     Nicolas Boichat <nicolas@boichat.ch>
-L:     mactel-linux-devel@lists.sourceforge.net
+M:     Henrik Rydberg <rydberg@euromail.se>
+L:     lm-sensors@lm-sensors.org
 S:     Maintained
 F:     drivers/hwmon/applesmc.c
 
@@ -971,6 +971,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.mcuos.com
 S:     Maintained
 
+ARM/U300 MACHINE SUPPORT
+M:     Linus Walleij <linus.walleij@stericsson.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Supported
+F:     arch/arm/mach-u300/
+F:     drivers/i2c/busses/i2c-stu300.c
+F:     drivers/rtc/rtc-coh901331.c
+F:     drivers/watchdog/coh901327_wdt.c
+F:     drivers/dma/coh901318*
+
 ARM/U8500 ARM ARCHITECTURE
 M:     Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
index 67c1001..fa1db90 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 34
-EXTRAVERSION = -rc3
-NAME = Man-Eating Seals of Antiquity
+EXTRAVERSION = -rc5
+NAME = Sheep on Meth
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 0f23009..6ab6b33 100644 (file)
@@ -172,7 +172,7 @@ not_angel:
                adr     r0, LC0
  ARM(          ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
  THUMB(                ldmia   r0, {r1, r2, r3, r4, r5, r6, r11, ip}   )
- THUMB(                ldr     sp, [r0, #28]                           )
+ THUMB(                ldr     sp, [r0, #32]                           )
                subs    r0, r0, r1              @ calculate the delta offset
 
                                                @ if delta is zero, we are
index 7f36d00..feb988a 100644 (file)
 
 #define kmap_prot              PAGE_KERNEL
 
-#define flush_cache_kmaps()    flush_cache_all()
+#define flush_cache_kmaps() \
+       do { \
+               if (cache_is_vivt()) \
+                       flush_cache_all(); \
+       } while (0)
 
 extern pte_t *pkmap_page_table;
 
@@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page);
 extern void *kmap_high_get(struct page *page);
 extern void kunmap_high(struct page *page);
 
+extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
+extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
+
+/*
+ * The following functions are already defined by <linux/highmem.h>
+ * when CONFIG_HIGHMEM is not set.
+ */
+#ifdef CONFIG_HIGHMEM
 extern void *kmap(struct page *page);
 extern void kunmap(struct page *page);
 extern void *kmap_atomic(struct page *page, enum km_type type);
 extern void kunmap_atomic(void *kvaddr, enum km_type type);
 extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
 extern struct page *kmap_atomic_to_page(const void *ptr);
+#endif
 
 #endif
index c019949..c4b2ea3 100644 (file)
@@ -18,6 +18,7 @@ enum km_type {
        KM_IRQ1,
        KM_SOFTIRQ0,
        KM_SOFTIRQ1,
+       KM_L1_CACHE,
        KM_L2_CACHE,
        KM_TYPE_NR
 };
index bf65e9f..47f023a 100644 (file)
@@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
 #endif /* CONFIG_IWMMXT */
 
 #ifdef CONFIG_VFP
-#if __LINUX_ARM_ARCH__ < 6
-/* For ARM pre-v6, we use fstmiax and fldmiax.  This adds one extra
- * word after the registers, and a word of padding at the end for
- * alignment.  */
 #define VFP_MAGIC              0x56465001
-#define VFP_STORAGE_SIZE       152
-#else
-#define VFP_MAGIC              0x56465002
-#define VFP_STORAGE_SIZE       144
-#endif
 
 struct vfp_sigframe
 {
        unsigned long           magic;
        unsigned long           size;
-       union vfp_state         storage;
-};
+       struct user_vfp         ufp;
+       struct user_vfp_exc     ufp_exc;
+} __attribute__((__aligned__(8)));
+
+/*
+ *  8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
+ *  4 bytes padding.
+ */
+#define VFP_STORAGE_SIZE       sizeof(struct vfp_sigframe)
+
 #endif /* CONFIG_VFP */
 
 /*
@@ -91,7 +90,7 @@ struct aux_sigframe {
 #ifdef CONFIG_IWMMXT
        struct iwmmxt_sigframe  iwmmxt;
 #endif
-#if 0 && defined CONFIG_VFP /* Not yet saved.  */
+#ifdef CONFIG_VFP
        struct vfp_sigframe     vfp;
 #endif
        /* Something that isn't a valid magic number for any coprocessor.  */
index df95e05..05ac4b0 100644 (file)
@@ -83,11 +83,21 @@ struct user{
 
 /*
  * User specific VFP registers. If only VFPv2 is present, registers 16 to 31
- * are ignored by the ptrace system call.
+ * are ignored by the ptrace system call and the signal handler.
  */
 struct user_vfp {
        unsigned long long fpregs[32];
        unsigned long fpscr;
 };
 
+/*
+ * VFP exception registers exposed to user space during signal delivery.
+ * Fields not relavant to the current VFP architecture are ignored.
+ */
+struct user_vfp_exc {
+       unsigned long   fpexc;
+       unsigned long   fpinst;
+       unsigned long   fpinst2;
+};
+
 #endif /* _ARM_USER_H */
index e7714f3..907d5a6 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
 #include <asm/unistd.h>
+#include <asm/vfp.h>
 
 #include "ptrace.h"
 #include "signal.h"
@@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
 
 #endif
 
+#ifdef CONFIG_VFP
+
+static int preserve_vfp_context(struct vfp_sigframe __user *frame)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *h = &thread->vfpstate.hard;
+       const unsigned long magic = VFP_MAGIC;
+       const unsigned long size = VFP_STORAGE_SIZE;
+       int err = 0;
+
+       vfp_sync_hwstate(thread);
+       __put_user_error(magic, &frame->magic, err);
+       __put_user_error(size, &frame->size, err);
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
+                             sizeof(h->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __put_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+       /*
+        * Copy the exception registers.
+        */
+       __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
+       __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+       __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+       return err ? -EFAULT : 0;
+}
+
+static int restore_vfp_context(struct vfp_sigframe __user *frame)
+{
+       struct thread_info *thread = current_thread_info();
+       struct vfp_hard_struct *h = &thread->vfpstate.hard;
+       unsigned long magic;
+       unsigned long size;
+       unsigned long fpexc;
+       int err = 0;
+
+       __get_user_error(magic, &frame->magic, err);
+       __get_user_error(size, &frame->size, err);
+
+       if (err)
+               return -EFAULT;
+       if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
+               return -EINVAL;
+
+       /*
+        * Copy the floating point registers. There can be unused
+        * registers see asm/hwcap.h for details.
+        */
+       err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
+                               sizeof(h->fpregs));
+       /*
+        * Copy the status and control register.
+        */
+       __get_user_error(h->fpscr, &frame->ufp.fpscr, err);
+
+       /*
+        * Sanitise and restore the exception registers.
+        */
+       __get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
+       /* Ensure the VFP is enabled. */
+       fpexc |= FPEXC_EN;
+       /* Ensure FPINST2 is invalid and the exception flag is cleared. */
+       fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
+       h->fpexc = fpexc;
+
+       __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
+       __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
+
+       if (!err)
+               vfp_flush_hwstate(thread);
+
+       return err ? -EFAULT : 0;
+}
+
+#endif
+
 /*
  * Do a signal return; undo the signal stack.  These are aligned to 64-bit.
  */
@@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
                err |= restore_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//     if (err == 0)
-//             err |= vfp_restore_state(&sf->aux.vfp);
+       if (err == 0)
+               err |= restore_vfp_context(&aux->vfp);
 #endif
 
        return err;
@@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
                err |= preserve_iwmmxt_context(&aux->iwmmxt);
 #endif
 #ifdef CONFIG_VFP
-//     if (err == 0)
-//             err |= vfp_save_state(&sf->aux.vfp);
+       if (err == 0)
+               err |= preserve_vfp_context(&aux->vfp);
 #endif
        __put_user_error(0, &aux->end_magic, err);
 
index 027dd57..d400455 100644 (file)
@@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261)        += at91sam9261.o at91sam926x_time.o at91sam9261_d
 obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91SAM9RL)  += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o  sam9_smc.o
- obj-$(CONFIG_ARCH_AT91SAM9G45)        += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
+obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91CAP9)    += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT572D940HF)  += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
 obj-$(CONFIG_ARCH_AT91X40)     += at91x40.o at91x40_time.o
index 987fab3..9c5b48e 100644 (file)
@@ -175,8 +175,6 @@ ENTRY(at91_slow_clock)
        orr     r3, r3, #(1 << 29)              /* bit 29 always set */
        str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
-       wait_pllalock
-
        /* Save PLLB setting and disable it */
        ldr     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
        str     r3, .saved_pllbr
@@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
        mov     r3, #AT91_PMC_PLLCOUNT
        str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
-       wait_pllblock
-
        /* Turn off the main oscillator */
        ldr     r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
        bic     r3, r3, #AT91_PMC_MOSCEN
@@ -205,13 +201,25 @@ ENTRY(at91_slow_clock)
        ldr     r3, .saved_pllbr
        str     r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
 
+       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       bne     1f
+       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       beq     2f
+1:
        wait_pllblock
+2:
 
        /* Restore PLLA setting */
        ldr     r3, .saved_pllar
        str     r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
 
+       tst     r3, #(AT91_PMC_MUL &  0xff0000)
+       bne     3f
+       tst     r3, #(AT91_PMC_MUL & ~0xff0000)
+       beq     4f
+3:
        wait_pllalock
+4:
 
 #ifdef SLOWDOWN_MASTER_CLOCK
        /*
index 2ccf670..29c0a91 100644 (file)
@@ -2221,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring);
 int dma_unmap(DMA_MemMap_t *memMap,    /* Stores state information about the map */
              int dirtied       /* non-zero if any of the pages were modified */
     ) {
+
+       int rc = 0;
        int regionIdx;
        int segmentIdx;
        DMA_Region_t *region;
        DMA_Segment_t *segment;
 
+       down(&memMap->lock);
+
        for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
                region = &memMap->region[regionIdx];
 
@@ -2239,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap,       /* Stores state information about the map */
                                        printk(KERN_ERR
                                               "%s: vmalloc'd pages are not yet supported\n",
                                               __func__);
-                                       return -EINVAL;
+                                       rc = -EINVAL;
+                                       goto out;
                                }
 
                        case DMA_MEM_TYPE_KMALLOC:
@@ -2276,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap,       /* Stores state information about the map */
                                        printk(KERN_ERR
                                               "%s: Unsupported memory type: %d\n",
                                               __func__, region->memType);
-                                       return -EINVAL;
+                                       rc = -EINVAL;
+                                       goto out;
                                }
                        }
 
@@ -2314,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap,      /* Stores state information about the map */
        memMap->numRegionsUsed = 0;
        memMap->inUse = 0;
 
+out:
        up(&memMap->lock);
 
-       return 0;
+       return rc;
 }
 
 EXPORT_SYMBOL(dma_unmap);
index cc377ae..cf547ad 100644 (file)
@@ -25,7 +25,7 @@
 #include <mach/hardware.h>
 
 /*************************************************************************
- * GPIO handling for EP93xx
+ * Interrupt handling for EP93xx on-chip GPIOs
  *************************************************************************/
 static unsigned char gpio_int_unmasked[3];
 static unsigned char gpio_int_enabled[3];
@@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3]                = { 0x98, 0xb4, 0x54 };
 static const u8 int_en_register_offset[3]      = { 0x9c, 0xb8, 0x58 };
 static const u8 int_debounce_register_offset[3]        = { 0xa8, 0xc4, 0x64 };
 
-void ep93xx_gpio_update_int_params(unsigned port)
+static void ep93xx_gpio_update_int_params(unsigned port)
 {
        BUG_ON(port > 2);
 
@@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port)
                EP93XX_GPIO_REG(int_en_register_offset[port]));
 }
 
-void ep93xx_gpio_int_mask(unsigned line)
+static inline void ep93xx_gpio_int_mask(unsigned line)
 {
        gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
 }
index 3872af1..170f68e 100644 (file)
@@ -62,6 +62,15 @@ config MACH_MX31_3DS
          Include support for MX31PDK (3DS) platform. This includes specific
          configurations for the board and its peripherals.
 
+config MACH_MX31_3DS_MXC_NAND_USE_BBT
+       bool "Make the MXC NAND driver use the in flash Bad Block Table"
+       depends on MACH_MX31_3DS
+       depends on MTD_NAND_MXC
+       help
+         Enable this if you want that the MXC NAND driver uses the in flash
+         Bad Block Table to know what blocks are bad instead of scanning the
+         entire flash looking for bad block markers.
+
 config MACH_MX31MOBOARD
        bool "Support mx31moboard platforms (EPFL Mobots group)"
        select ARCH_MX31
@@ -95,6 +104,7 @@ config MACH_PCM043
 config MACH_ARMADILLO5X0
        bool "Support Atmark Armadillo-500 Development Base Board"
        select ARCH_MX31
+       select MXC_ULPI if USB_ULPI
        help
          Include support for Atmark Armadillo-500 platform. This includes
          specific configurations for the board and its peripherals.
index 80dba99..9a9eb6d 100644 (file)
@@ -468,6 +468,7 @@ static struct clk ahb_clk = {
        }
 
 DEFINE_CLOCK(perclk_clk,  0, NULL,          0, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 DEFINE_CLOCK(sdhc1_clk,   0, MXC_CCM_CGR0,  0, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(sdhc2_clk,   1, MXC_CCM_CGR0,  2, NULL, NULL, &perclk_clk);
@@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk,   0, MXC_CCM_CGR1,  0, NULL, NULL, &ahb_clk);
 DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1,  2, mstick1_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1,  4, mstick2_get_rate, NULL, &usb_pll_clk);
 DEFINE_CLOCK1(csi_clk,    0, MXC_CCM_CGR1,  6, csi, NULL, &serial_pll_clk);
-DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ipg_clk);
+DEFINE_CLOCK(rtc_clk,     0, MXC_CCM_CGR1,  8, NULL, NULL, &ckil_clk);
 DEFINE_CLOCK(wdog_clk,    0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(pwm_clk,     0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
 DEFINE_CLOCK(usb_clk2,    0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
@@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1,    0, NULL,          0, usb_get_rate, NULL, &usb_pll_clk)
 DEFINE_CLOCK(nfc_clk,     0, NULL,          0, nfc_get_rate, NULL, &ahb_clk);
 DEFINE_CLOCK(scc_clk,     0, NULL,          0, NULL, NULL, &ipg_clk);
 DEFINE_CLOCK(ipg_clk,     0, NULL,          0, ipg_get_rate, NULL, &ahb_clk);
-DEFINE_CLOCK(ckil_clk,    0, NULL,          0, clk_ckil_get_rate, NULL, NULL);
 
 #define _REGISTER_CLOCK(d, n, c) \
        { \
@@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK(NULL, "iim", iim_clk)
        _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
        _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
-       _REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
 };
 
 int __init mx31_clocks_init(unsigned long fref)
index 6adb586..f891115 100644 (file)
@@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = {
        .resource = imx_ssi_resources1,
 };
 
-static int mx3_devices_init(void)
+static struct resource imx_wdt_resources[] = {
+       {
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device imx_wdt_device0 = {
+       .name           = "imx-wdt",
+       .id             = 0,
+       .num_resources  = ARRAY_SIZE(imx_wdt_resources),
+       .resource       = imx_wdt_resources,
+};
+
+static int __init mx3_devices_init(void)
 {
        if (cpu_is_mx31()) {
                mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
                mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
+               imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
+               imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
                mxc_register_device(&mxc_rnga_device, NULL);
        }
        if (cpu_is_mx35()) {
@@ -597,6 +612,8 @@ static int mx3_devices_init(void)
                imx_ssi_resources0[1].end = MX35_INT_SSI1;
                imx_ssi_resources1[1].start = MX35_INT_SSI2;
                imx_ssi_resources1[1].end = MX35_INT_SSI2;
+               imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
+               imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
        }
 
        return 0;
index 42cf175..4f77eb5 100644 (file)
@@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1;
 extern struct platform_device mxc_spi_device2;
 extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device1;
-
+extern struct platform_device imx_ssi_device1;
+extern struct platform_device imx_wdt_device0;
index 3d72b0b..5f72ec9 100644 (file)
@@ -36,6 +36,9 @@
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
 #include <linux/i2c.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/delay.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -52,6 +55,8 @@
 #include <mach/ipu.h>
 #include <mach/mx3fb.h>
 #include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
 
 #include "devices.h"
 #include "crm_regs.h"
@@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = {
        /* I2C2 */
        MX31_PIN_CSPI2_MOSI__SCL,
        MX31_PIN_CSPI2_MISO__SDA,
+       /* OTG */
+       MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+       MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+       MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+       MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+       MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+       MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+       MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+       MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+       MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+       MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+       MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+       MX31_PIN_USBOTG_STP__USBOTG_STP,
+       /* USB host 2 */
+       IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
+       IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
 };
 
+/* USB */
+#if defined(CONFIG_USB_ULPI)
+
+#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
+#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
+#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+                       PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+       int err;
+
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+       /* Chip already enabled by hardware */
+       /* OTG phy reset*/
+       err = gpio_request(OTG_RESET, "USB-OTG-RESET");
+       if (err) {
+               pr_err("Failed to request the usb otg reset gpio\n");
+               return err;
+       }
+
+       err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
+       if (err) {
+               pr_err("Failed to reset the usb otg phy\n");
+               goto otg_free_reset;
+       }
+
+       gpio_set_value(OTG_RESET, 0/*LOW*/);
+       mdelay(5);
+       gpio_set_value(OTG_RESET, 1/*HIGH*/);
+
+       return 0;
+
+otg_free_reset:
+       gpio_free(OTG_RESET);
+       return err;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+       int err;
+
+       mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+       mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+
+       /* Enable the chip */
+       err = gpio_request(USBH2_CS, "USB-H2-CS");
+       if (err) {
+               pr_err("Failed to request the usb host 2 CS gpio\n");
+               return err;
+       }
+
+       err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
+       if (err) {
+               pr_err("Failed to drive the usb host 2 CS gpio\n");
+               goto h2_free_cs;
+       }
+
+       /* H2 phy reset*/
+       err = gpio_request(USBH2_RESET, "USB-H2-RESET");
+       if (err) {
+               pr_err("Failed to request the usb host 2 reset gpio\n");
+               goto h2_free_cs;
+       }
+
+       err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
+       if (err) {
+               pr_err("Failed to reset the usb host 2 phy\n");
+               goto h2_free_reset;
+       }
+
+       gpio_set_value(USBH2_RESET, 0/*LOW*/);
+       mdelay(5);
+       gpio_set_value(USBH2_RESET, 1/*HIGH*/);
+
+       return 0;
+
+h2_free_reset:
+       gpio_free(USBH2_RESET);
+h2_free_cs:
+       gpio_free(USBH2_CS);
+       return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata = {
+       .init   = usbotg_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+       .init   = usbh2_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif /* CONFIG_USB_ULPI */
+
 /* RTC over I2C*/
 #define ARMADILLO5X0_RTC_GPIO  IOMUX_TO_GPIO(MX31_PIN_SRXD4)
 
@@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void)
        if (armadillo5x0_i2c_rtc.irq == 0)
                pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
        i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
+
+       /* USB */
+#if defined(CONFIG_USB_ULPI)
+       usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+       usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+       mxc_register_device(&mxc_otg_host, &usbotg_pdata);
+       mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
 }
 
 static void __init armadillo5x0_timer_init(void)
index b88c18a..f54af1e 100644 (file)
@@ -23,6 +23,9 @@
 #include <linux/gpio.h>
 #include <linux/smsc911x.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/machine.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/memory.h>
 #include <asm/mach/map.h>
 #include <mach/common.h>
-#include <mach/board-mx31pdk.h>
+#include <mach/board-mx31_3ds.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
+#include <mach/mxc_nand.h>
+#include <mach/spi.h>
 #include "devices.h"
 
 /*!
- * @file mx31pdk.c
+ * @file mx31_3ds.c
  *
  * @brief This file contains the board-specific initialization routines.
  *
  * @ingroup System
  */
 
-static int mx31pdk_pins[] = {
+static int mx31_3ds_pins[] = {
        /* UART1 */
        MX31_PIN_CTS1__CTS1,
        MX31_PIN_RTS1__RTS1,
        MX31_PIN_TXD1__TXD1,
        MX31_PIN_RXD1__RXD1,
        IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
+       /* SPI 1 */
+       MX31_PIN_CSPI2_SCLK__SCLK,
+       MX31_PIN_CSPI2_MOSI__MOSI,
+       MX31_PIN_CSPI2_MISO__MISO,
+       MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
+       MX31_PIN_CSPI2_SS0__SS0,
+       MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
+       /* MC13783 IRQ */
+       IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+       .constraints = {
+               .boot_on        = 1,
+               .always_on      = 1,
+       },
+};
+
+static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
+       {
+               .id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */
+               .init_data = &pwgtx_init,
+       }, {
+               .id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
+               .init_data = &pwgtx_init,
+       },
+};
+
+/* MC13783 */
+static struct mc13783_platform_data mc13783_pdata __initdata = {
+       .regulators = mx31_3ds_regulators,
+       .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+       .flags  = MC13783_USE_REGULATOR,
+};
+
+/* SPI */
+static int spi1_internal_chipselect[] = {
+       MXC_SPI_CS(0),
+       MXC_SPI_CS(2),
+};
+
+static struct spi_imx_master spi1_pdata = {
+       .chipselect     = spi1_internal_chipselect,
+       .num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
+};
+
+static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
+       {
+               .modalias       = "mc13783",
+               .max_speed_hz   = 1000000,
+               .bus_num        = 1,
+               .chip_select    = 1, /* SS2 */
+               .platform_data  = &mc13783_pdata,
+               .irq            = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+               .mode = SPI_CS_HIGH,
+       },
+};
+
+/*
+ * NAND Flash
+ */
+static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
+       .width          = 1,
+       .hw_ecc         = 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+       .flash_bbt      = 1,
+#endif
 };
 
 static struct imxuart_platform_data uart_pdata = {
@@ -95,7 +168,7 @@ static struct platform_device smsc911x_device = {
  * LEDs, switches, interrupts for Ethernet.
  */
 
-static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
+static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
 {
        uint32_t imr_val;
        uint32_t int_valid;
@@ -163,7 +236,7 @@ static struct irq_chip expio_irq_chip = {
        .unmask = expio_unmask_irq,
 };
 
-static int __init mx31pdk_init_expio(void)
+static int __init mx31_3ds_init_expio(void)
 {
        int i;
        int ret;
@@ -176,7 +249,7 @@ static int __init mx31pdk_init_expio(void)
                return -ENODEV;
        }
 
-       pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n",
+       pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
                __raw_readw(CPLD_CODE_VER_REG));
 
        /*
@@ -201,7 +274,7 @@ static int __init mx31pdk_init_expio(void)
                set_irq_flags(i, IRQF_VALID);
        }
        set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
-       set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler);
+       set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
 
        return 0;
 }
@@ -209,7 +282,7 @@ static int __init mx31pdk_init_expio(void)
 /*
  * This structure defines the MX31 memory map.
  */
-static struct map_desc mx31pdk_io_desc[] __initdata = {
+static struct map_desc mx31_3ds_io_desc[] __initdata = {
        {
                .virtual = MX31_CS5_BASE_ADDR_VIRT,
                .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
@@ -221,10 +294,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = {
 /*
  * Set up static virtual mappings.
  */
-static void __init mx31pdk_map_io(void)
+static void __init mx31_3ds_map_io(void)
 {
        mx31_map_io();
-       iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
+       iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
 }
 
 /*!
@@ -232,35 +305,40 @@ static void __init mx31pdk_map_io(void)
  */
 static void __init mxc_board_init(void)
 {
-       mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
-                                     "mx31pdk");
+       mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
+                                     "mx31_3ds");
 
        mxc_register_device(&mxc_uart_device0, &uart_pdata);
+       mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata);
+
+       mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+       spi_register_board_info(mx31_3ds_spi_devs,
+                                               ARRAY_SIZE(mx31_3ds_spi_devs));
 
-       if (!mx31pdk_init_expio())
+       if (!mx31_3ds_init_expio())
                platform_device_register(&smsc911x_device);
 }
 
-static void __init mx31pdk_timer_init(void)
+static void __init mx31_3ds_timer_init(void)
 {
        mx31_clocks_init(26000000);
 }
 
-static struct sys_timer mx31pdk_timer = {
-       .init   = mx31pdk_timer_init,
+static struct sys_timer mx31_3ds_timer = {
+       .init   = mx31_3ds_timer_init,
 };
 
 /*
  * The following uses standard kernel macros defined in arch.h in order to
- * initialize __mach_desc_MX31PDK data structure.
+ * initialize __mach_desc_MX31_3DS data structure.
  */
 MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
        /* Maintainer: Freescale Semiconductor, Inc. */
        .phys_io        = MX31_AIPS1_BASE_ADDR,
        .io_pg_offst    = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
        .boot_params    = MX3x_PHYS_OFFSET + 0x100,
-       .map_io         = mx31pdk_map_io,
+       .map_io         = mx31_3ds_map_io,
        .init_irq       = mx31_init_irq,
        .init_machine   = mxc_board_init,
-       .timer          = &mx31pdk_timer,
+       .timer          = &mx31_3ds_timer,
 MACHINE_END
index 034ec81..2df1ec5 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/can/platform/sja1000.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
-#include <linux/fsl_devices.h>
 #include <linux/gfp.h>
 
 #include <media/soc_camera.h>
index ccd8742..093c595 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/platform_device.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
 
@@ -206,5 +205,6 @@ void __init mx31lite_db_init(void)
        mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
        mxc_register_device(&mxc_spi_device0, &spi0_pdata);
        platform_device_register(&litekit_led_device);
+       mxc_register_device(&imx_wdt_device0, NULL);
 }
 
index be90c03..8f85f73 100644 (file)
@@ -757,7 +757,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
 
 /* GPT */
 DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
-       NULL,  NULL, &ipg_perclk, NULL);
+       NULL,  NULL, &ipg_clk, NULL);
 DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
        NULL,  NULL, &ipg_clk, NULL);
 
index 41c769f..2d37785 100644 (file)
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
 
+static int cpu_silicon_rev = -1;
+
+#define SI_REV 0x48
+
+static void query_silicon_parameter(void)
+{
+       void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
+       u32 rev;
+
+       if (!rom) {
+               cpu_silicon_rev = -EINVAL;
+               return;
+       }
+
+       rev = readl(rom + SI_REV);
+       switch (rev) {
+       case 0x1:
+               cpu_silicon_rev = MX51_CHIP_REV_1_0;
+               break;
+       case 0x2:
+               cpu_silicon_rev = MX51_CHIP_REV_1_1;
+               break;
+       case 0x10:
+               cpu_silicon_rev = MX51_CHIP_REV_2_0;
+               break;
+       case 0x20:
+               cpu_silicon_rev = MX51_CHIP_REV_3_0;
+               break;
+       default:
+               cpu_silicon_rev = 0;
+       }
+
+       iounmap(rom);
+}
+
+/*
+ * Returns:
+ *     the silicon revision of the cpu
+ *     -EINVAL - not a mx51
+ */
+int mx51_revision(void)
+{
+       if (!cpu_is_mx51())
+               return -EINVAL;
+
+       if (cpu_silicon_rev == -1)
+               query_silicon_parameter();
+
+       return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx51_revision);
+
 static int __init post_cpu_init(void)
 {
        unsigned int reg;
index c21e18b..b7677ef 100644 (file)
@@ -35,11 +35,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
                .length = MX51_DEBUG_SIZE,
                .type = MT_DEVICE
        }, {
-               .virtual = MX51_TZIC_BASE_ADDR_VIRT,
-               .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
-               .length = MX51_TZIC_SIZE,
-               .type = MT_DEVICE
-       }, {
                .virtual = MX51_AIPS1_BASE_ADDR_VIRT,
                .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
                .length = MX51_AIPS1_SIZE,
@@ -54,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
                .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
                .length = MX51_AIPS2_SIZE,
                .type = MT_DEVICE
-       }, {
-               .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
-               .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
-               .length = MX51_NFC_AXI_SIZE,
-               .type = MT_DEVICE
        },
 };
 
@@ -69,14 +59,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
  */
 void __init mx51_map_io(void)
 {
-       u32 tzic_addr;
-
-       if (mx51_revision() < MX51_CHIP_REV_2_0)
-               tzic_addr = 0x8FFFC000;
-       else
-               tzic_addr = 0xE0003000;
-       mxc_io_desc[2].pfn =  __phys_to_pfn(tzic_addr);
-
        mxc_set_cpu_type(MXC_CPU_MX51);
        mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
        mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
@@ -85,5 +67,17 @@ void __init mx51_map_io(void)
 
 void __init mx51_init_irq(void)
 {
-       tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
+       unsigned long tzic_addr;
+       void __iomem *tzic_virt;
+
+       if (mx51_revision() < MX51_CHIP_REV_2_0)
+               tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
+       else
+               tzic_addr = MX51_TZIC_BASE_ADDR;
+
+       tzic_virt = ioremap(tzic_addr, SZ_16K);
+       if (!tzic_virt)
+               panic("unable to map TZIC interrupt controller\n");
+
+       tzic_init_irq(tzic_virt);
 }
index 8bca4de..f55fa10 100644 (file)
@@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
        kfrom = kmap_atomic(from, KM_USER0);
        kto = kmap_atomic(to, KM_USER1);
        copy_page(kto, kfrom);
-#ifdef CONFIG_HIGHMEM
-       /*
-        * kmap_atomic() doesn't set the page virtual address, and
-        * kunmap_atomic() takes care of cache flushing already.
-        */
-       if (page_address(to) != NULL)
-#endif
-               __cpuc_flush_dcache_area(kto, PAGE_SIZE);
+       __cpuc_flush_dcache_area(kto, PAGE_SIZE);
        kunmap_atomic(kto, KM_USER1);
        kunmap_atomic(kfrom, KM_USER0);
 }
index 1351edc..13fa536 100644 (file)
@@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
                                vaddr += offset;
                                op(vaddr, len, dir);
                                kunmap_high(page);
+                       } else if (cache_is_vipt()) {
+                               pte_t saved_pte;
+                               vaddr = kmap_high_l1_vipt(page, &saved_pte);
+                               op(vaddr + offset, len, dir);
+                               kunmap_high_l1_vipt(page, saved_pte);
                        }
                } else {
                        vaddr = page_address(page) + offset;
index e34f095..c6844cb 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
+#include <asm/highmem.h>
 #include <asm/smp_plat.h>
 #include <asm/system.h>
 #include <asm/tlbflush.h>
@@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
-       void *addr = page_address(page);
-
        /*
         * Writeback any data associated with the kernel mapping of this
         * page.  This ensures that data in the physical page is mutually
         * coherent with the kernels mapping.
         */
-#ifdef CONFIG_HIGHMEM
-       /*
-        * kmap_atomic() doesn't set the page virtual address, and
-        * kunmap_atomic() takes care of cache flushing already.
-        */
-       if (addr)
-#endif
-               __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+       if (!PageHighMem(page)) {
+               __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
+       } else {
+               void *addr = kmap_high_get(page);
+               if (addr) {
+                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                       kunmap_high(page);
+               } else if (cache_is_vipt()) {
+                       pte_t saved_pte;
+                       addr = kmap_high_l1_vipt(page, &saved_pte);
+                       __cpuc_flush_dcache_area(addr, PAGE_SIZE);
+                       kunmap_high_l1_vipt(page, saved_pte);
+               }
+       }
 
        /*
         * If this is a page cache page, and we have an aliasing VIPT cache,
index 2be1ec7..77b030f 100644 (file)
@@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
        unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
 
        if (kvaddr >= (void *)FIXADDR_START) {
-               __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
+               if (cache_is_vivt())
+                       __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
 #ifdef CONFIG_DEBUG_HIGHMEM
                BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
                set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
@@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr)
        pte = TOP_PTE(vaddr);
        return pte_page(*pte);
 }
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+
+#include <linux/percpu.h>
+
+/*
+ * The VIVT cache of a highmem page is always flushed before the page
+ * is unmapped. Hence unmapped highmem pages need no cache maintenance
+ * in that case.
+ *
+ * However unmapped pages may still be cached with a VIPT cache, and
+ * it is not possible to perform cache maintenance on them using physical
+ * addresses unfortunately.  So we have no choice but to set up a temporary
+ * virtual mapping for that purpose.
+ *
+ * Yet this VIPT cache maintenance may be triggered from DMA support
+ * functions which are possibly called from interrupt context. As we don't
+ * want to keep interrupt disabled all the time when such maintenance is
+ * taking place, we therefore allow for some reentrancy by preserving and
+ * restoring the previous fixmap entry before the interrupted context is
+ * resumed.  If the reentrancy depth is 0 then there is no need to restore
+ * the previous fixmap, and leaving the current one in place allow it to
+ * be reused the next time without a TLB flush (common with DMA).
+ */
+
+static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
+
+void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
+{
+       unsigned int idx, cpu = smp_processor_id();
+       int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+       unsigned long vaddr, flags;
+       pte_t pte, *ptep;
+
+       idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       ptep = TOP_PTE(vaddr);
+       pte = mk_pte(page, kmap_prot);
+
+       if (!in_interrupt())
+               preempt_disable();
+
+       raw_local_irq_save(flags);
+       (*depth)++;
+       if (pte_val(*ptep) == pte_val(pte)) {
+               *saved_pte = pte;
+       } else {
+               *saved_pte = *ptep;
+               set_pte_ext(ptep, pte, 0);
+               local_flush_tlb_kernel_page(vaddr);
+       }
+       raw_local_irq_restore(flags);
+
+       return (void *)vaddr;
+}
+
+void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
+{
+       unsigned int idx, cpu = smp_processor_id();
+       int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
+       unsigned long vaddr, flags;
+       pte_t pte, *ptep;
+
+       idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
+       vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+       ptep = TOP_PTE(vaddr);
+       pte = mk_pte(page, kmap_prot);
+
+       BUG_ON(pte_val(*ptep) != pte_val(pte));
+       BUG_ON(*depth <= 0);
+
+       raw_local_irq_save(flags);
+       (*depth)--;
+       if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
+               set_pte_ext(ptep, saved_pte, 0);
+               local_flush_tlb_kernel_page(vaddr);
+       }
+       raw_local_irq_restore(flags);
+
+       if (!in_interrupt())
+               preempt_enable();
+}
+
+#endif  /* CONFIG_CPU_CACHE_VIPT */
index 9d4da6a..241c24a 100644 (file)
@@ -420,6 +420,10 @@ static void __init build_mem_type_table(void)
                user_pgprot |= L_PTE_SHARED;
                kern_pgprot |= L_PTE_SHARED;
                vecs_pgprot |= L_PTE_SHARED;
+               mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
+               mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
+               mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
+               mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
                mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
                mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
 #endif
@@ -1050,10 +1054,12 @@ void setup_mm_for_reboot(char mode)
        pgd_t *pgd;
        int i;
 
-       if (current->mm && current->mm->pgd)
-               pgd = current->mm->pgd;
-       else
-               pgd = init_mm.pgd;
+       /*
+        * We need to access to user-mode page tables here. For kernel threads
+        * we don't have any user-mode mappings so we use the context that we
+        * "borrowed".
+        */
+       pgd = current->active_mm->pgd;
 
        base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
        if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
@@ -8,8 +8,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
+#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
 
 /* Definitions for components on the Debug board */
 
@@ -56,4 +56,4 @@
 
 #define MXC_MAX_EXP_IO_LINES   16
 
-#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */
+#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */
index 771532b..5aad344 100644 (file)
@@ -14,7 +14,7 @@
  * FB100000    70000000        1M      SPBA 0
  * FB000000    73F00000        1M      AIPS 1
  * FB200000    83F00000        1M      AIPS 2
- * FA100000    8FFFC000        16K     TZIC (interrupt controller)
+ *             8FFFC000        16K     TZIC (interrupt controller)
  *             90000000        256M    CSD0 SDRAM/DDR
  *             A0000000        256M    CSD1 SDRAM/DDR
  *             B0000000        128M    CS0 Flash
  *             C8000000        64M     CS3 Flash
  *             CC000000        32M     CS4 SRAM
  *             CE000000        32M     CS5 SRAM
- * F9000000    CFFF0000        64K     NFC (NAND Flash AXI)
+ *             CFFF0000        64K     NFC (NAND Flash AXI)
  *
  */
 
 /*
+ * IROM
+ */
+#define MX51_IROM_BASE_ADDR            0x0
+#define MX51_IROM_SIZE                 SZ_64K
+
+/*
  * IRAM
  */
 #define MX51_IRAM_BASE_ADDR            0x1FFE0000      /* internal ram */
@@ -40,7 +46,6 @@
  * NFC
  */
 #define MX51_NFC_AXI_BASE_ADDR         0xCFFF0000      /* NAND flash AXI */
-#define MX51_NFC_AXI_BASE_ADDR_VIRT    0xF9000000
 #define MX51_NFC_AXI_SIZE              SZ_64K
 
 /*
@@ -49,9 +54,8 @@
 #define MX51_GPU_BASE_ADDR             0x20000000
 #define MX51_GPU2D_BASE_ADDR           0xD0000000
 
-#define MX51_TZIC_BASE_ADDR            0x8FFFC000
-#define MX51_TZIC_BASE_ADDR_VIRT       0xFA100000
-#define MX51_TZIC_SIZE                 SZ_16K
+#define MX51_TZIC_BASE_ADDR_TO1                0x8FFFC000
+#define MX51_TZIC_BASE_ADDR            0xE0000000
 
 #define MX51_DEBUG_BASE_ADDR           0x60000000
 #define MX51_DEBUG_BASE_ADDR_VIRT      0xFA200000
 #define MX51_IO_ADDRESS(x)                                     \
        (void __iomem *)                                        \
        (MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) :    \
-       MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) :     \
        MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) :   \
        MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) :   \
        MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) :   \
-       MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) :   \
-       MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \
+       MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
        0xDEADBEEF)
 
 /*
 #define MX51_IRAM_IO_ADDRESS(x)  \
        (((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
 
-#define MX51_TZIC_IO_ADDRESS(x)  \
-       (((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT)
-
 #define MX51_DEBUG_IO_ADDRESS(x)  \
        (((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
 
 #define MX51_AIPS2_IO_ADDRESS(x)  \
        (((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
 
-#define MX51_NFC_AXI_IO_ADDRESS(x) \
-       (((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT)
-
 #define MX51_IS_MEM_DEVICE_NONSHARED(x)                0
 
 /*
 
 #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
 
-extern unsigned int system_rev;
-
-static inline unsigned int mx51_revision(void)
-{
-       return system_rev;
-}
+extern int mx51_revision(void);
 #endif
 
 #endif /*  __ASM_ARCH_MXC_MX51_H__ */
index 52e476a..b6d3d0f 100644 (file)
@@ -66,6 +66,7 @@ static inline void flush(void)
 #define MX2X_UART1_BASE_ADDR   0x1000a000
 #define MX3X_UART1_BASE_ADDR   0x43F90000
 #define MX3X_UART2_BASE_ADDR   0x43F94000
+#define MX51_UART1_BASE_ADDR   0x73fbc000
 
 static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 {
@@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
        case MACH_TYPE_MAGX_ZN5:
                uart_base = MX3X_UART2_BASE_ADDR;
                break;
+       case MACH_TYPE_MX51_BABBAGE:
+               uart_base = MX51_UART1_BASE_ADDR;
+               break;
        default:
                break;
        }
index a420cb9..315a540 100644 (file)
@@ -428,26 +428,6 @@ static void vfp_pm_init(void)
 static inline void vfp_pm_init(void) { }
 #endif /* CONFIG_PM */
 
-/*
- * Synchronise the hardware VFP state of a thread other than current with the
- * saved one. This function is used by the ptrace mechanism.
- */
-#ifdef CONFIG_SMP
-void vfp_sync_hwstate(struct thread_info *thread)
-{
-}
-
-void vfp_flush_hwstate(struct thread_info *thread)
-{
-       /*
-        * On SMP systems, the VFP state is automatically saved at every
-        * context switch. We mark the thread VFP state as belonging to a
-        * non-existent CPU so that the saved one will be reloaded when
-        * needed.
-        */
-       thread->vfpstate.hard.cpu = NR_CPUS;
-}
-#else
 void vfp_sync_hwstate(struct thread_info *thread)
 {
        unsigned int cpu = get_cpu();
@@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread)
                last_VFP_context[cpu] = NULL;
        }
 
+#ifdef CONFIG_SMP
+       /*
+        * For SMP we still have to take care of the case where the thread
+        * migrates to another CPU and then back to the original CPU on which
+        * the last VFP user is still the same thread. Mark the thread VFP
+        * state as belonging to a non-existent CPU so that the saved one will
+        * be reloaded in the above case.
+        */
+       thread->vfpstate.hard.cpu = NR_CPUS;
+#endif
        put_cpu();
 }
-#endif
 
 #include <linux/smp.h>
 
index 73c5c2b..7f3c0a2 100644 (file)
@@ -1802,7 +1802,8 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 {
        struct kvm_memory_slot *memslot;
        int r, i;
-       long n, base;
+       long base;
+       unsigned long n;
        unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base +
                        offsetof(struct kvm_vm_data, kvm_mem_dirty_log));
 
@@ -1815,7 +1816,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
        base = memslot->base_gfn / BITS_PER_LONG;
 
        for (i = 0; i < n/sizeof(long); ++i) {
@@ -1831,7 +1832,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                struct kvm_dirty_log *log)
 {
        int r;
-       int n;
+       unsigned long n;
        struct kvm_memory_slot *memslot;
        int is_dirty = 0;
 
@@ -1850,7 +1851,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        if (is_dirty) {
                kvm_flush_remote_tlbs(kvm);
                memslot = &kvm->memslots->memslots[log->slot];
-               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               n = kvm_dirty_bitmap_bytes(memslot);
                memset(memslot->dirty_bitmap, 0, n);
        }
        r = 0;
index 88b7af2..d9d2ed6 100644 (file)
@@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new)
 static inline int atomic_sub_and_test(int i, atomic_t *v)
 {
        char c;
-       __asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
+       __asm__ __volatile__("subl %2,%1; seq %0"
+                            : "=d" (c), "+m" (*v)
+                            : "id" (i));
        return c != 0;
 }
 
 static inline int atomic_add_negative(int i, atomic_t *v)
 {
        char c;
-       __asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
+       __asm__ __volatile__("addl %2,%1; smi %0"
+                            : "=d" (c), "+m" (*v)
+                            : "id" (i));
        return c != 0;
 }
 
index ef22938..01a8716 100644 (file)
@@ -212,5 +212,10 @@ struct mcf_platform_uart {
 #define        MCFUART_URF_RXS         0xc0            /* Receiver status */
 #endif
 
+#if defined(CONFIG_M5272)
+#define MCFUART_TXFIFOSIZE     25
+#else
+#define MCFUART_TXFIFOSIZE     1
+#endif
 /****************************************************************************/
 #endif /* mcfuart_h */
index 1320eaa..a29dd74 100644 (file)
@@ -17,13 +17,11 @@ struct sigcontext {
 #ifndef __uClinux__
 # ifdef __mcoldfire__
        unsigned long  sc_fpregs[2][2]; /* room for two fp registers */
-       unsigned long  sc_fpcntl[3];
-       unsigned char  sc_fpstate[16+6*8];
 # else
        unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
+# endif
        unsigned long  sc_fpcntl[3];
        unsigned char  sc_fpstate[216];
-# endif
 #endif
 };
 
index ce404bc..1404257 100644 (file)
@@ -94,7 +94,7 @@ cflags-$(CONFIG_M520x)                := $(call cc-option,-mcpu=5208,-m5200)
 cflags-$(CONFIG_M523x)         := $(call cc-option,-mcpu=523x,-m5307)
 cflags-$(CONFIG_M5249)         := $(call cc-option,-mcpu=5249,-m5200)
 cflags-$(CONFIG_M5271)         := $(call cc-option,-mcpu=5271,-m5307)
-cflags-$(CONFIG_M5272)         := $(call cc-option,-mcpu=5271,-m5200)
+cflags-$(CONFIG_M5272)         := $(call cc-option,-mcpu=5272,-m5307)
 cflags-$(CONFIG_M5275)         := $(call cc-option,-mcpu=5275,-m5307)
 cflags-$(CONFIG_M528x)         := $(call cc-option,-m528x,-m5307)
 cflags-$(CONFIG_M5307)         := $(call cc-option,-m5307,-m5200)
index 56043ad..aff6f57 100644 (file)
@@ -145,6 +145,6 @@ ENTRY(ret_from_user_signal)
        trap #0
 
 ENTRY(ret_from_user_rt_signal)
-       move #__NR_rt_sigreturn,%d0
+       movel #__NR_rt_sigreturn,%d0
        trap #0
 
index 1143f77..6f22970 100644 (file)
@@ -107,7 +107,6 @@ void init_IRQ(void)
        _ramvec[vba+CPMVEC_PIO_PC7]     = inthandler;  /* pio - pc7 */
        _ramvec[vba+CPMVEC_PIO_PC6]     = inthandler;  /* pio - pc6 */
        _ramvec[vba+CPMVEC_TIMER3]      = inthandler;  /* timer 3 */
-       _ramvec[vba+CPMVEC_RISCTIMER]   = inthandler;  /* reserved */
        _ramvec[vba+CPMVEC_PIO_PC5]     = inthandler;  /* pio - pc5 */
        _ramvec[vba+CPMVEC_PIO_PC4]     = inthandler;  /* pio - pc4 */
        _ramvec[vba+CPMVEC_RESERVED2]   = inthandler;  /* reserved */
index 379536e..be7e92e 100644 (file)
@@ -60,43 +60,6 @@ void __init board_setup(void)
        wmb();
 }
 
-/* use the hexleds to count the number of times the cpu has entered
- * wait, the dots to indicate whether the CPU is currently idle or
- * active (dots off = sleeping, dots on = working) for cases where
- * the number doesn't change for a long(er) period of time.
- */
-static void db1200_wait(void)
-{
-       __asm__("       .set    push                    \n"
-               "       .set    mips3                   \n"
-               "       .set    noreorder               \n"
-               "       cache   0x14, 0(%0)             \n"
-               "       cache   0x14, 32(%0)            \n"
-               "       cache   0x14, 64(%0)            \n"
-               /* dots off: we're about to call wait */
-               "       lui     $26, 0xb980             \n"
-               "       ori     $27, $0, 3              \n"
-               "       sb      $27, 0x18($26)          \n"
-               "       sync                            \n"
-               "       nop                             \n"
-               "       wait                            \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               "       nop                             \n"
-               /* dots on: there's work to do, increment cntr */
-               "       lui     $26, 0xb980             \n"
-               "       sb      $0, 0x18($26)           \n"
-               "       lui     $26, 0xb9c0             \n"
-               "       lb      $27, 0($26)             \n"
-               "       addiu   $27, $27, 1             \n"
-               "       sb      $27, 0($26)             \n"
-               "       sync                            \n"
-               "       .set    pop                     \n"
-               : : "r" (db1200_wait));
-}
-
 static int __init db1200_arch_init(void)
 {
        /* GPIO7 is low-level triggered CPLD cascade */
@@ -110,9 +73,6 @@ static int __init db1200_arch_init(void)
        irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
        irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
 
-       if (cpu_wait)
-               cpu_wait = db1200_wait;
-
        return 0;
 }
 arch_initcall(db1200_arch_init);
index 246df7a..2fafc78 100644 (file)
@@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = {
                .on     = vlynq_on,
                .off    = vlynq_off,
        },
-       .reset_bit      = 26,
+       .reset_bit      = 16,
        .gpio_bit       = 19,
 };
 
@@ -600,6 +600,7 @@ static int __init ar7_register_devices(void)
        }
 
        if (ar7_has_high_cpmac()) {
+               res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
                if (!res) {
                        cpmac_get_mac(1, cpmac_high_data.dev_addr);
 
index ea17941..8dba8cf 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/addrspace.h>
 #include <bcm63xx_board.h>
 #include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_uart.h>
 #include <bcm63xx_regs.h>
 #include <bcm63xx_io.h>
 #include <bcm63xx_dev_pci.h>
@@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = {
        .name                           = "96338GW",
        .expected_cpu_id                = 0x6338,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .enet0 = {
                .force_speed_100        = 1,
@@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = {
        .name                           = "96338W",
        .expected_cpu_id                = 0x6338,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .enet0 = {
                .force_speed_100        = 1,
@@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = {
 static struct board_info __initdata board_96345gw2 = {
        .name                           = "96345GW2",
        .expected_cpu_id                = 0x6345,
+
+       .has_uart0                      = 1,
 };
 #endif
 
@@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = {
        .name                           = "96348R",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_pci                        = 1,
 
@@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = {
        .name                           = "96348GW-10",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = {
        .name                           = "96348GW-11",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = {
        .name                           = "96348GW",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -349,9 +358,10 @@ static struct board_info __initdata board_FAST2404 = {
        .name                           = "F@ST2404",
        .expected_cpu_id                = 0x6348,
 
-       .has_enet0                      = 1,
-       .has_enet1                      = 1,
-       .has_pci                        = 1,
+       .has_uart0                      = 1,
+        .has_enet0                     = 1,
+        .has_enet1                     = 1,
+        .has_pci                       = 1,
 
        .enet0 = {
                .has_phy                = 1,
@@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = {
        .has_ehci0                      = 1,
 };
 
+static struct board_info __initdata board_rta1025w_16 = {
+       .name                           = "RTA1025W_16",
+       .expected_cpu_id                = 0x6348,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+};
+
+
 static struct board_info __initdata board_DV201AMR = {
        .name                           = "DV201AMR",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_pci                        = 1,
        .has_ohci0                      = 1,
 
@@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = {
        .name                           = "96348GW-A",
        .expected_cpu_id                = 0x6348,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = {
        .name                           = "96358VW",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = {
        .name                           = "96358VW2",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = {
        .name                           = "AGPF-S0",
        .expected_cpu_id                = 0x6358,
 
+       .has_uart0                      = 1,
        .has_enet0                      = 1,
        .has_enet1                      = 1,
        .has_pci                        = 1,
@@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = {
        .has_ohci0 = 1,
        .has_ehci0 = 1,
 };
+
+static struct board_info __initdata board_DWVS0 = {
+       .name                           = "DWV-S0",
+       .expected_cpu_id                = 0x6358,
+
+       .has_enet0                      = 1,
+       .has_enet1                      = 1,
+       .has_pci                        = 1,
+
+       .enet0 = {
+               .has_phy                = 1,
+               .use_internal_phy       = 1,
+       },
+
+       .enet1 = {
+               .force_speed_100        = 1,
+               .force_duplex_full      = 1,
+       },
+
+       .has_ohci0                      = 1,
+};
 #endif
 
 /*
@@ -552,16 +607,88 @@ static const struct board_info __initdata *bcm963xx_boards[] = {
        &board_FAST2404,
        &board_DV201AMR,
        &board_96348gw_a,
+       &board_rta1025w_16,
 #endif
 
 #ifdef CONFIG_BCM63XX_CPU_6358
        &board_96358vw,
        &board_96358vw2,
        &board_AGPFS0,
+       &board_DWVS0,
 #endif
 };
 
 /*
+ * Register a sane SPROMv2 to make the on-board
+ * bcm4318 WLAN work
+ */
+#ifdef CONFIG_SSB_PCIHOST
+static struct ssb_sprom bcm63xx_sprom = {
+       .revision               = 0x02,
+       .board_rev              = 0x17,
+       .country_code           = 0x0,
+       .ant_available_bg       = 0x3,
+       .pa0b0                  = 0x15ae,
+       .pa0b1                  = 0xfa85,
+       .pa0b2                  = 0xfe8d,
+       .pa1b0                  = 0xffff,
+       .pa1b1                  = 0xffff,
+       .pa1b2                  = 0xffff,
+       .gpio0                  = 0xff,
+       .gpio1                  = 0xff,
+       .gpio2                  = 0xff,
+       .gpio3                  = 0xff,
+       .maxpwr_bg              = 0x004c,
+       .itssi_bg               = 0x00,
+       .boardflags_lo          = 0x2848,
+       .boardflags_hi          = 0x0000,
+};
+#endif
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+       return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+static int board_get_mac_address(u8 *mac)
+{
+       u8 *p;
+       int count;
+
+       if (mac_addr_used >= nvram.mac_addr_count) {
+               printk(KERN_ERR PFX "not enough mac address\n");
+               return -ENODEV;
+       }
+
+       memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
+       p = mac + ETH_ALEN - 1;
+       count = mac_addr_used;
+
+       while (count--) {
+               do {
+                       (*p)++;
+                       if (*p != 0)
+                               break;
+                       p--;
+               } while (p != mac);
+       }
+
+       if (p == mac) {
+               printk(KERN_ERR PFX "unable to fetch mac address\n");
+               return -ENODEV;
+       }
+
+       mac_addr_used++;
+       return 0;
+}
+
+/*
  * early init callback, read nvram data from flash and checksum it
  */
 void __init board_prom_init(void)
@@ -659,6 +786,17 @@ void __init board_prom_init(void)
        }
 
        bcm_gpio_writel(val, GPIO_MODE_REG);
+
+       /* Generate MAC address for WLAN and
+        * register our SPROM */
+#ifdef CONFIG_SSB_PCIHOST
+       if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+               memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
+                       printk(KERN_ERR "failed to register fallback SPROM\n");
+       }
+#endif
 }
 
 /*
@@ -676,49 +814,6 @@ void __init board_setup(void)
                panic("unexpected CPU for bcm963xx board");
 }
 
-/*
- * return board name for /proc/cpuinfo
- */
-const char *board_get_name(void)
-{
-       return board.name;
-}
-
-/*
- * register & return a new board mac address
- */
-static int board_get_mac_address(u8 *mac)
-{
-       u8 *p;
-       int count;
-
-       if (mac_addr_used >= nvram.mac_addr_count) {
-               printk(KERN_ERR PFX "not enough mac address\n");
-               return -ENODEV;
-       }
-
-       memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
-       p = mac + ETH_ALEN - 1;
-       count = mac_addr_used;
-
-       while (count--) {
-               do {
-                       (*p)++;
-                       if (*p != 0)
-                               break;
-                       p--;
-               } while (p != mac);
-       }
-
-       if (p == mac) {
-               printk(KERN_ERR PFX "unable to fetch mac address\n");
-               return -ENODEV;
-       }
-
-       mac_addr_used++;
-       return 0;
-}
-
 static struct mtd_partition mtd_partitions[] = {
        {
                .name           = "cfe",
@@ -750,33 +845,6 @@ static struct platform_device mtd_dev = {
        },
 };
 
-/*
- * Register a sane SPROMv2 to make the on-board
- * bcm4318 WLAN work
- */
-#ifdef CONFIG_SSB_PCIHOST
-static struct ssb_sprom bcm63xx_sprom = {
-       .revision               = 0x02,
-       .board_rev              = 0x17,
-       .country_code           = 0x0,
-       .ant_available_bg       = 0x3,
-       .pa0b0                  = 0x15ae,
-       .pa0b1                  = 0xfa85,
-       .pa0b2                  = 0xfe8d,
-       .pa1b0                  = 0xffff,
-       .pa1b1                  = 0xffff,
-       .pa1b2                  = 0xffff,
-       .gpio0                  = 0xff,
-       .gpio1                  = 0xff,
-       .gpio2                  = 0xff,
-       .gpio3                  = 0xff,
-       .maxpwr_bg              = 0x004c,
-       .itssi_bg               = 0x00,
-       .boardflags_lo          = 0x2848,
-       .boardflags_hi          = 0x0000,
-};
-#endif
-
 static struct gpio_led_platform_data bcm63xx_led_data;
 
 static struct platform_device bcm63xx_gpio_leds = {
@@ -792,6 +860,12 @@ int __init board_register_devices(void)
 {
        u32 val;
 
+       if (board.has_uart0)
+               bcm63xx_uart_register(0);
+
+       if (board.has_uart1)
+               bcm63xx_uart_register(1);
+
        if (board.has_pccard)
                bcm63xx_pcmcia_register();
 
@@ -806,17 +880,6 @@ int __init board_register_devices(void)
        if (board.has_dsp)
                bcm63xx_dsp_register(&board.dsp);
 
-       /* Generate MAC address for WLAN and
-        * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
-       if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
-               memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-               memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
-               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
-                       printk(KERN_ERR "failed to register fallback SPROM\n");
-       }
-#endif
-
        /* read base address of boot chip select (0) */
        if (BCMCPU_IS_6345())
                val = 0x1fc00000;
index 70378bb..cbb7caf 100644 (file)
@@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = {
        [RSET_TIMER]            = BCM_6338_TIMER_BASE,
        [RSET_WDT]              = BCM_6338_WDT_BASE,
        [RSET_UART0]            = BCM_6338_UART0_BASE,
+       [RSET_UART1]            = BCM_6338_UART1_BASE,
        [RSET_GPIO]             = BCM_6338_GPIO_BASE,
        [RSET_SPI]              = BCM_6338_SPI_BASE,
        [RSET_OHCI0]            = BCM_6338_OHCI0_BASE,
@@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = {
        [RSET_TIMER]            = BCM_6345_TIMER_BASE,
        [RSET_WDT]              = BCM_6345_WDT_BASE,
        [RSET_UART0]            = BCM_6345_UART0_BASE,
+       [RSET_UART1]            = BCM_6345_UART1_BASE,
        [RSET_GPIO]             = BCM_6345_GPIO_BASE,
        [RSET_SPI]              = BCM_6345_SPI_BASE,
        [RSET_UDC0]             = BCM_6345_UDC0_BASE,
@@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = {
        [RSET_TIMER]            = BCM_6348_TIMER_BASE,
        [RSET_WDT]              = BCM_6348_WDT_BASE,
        [RSET_UART0]            = BCM_6348_UART0_BASE,
+       [RSET_UART1]            = BCM_6348_UART1_BASE,
        [RSET_GPIO]             = BCM_6348_GPIO_BASE,
        [RSET_SPI]              = BCM_6348_SPI_BASE,
        [RSET_OHCI0]            = BCM_6348_OHCI0_BASE,
@@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = {
        [RSET_TIMER]            = BCM_6358_TIMER_BASE,
        [RSET_WDT]              = BCM_6358_WDT_BASE,
        [RSET_UART0]            = BCM_6358_UART0_BASE,
+       [RSET_UART1]            = BCM_6358_UART1_BASE,
        [RSET_GPIO]             = BCM_6358_GPIO_BASE,
        [RSET_SPI]              = BCM_6358_SPI_BASE,
        [RSET_OHCI0]            = BCM_6358_OHCI0_BASE,
@@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = {
 static const int bcm96358_irqs[] = {
        [IRQ_TIMER]             = BCM_6358_TIMER_IRQ,
        [IRQ_UART0]             = BCM_6358_UART0_IRQ,
+       [IRQ_UART1]             = BCM_6358_UART1_IRQ,
        [IRQ_DSL]               = BCM_6358_DSL_IRQ,
        [IRQ_ENET0]             = BCM_6358_ENET0_IRQ,
        [IRQ_ENET1]             = BCM_6358_ENET1_IRQ,
index b051946..c2963da 100644 (file)
 #include <linux/platform_device.h>
 #include <bcm63xx_cpu.h>
 
-static struct resource uart_resources[] = {
+static struct resource uart0_resources[] = {
        {
-               .start          = -1, /* filled at runtime */
-               .end            = -1, /* filled at runtime */
+               /* start & end filled at runtime */
                .flags          = IORESOURCE_MEM,
        },
        {
-               .start          = -1, /* filled at runtime */
+               /* start filled at runtime */
                .flags          = IORESOURCE_IRQ,
        },
 };
 
-static struct platform_device bcm63xx_uart_device = {
-       .name           = "bcm63xx_uart",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(uart_resources),
-       .resource       = uart_resources,
+static struct resource uart1_resources[] = {
+       {
+               /* start & end filled at runtime */
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               /* start filled at runtime */
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device bcm63xx_uart_devices[] = {
+       {
+               .name           = "bcm63xx_uart",
+               .id             = 0,
+               .num_resources  = ARRAY_SIZE(uart0_resources),
+               .resource       = uart0_resources,
+       },
+
+       {
+               .name           = "bcm63xx_uart",
+               .id             = 1,
+               .num_resources  = ARRAY_SIZE(uart1_resources),
+               .resource       = uart1_resources,
+       }
 };
 
-int __init bcm63xx_uart_register(void)
+int __init bcm63xx_uart_register(unsigned int id)
 {
-       uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
-       uart_resources[0].end = uart_resources[0].start;
-       uart_resources[0].end += RSET_UART_SIZE - 1;
-       uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
-       return platform_device_register(&bcm63xx_uart_device);
+       if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
+               return -ENODEV;
+
+       if (id == 1 && !BCMCPU_IS_6358())
+               return -ENODEV;
+
+       if (id == 0) {
+               uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
+               uart0_resources[0].end = uart0_resources[0].start +
+                       RSET_UART_SIZE - 1;
+               uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
+       }
+
+       if (id == 1) {
+               uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
+               uart1_resources[0].end = uart1_resources[0].start +
+                       RSET_UART_SIZE - 1;
+               uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
+       }
+
+       return platform_device_register(&bcm63xx_uart_devices[id]);
 }
-arch_initcall(bcm63xx_uart_register);
index 87ca390..315bc7f 100644 (file)
@@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = {
 
 int __init bcm63xx_gpio_init(void)
 {
+       gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
+       gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
        bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
        pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
 
        return gpiochip_add(&bcm63xx_gpio_chip);
 }
-
-arch_initcall(bcm63xx_gpio_init);
index b321d3b..9a06fa9 100644 (file)
@@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops;
 extern void pci_console_init(const char *arg);
 #endif
 
-#ifdef CONFIG_CAVIUM_RESERVE32
-extern uint64_t octeon_reserve32_memory;
-#endif
 static unsigned long long MAX_MEMORY = 512ull << 20;
 
 struct octeon_boot_descriptor *octeon_boot_desc_ptr;
@@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
        write_octeon_c0_dcacheerr(0);
 }
 
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-/**
- * Called on every core to setup the wired tlb entry needed
- * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
- *
- */
-static void octeon_hal_setup_per_cpu_reserved32(void *unused)
-{
-       /*
-        * The config has selected to wire the reserve32 memory for all
-        * userspace applications. We need to put a wired TLB entry in for each
-        * 512MB of reserve32 memory. We only handle double 256MB pages here,
-        * so reserve32 must be multiple of 512MB.
-        */
-       uint32_t size = CONFIG_CAVIUM_RESERVE32;
-       uint32_t entrylo0 =
-               0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
-       uint32_t entrylo1 = entrylo0 + (256 << 14);
-       uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
-       while (size >= 512) {
-#if 0
-               pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
-                       smp_processor_id(), entryhi);
-#endif
-               add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
-               entrylo0 += 512 << 14;
-               entrylo1 += 512 << 14;
-               entryhi += 512 << 20;
-               size -= 512;
-       }
-}
-#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
-
-/**
- * Called to release the named block which was used to made sure
- * that nobody used the memory for something else during
- * init. Now we'll free it so userspace apps can use this
- * memory region with bootmem_alloc.
- *
- * This function is called only once from prom_free_prom_memory().
- */
-void octeon_hal_setup_reserved32(void)
-{
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-       on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
-#endif
-}
-
 /**
  * Reboot Octeon
  *
@@ -294,18 +243,6 @@ static void octeon_halt(void)
        octeon_kill_core(NULL);
 }
 
-#if 0
-/**
- * Platform time init specifics.
- * Returns
- */
-void __init plat_time_init(void)
-{
-       /* Nothing special here, but we are required to have one */
-}
-
-#endif
-
 /**
  * Handle all the error condition interrupts that might occur.
  *
@@ -502,25 +439,13 @@ void __init prom_init(void)
         * memory when it is getting memory from the
         * bootloader. Later, after the memory allocations are
         * complete, the reserve32 will be freed.
-        */
-#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
-       if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
-               pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
-                      "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
-                      "is set\n");
-       else
-               addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
-                                                       0, 0, 512 << 20,
-                                                       "CAVIUM_RESERVE32", 0);
-#else
-       /*
+        *
         * Allocate memory for RESERVED32 aligned on 2MB boundary. This
         * is in case we later use hugetlb entries with it.
         */
        addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
                                                0, 0, 2 << 20,
                                                "CAVIUM_RESERVE32", 0);
-#endif
        if (addr < 0)
                pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
        else
@@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
                panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
        }
 #endif
-
-       /* This call is here so that it is performed after any TLB
-          initializations. It needs to be after these in case the
-          CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
-       octeon_hal_setup_reserved32();
 }
index 51e9802..6d99b9d 100644 (file)
@@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu)
        uint32_t avail_coremask;
        struct cvmx_bootmem_named_block_desc *block_desc;
 
-#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
-       /* Disable the watchdog */
-       cvmx_ciu_wdogx_t ciu_wdog;
-       ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
-       ciu_wdog.s.mode = 0;
-       cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
-#endif
-
        while (per_cpu(cpu_state, cpu) != CPU_DEAD)
                cpu_relax();
 
index c2f06e3..0583bb2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc8
-# Wed Jul  2 17:02:55 2008
+# Linux kernel version: 2.6.34-rc3
+# Sat Apr  3 16:32:11 2010
 #
 CONFIG_MIPS=y
 
@@ -9,20 +9,25 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
 # CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MARKEINS is not set
+# CONFIG_NEC_MARKEINS is not set
 # CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
 # CONFIG_PNX8550_JBS is not set
 # CONFIG_PNX8550_STB810 is not set
 # CONFIG_PMC_MSP is not set
 # CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
 # CONFIG_SGI_IP22 is not set
 # CONFIG_SGI_IP27 is not set
 # CONFIG_SGI_IP28 is not set
@@ -36,10 +41,13 @@ CONFIG_MIPS=y
 # CONFIG_SIBYTE_SENTOSA is not set
 CONFIG_SIBYTE_BIGSUR=y
 # CONFIG_SNI_RM is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
 # CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 CONFIG_SIBYTE_BCM1x80=y
 CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_1 is not set
@@ -48,14 +56,13 @@ CONFIG_SIBYTE_SB1xxx_SOC=y
 # CONFIG_CPU_SB1_PASS_4 is not set
 # CONFIG_CPU_SB1_PASS_2_112x is not set
 # CONFIG_CPU_SB1_PASS_3 is not set
-# CONFIG_SIMULATION is not set
 # CONFIG_SB1_CEX_ALWAYS_FATAL is not set
 # CONFIG_SB1_CERR_STALL is not set
-CONFIG_SIBYTE_CFE=y
 # CONFIG_SIBYTE_CFE_CONSOLE is not set
 # CONFIG_SIBYTE_BUS_WATCHER is not set
 # CONFIG_SIBYTE_TBPROF is not set
 CONFIG_SIBYTE_HAS_ZBUS_PROFILING=y
+CONFIG_LOONGSON_UART_BASE=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -66,15 +73,13 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_CEVT_BCM1480=y
 CONFIG_CSRC_BCM1480=y
 CONFIG_CFE=y
 CONFIG_DMA_COHERENT=y
-CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_NO_IOPORT is not set
 CONFIG_CPU_BIG_ENDIAN=y
 # CONFIG_CPU_LITTLE_ENDIAN is not set
@@ -88,7 +93,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -101,6 +107,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_TX49XX is not set
 # CONFIG_CPU_R5000 is not set
 # CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
 # CONFIG_CPU_R6000 is not set
 # CONFIG_CPU_NEVADA is not set
 # CONFIG_CPU_R8000 is not set
@@ -108,6 +115,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 # CONFIG_CPU_RM7000 is not set
 # CONFIG_CPU_RM9000 is not set
 CONFIG_CPU_SB1=y
+# CONFIG_CPU_CAVIUM_OCTEON is not set
 CONFIG_SYS_HAS_CPU_SB1=y
 CONFIG_WEAK_ORDERING=y
 CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
@@ -123,11 +131,13 @@ CONFIG_64BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 # CONFIG_SIBYTE_DMA_PAGEOPS is not set
 CONFIG_MIPS_MT_DISABLED=y
 # CONFIG_MIPS_MT_SMP is not set
 # CONFIG_MIPS_MT_SMTC is not set
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_CPU_HAS_SYNC=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
@@ -142,18 +152,17 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_SMP=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_NR_CPUS_DEFAULT_4=y
 CONFIG_NR_CPUS=4
-# CONFIG_MIPS_CMP is not set
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -175,6 +184,7 @@ CONFIG_SECCOMP=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -188,6 +198,7 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
 CONFIG_TASKSTATS=y
@@ -195,23 +206,39 @@ CONFIG_TASK_DELAY_ACCT=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_CGROUPS is not set
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
 CONFIG_RELAY=y
-# CONFIG_NAMESPACES is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
@@ -222,29 +249,36 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 # CONFIG_PCSPKR_PLATFORM is not set
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_SYSCALL_WRAPPERS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -252,26 +286,52 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
 CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
 # IO Schedulers
 #
 CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
 CONFIG_IOSCHED_DEADLINE=y
 CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
 
 #
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
@@ -280,8 +340,9 @@ CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
 CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
 CONFIG_ZONE_DMA32=y
 # CONFIG_PCCARD is not set
@@ -291,6 +352,8 @@ CONFIG_ZONE_DMA32=y
 # Executable file formats
 #
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MIPS32_COMPAT=y
 CONFIG_COMPAT=y
@@ -304,23 +367,20 @@ CONFIG_BINFMT_ELF32=y
 #
 CONFIG_PM=y
 # CONFIG_PM_DEBUG is not set
-
-#
-# Networking
-#
+# CONFIG_PM_RUNTIME is not set
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -353,36 +413,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 CONFIG_TCP_MD5SIG=y
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-CONFIG_IP_VS_PROTO_TCP=y
-CONFIG_IP_VS_PROTO_UDP=y
-CONFIG_IP_VS_PROTO_ESP=y
-CONFIG_IP_VS_PROTO_AH=y
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
 CONFIG_IPV6=m
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -399,11 +429,13 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
 CONFIG_INET6_XFRM_MODE_BEET=m
 CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
 CONFIG_IPV6_SIT=m
+CONFIG_IPV6_SIT_6RD=y
 CONFIG_IPV6_NDISC_NODETYPE=y
 CONFIG_IPV6_TUNNEL=m
 CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_IPV6_SUBTREES=y
 # CONFIG_IPV6_MROUTE is not set
+CONFIG_NETLABEL=y
 CONFIG_NETWORK_SECMARK=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
@@ -421,19 +453,53 @@ CONFIG_NF_CONNTRACK_IRC=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CT_NETLINK=m
 CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_MARK=m
 CONFIG_NETFILTER_XT_TARGET_NFLOG=m
 CONFIG_NETFILTER_XT_TARGET_SECMARK=m
-CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
 CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
 CONFIG_NETFILTER_XT_MATCH_POLICY=m
 CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+# CONFIG_IP_VS_DEBUG is not set
+CONFIG_IP_VS_TAB_BITS=12
+
+#
+# IPVS transport protocol load balancing support
+#
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_AH_ESP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+
+#
+# IPVS scheduler
+#
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+CONFIG_IP_VS_FTP=m
 
 #
 # IP: Netfilter Configuration
 #
+CONFIG_NF_DEFRAG_IPV4=m
 CONFIG_NF_CONNTRACK_IPV4=m
 CONFIG_NF_CONNTRACK_PROC_COMPAT=y
 CONFIG_IP_NF_IPTABLES=m
@@ -459,22 +525,44 @@ CONFIG_IP_NF_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP_DCCP is not set
+CONFIG_IP_DCCP=m
+CONFIG_INET_DCCP_DIAG=m
+
+#
+# DCCP CCIDs Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
+CONFIG_IP_DCCP_CCID3=y
+# CONFIG_IP_DCCP_CCID3_DEBUG is not set
+CONFIG_IP_DCCP_CCID3_RTO=100
+CONFIG_IP_DCCP_TFRC_LIB=y
+
+#
+# DCCP Kernel Hacking
+#
+# CONFIG_IP_DCCP_DEBUG is not set
 CONFIG_IP_SCTP=m
 # CONFIG_SCTP_DBG_MSG is not set
 # CONFIG_SCTP_DBG_OBJCNT is not set
 # CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
+CONFIG_SCTP_HMAC_SHA1=y
+# CONFIG_SCTP_HMAC_MD5 is not set
+# CONFIG_RDS is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
+CONFIG_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
@@ -482,26 +570,47 @@ CONFIG_SCTP_HMAC_MD5=y
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
 # CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+CONFIG_AX25=m
+CONFIG_AX25_DAMA_SLAVE=y
+CONFIG_NETROM=m
+CONFIG_ROSE=m
+
+#
+# AX.25 network device drivers
+#
+CONFIG_MKISS=m
+CONFIG_6PACK=m
+CONFIG_BPQETHER=m
+CONFIG_BAYCOM_SER_FDX=m
+CONFIG_BAYCOM_SER_HDX=m
+CONFIG_YAM=m
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
 CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
 
 #
-# Wireless
+# CFG80211 needs to be enabled for MAC80211
 #
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -513,9 +622,12 @@ CONFIG_FIB_RULES=y
 # Generic Driver Options
 #
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=m
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
@@ -530,33 +642,53 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
 CONFIG_BLK_DEV_NBD=m
 # CONFIG_BLK_DEV_SX8 is not set
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 CONFIG_SGI_IOC4=m
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+CONFIG_EEPROM_LEGACY=y
+CONFIG_EEPROM_MAX6875=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
 CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
 
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_XFER_MODE=y
+CONFIG_IDE_TIMINGS=y
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 CONFIG_BLK_DEV_IDETAPE=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_IDE_TASK_IOCTL is not set
 CONFIG_IDE_PROC_FS=y
 
@@ -581,14 +713,13 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_AMD74XX is not set
 CONFIG_BLK_DEV_CMD64X=y
 # CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5520 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_BLK_DEV_HPT366 is not set
 # CONFIG_BLK_DEV_JMICRON is not set
 # CONFIG_BLK_DEV_SC1200 is not set
 # CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
 CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_IT821X is not set
 # CONFIG_BLK_DEV_NS87415 is not set
@@ -600,14 +731,12 @@ CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 CONFIG_BLK_DEV_TC86C001=m
-# CONFIG_BLK_DEV_IDE_SWARM is not set
 CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_DMA=y
@@ -625,10 +754,6 @@ CONFIG_BLK_DEV_SR=m
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
 CONFIG_CHR_DEV_SCH=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
 # CONFIG_SCSI_MULTI_LUN is not set
 # CONFIG_SCSI_CONSTANTS is not set
 # CONFIG_SCSI_LOGGING is not set
@@ -645,27 +770,36 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SRP_ATTRS is not set
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
 # CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_ARCMSR is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
 # CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
 # CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
@@ -676,9 +810,15 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 CONFIG_SATA_SIL24=y
@@ -700,6 +840,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
 # CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
 # CONFIG_PATA_ATIIXP is not set
 # CONFIG_PATA_CMD640_PCI is not set
 # CONFIG_PATA_CMD64X is not set
@@ -715,6 +856,7 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_IT821X is not set
 # CONFIG_PATA_IT8213 is not set
 # CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
 # CONFIG_PATA_TRIFLEX is not set
 # CONFIG_PATA_MARVELL is not set
 # CONFIG_PATA_MPIIX is not set
@@ -725,14 +867,16 @@ CONFIG_ATA_SFF=y
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
 # CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
 # CONFIG_PATA_PDC_OLD is not set
 # CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
 # CONFIG_PATA_RZ1000 is not set
 # CONFIG_PATA_SC1200 is not set
 # CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
 CONFIG_PATA_SIL680=y
 # CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
@@ -745,13 +889,16 @@ CONFIG_PATA_SIL680=y
 #
 
 #
-# Enable only one of the two stacks, unless you know what you are doing
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
 #
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -774,6 +921,9 @@ CONFIG_PHYLIB=y
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
 # CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
@@ -783,23 +933,33 @@ CONFIG_MII=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -811,29 +971,42 @@ CONFIG_SB1250_MAC=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
+CONFIG_MDIO=m
 # CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
 CONFIG_CHELSIO_T3=m
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 CONFIG_NETXEN_NIC=m
 # CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
+# CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
 
 #
-# Wireless LAN
+# Enable WiMAX (Networking options) to see the WiMAX drivers
 #
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -856,6 +1029,7 @@ CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
@@ -873,6 +1047,7 @@ CONFIG_SERIO_SERPORT=y
 # CONFIG_SERIO_PCIPS2 is not set
 # CONFIG_SERIO_LIBPS2 is not set
 CONFIG_SERIO_RAW=m
+# CONFIG_SERIO_ALTERA_PS2 is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -893,8 +1068,6 @@ CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_N_HDLC is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
 # CONFIG_STALDRV is not set
 # CONFIG_NOZOMI is not set
 
@@ -911,7 +1084,9 @@ CONFIG_SERIAL_SB1250_DUART_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
 CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
@@ -923,89 +1098,99 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# PC SMBus host controller drivers
+#
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
 # CONFIG_I2C_ALI15X3 is not set
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-CONFIG_I2C_SIBYTE=y
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
 
 #
-# Miscellaneous I2C Chip support
+# I2C system bus drivers (mostly embedded / system-on-chip)
 #
-# CONFIG_DS1682 is not set
-CONFIG_EEPROM_LEGACY=y
-CONFIG_SENSORS_PCF8574=y
-# CONFIG_PCF8575 is not set
-CONFIG_SENSORS_PCF8591=y
-CONFIG_EEPROM_MAX6875=y
-# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+CONFIG_I2C_SIBYTE=y
+# CONFIG_I2C_STUB is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CHIP=y
 # CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+CONFIG_VGA_ARB=y
+CONFIG_VGA_ARB_MAX_GPUS=16
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -1016,10 +1201,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1030,9 +1211,18 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -1040,41 +1230,66 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
 #
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
 # File systems
 #
 CONFIG_EXT2_FS=m
 CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
 CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_FS_XIP=y
+CONFIG_JBD=m
+CONFIG_JBD2=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 CONFIG_QUOTA=y
 CONFIG_QUOTA_NETLINK_INTERFACE=y
 # CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QUOTA_TREE=m
 # CONFIG_QFMT_V1 is not set
 CONFIG_QFMT_V2=m
 CONFIG_QUOTACTL=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=m
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -1103,15 +1318,13 @@ CONFIG_NTFS_RW=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_CONFIGFS_FS=m
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_ECRYPT_FS is not set
@@ -1120,9 +1333,12 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1133,16 +1349,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+CONFIG_RPCSEC_GSS_SPKM3=m
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1205,12 +1422,18 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=2048
 CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -1219,23 +1442,53 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_LOCK_ALLOC is not set
 # CONFIG_PROVE_LOCKING is not set
 # CONFIG_LOCK_STAT is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DEBUG_LIST is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
 # CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_RCU_CPU_STALL_DETECTOR=y
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_EARLY_PRINTK=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_SB1XXX_CORELIS is not set
@@ -1246,20 +1499,50 @@ CONFIG_DEBUG_MUTEXES=y
 #
 CONFIG_KEYS=y
 CONFIG_KEYS_DEBUG_PROC_KEYS=y
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_NETWORK_XFRM=y
+# CONFIG_SECURITY_PATH is not set
+CONFIG_LSM_MMAP_MIN_ADDR=65536
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SELINUX_DEVELOP=y
+CONFIG_SECURITY_SELINUX_AVC_STATS=y
+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
+# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set
+# CONFIG_SECURITY_SMACK is not set
+# CONFIG_SECURITY_TOMOYO is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
 CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 CONFIG_CRYPTO_NULL=y
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
 # CONFIG_CRYPTO_TEST is not set
@@ -1276,7 +1559,7 @@ CONFIG_CRYPTO_SEQIV=m
 #
 CONFIG_CRYPTO_CBC=m
 CONFIG_CRYPTO_CTR=m
-# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_CTS=m
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_LRW=m
 CONFIG_CRYPTO_PCBC=m
@@ -1287,14 +1570,20 @@ CONFIG_CRYPTO_XTS=m
 #
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
 
 #
 # Digest
 #
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_GHASH=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1325,25 +1614,36 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
 # Compression
 #
 CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
 CONFIG_LIBCRC32C=m
 CONFIG_AUDIT_GENERIC=y
-CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
-CONFIG_PLIST=y
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index 1dd74fb..9252d9b 100644 (file)
 #include <asm/siginfo.h>
 
 struct mips_abi {
-       int (* const setup_frame)(struct k_sigaction * ka,
+       int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
                                  struct pt_regs *regs, int signr,
                                  sigset_t *set);
-       int (* const setup_rt_frame)(struct k_sigaction * ka,
+       const unsigned long     signal_return_offset;
+       int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
                               struct pt_regs *regs, int signr,
                               sigset_t *set, siginfo_t *info);
+       const unsigned long     rt_signal_return_offset;
        const unsigned long     restart;
 };
 
index e53d7be..ea77a42 100644 (file)
@@ -310,6 +310,7 @@ do {                                                                        \
 
 #endif /* CONFIG_64BIT */
 
+struct pt_regs;
 struct task_struct;
 
 extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
@@ -367,4 +368,8 @@ extern const char *__elf_platform;
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 #endif
 
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+                                      int uses_interp);
 #endif /* _ASM_ELF_H */
index aecada6..3b40927 100644 (file)
@@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
 
 #define MIPS_FPU_EMU_INC_STATS(M)                                      \
-       cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
+do {                                                                   \
+       preempt_disable();                                              \
+       __local_inc(&__get_cpu_var(fpuemustats).M);                     \
+       preempt_enable();                                               \
+} while (0)
 
 #else
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
index b12c4ac..96a2391 100644 (file)
@@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
        RSET_TIMER,
        RSET_WDT,
        RSET_UART0,
+       RSET_UART1,
        RSET_GPIO,
        RSET_SPI,
        RSET_UDC0,
@@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
 #define BCM_6338_TIMER_BASE            (0xfffe0200)
 #define BCM_6338_WDT_BASE              (0xfffe021c)
 #define BCM_6338_UART0_BASE            (0xfffe0300)
+#define BCM_6338_UART1_BASE            (0xdeadbeef)
 #define BCM_6338_GPIO_BASE             (0xfffe0400)
 #define BCM_6338_SPI_BASE              (0xfffe0c00)
 #define BCM_6338_UDC0_BASE             (0xdeadbeef)
@@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
 #define BCM_6345_TIMER_BASE            (0xfffe0200)
 #define BCM_6345_WDT_BASE              (0xfffe021c)
 #define BCM_6345_UART0_BASE            (0xfffe0300)
+#define BCM_6345_UART1_BASE            (0xdeadbeef)
 #define BCM_6345_GPIO_BASE             (0xfffe0400)
 #define BCM_6345_SPI_BASE              (0xdeadbeef)
 #define BCM_6345_UDC0_BASE             (0xdeadbeef)
@@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
 #define BCM_6348_TIMER_BASE            (0xfffe0200)
 #define BCM_6348_WDT_BASE              (0xfffe021c)
 #define BCM_6348_UART0_BASE            (0xfffe0300)
+#define BCM_6348_UART1_BASE            (0xdeadbeef)
 #define BCM_6348_GPIO_BASE             (0xfffe0400)
 #define BCM_6348_SPI_BASE              (0xfffe0c00)
 #define BCM_6348_UDC0_BASE             (0xfffe1000)
@@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
 #define BCM_6358_TIMER_BASE            (0xfffe0040)
 #define BCM_6358_WDT_BASE              (0xfffe005c)
 #define BCM_6358_UART0_BASE            (0xfffe0100)
+#define BCM_6358_UART1_BASE            (0xfffe0120)
 #define BCM_6358_GPIO_BASE             (0xfffe0080)
 #define BCM_6358_SPI_BASE              (0xdeadbeef)
 #define BCM_6358_UDC0_BASE             (0xfffe0800)
@@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6338_WDT_BASE;
        case RSET_UART0:
                return BCM_6338_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6338_UART1_BASE;
        case RSET_GPIO:
                return BCM_6338_GPIO_BASE;
        case RSET_SPI:
@@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6345_WDT_BASE;
        case RSET_UART0:
                return BCM_6345_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6345_UART1_BASE;
        case RSET_GPIO:
                return BCM_6345_GPIO_BASE;
        case RSET_SPI:
@@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6348_WDT_BASE;
        case RSET_UART0:
                return BCM_6348_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6348_UART1_BASE;
        case RSET_GPIO:
                return BCM_6348_GPIO_BASE;
        case RSET_SPI:
@@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
                return BCM_6358_WDT_BASE;
        case RSET_UART0:
                return BCM_6358_UART0_BASE;
+       case RSET_UART1:
+               return BCM_6358_UART1_BASE;
        case RSET_GPIO:
                return BCM_6358_GPIO_BASE;
        case RSET_SPI:
@@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
 enum bcm63xx_irq {
        IRQ_TIMER = 0,
        IRQ_UART0,
+       IRQ_UART1,
        IRQ_DSL,
        IRQ_ENET0,
        IRQ_ENET1,
@@ -510,6 +524,7 @@ enum bcm63xx_irq {
  */
 #define BCM_6358_TIMER_IRQ             (IRQ_INTERNAL_BASE + 0)
 #define BCM_6358_UART0_IRQ             (IRQ_INTERNAL_BASE + 2)
+#define BCM_6358_UART1_IRQ             (IRQ_INTERNAL_BASE + 3)
 #define BCM_6358_OHCI0_IRQ             (IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_ENET1_IRQ             (IRQ_INTERNAL_BASE + 6)
 #define BCM_6358_ENET0_IRQ             (IRQ_INTERNAL_BASE + 8)
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
new file mode 100644 (file)
index 0000000..23c705b
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_UART_H_
+#define BCM63XX_DEV_UART_H_
+
+int bcm63xx_uart_register(unsigned int id);
+
+#endif /* BCM63XX_DEV_UART_H_ */
index 76a0b72..43d4da0 100644 (file)
@@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void)
        switch (bcm63xx_get_cpu_id()) {
        case BCM6358_CPU_ID:
                return 40;
+       case BCM6338_CPU_ID:
+               return 8;
+       case BCM6345_CPU_ID:
+               return 16;
        case BCM6348_CPU_ID:
        default:
                return 37;
index 6479090..474daaa 100644 (file)
@@ -45,6 +45,8 @@ struct board_info {
        unsigned int    has_ohci0:1;
        unsigned int    has_ehci0:1;
        unsigned int    has_dsp:1;
+       unsigned int    has_uart0:1;
+       unsigned int    has_uart1:1;
 
        /* ethernet config */
        struct bcm63xx_enet_platform_data enet0;
index 71742ba..f453c01 100644 (file)
@@ -24,7 +24,7 @@
 #define cpu_has_smartmips              0
 #define cpu_has_vtag_icache            0
 
-#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
+#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
 #define cpu_has_dc_aliases             0
 #endif
 
index 7950ef4..743385d 100644 (file)
 #if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
     defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
 
-#define BCM1250_M3_WAR 1
+#ifndef __ASSEMBLY__
+extern int sb1250_m3_workaround_needed(void);
+#endif
+
+#define BCM1250_M3_WAR sb1250_m3_workaround_needed()
 #define SIBYTE_1956_WAR        1
 
 #else
index 4063edd..c436138 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef __ASM_MMU_H
 #define __ASM_MMU_H
 
-typedef unsigned long mm_context_t[NR_CPUS];
+typedef struct {
+       unsigned long asid[NR_CPUS];
+       void *vdso;
+} mm_context_t;
 
 #endif /* __ASM_MMU_H */
index 145bb81..d959273 100644 (file)
@@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
 
 #endif
 
-#define cpu_context(cpu, mm)   ((mm)->context[cpu])
+#define cpu_context(cpu, mm)   ((mm)->context.asid[cpu])
 #define cpu_asid(cpu, mm)      (cpu_context((cpu), (mm)) & ASID_MASK)
 #define asid_cache(cpu)                (cpu_data[cpu].asid_cache)
 
index ac32572..a16beaf 100644 (file)
@@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
                                 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
 
-#define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
-#define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
+#define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE +    \
+                                                               PHYS_OFFSET)
+#define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET -    \
+                                                               PHYS_OFFSET)
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
index 087a888..ab38791 100644 (file)
@@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
 
 extern unsigned int vced_count, vcei_count;
 
+/*
+ * A special page (the vdso) is mapped into all processes at the very
+ * top of the virtual memory space.
+ */
+#define SPECIAL_PAGES_SIZE PAGE_SIZE
+
 #ifdef CONFIG_32BIT
 /*
  * User space process size: 2GB. This is hardcoded into a few places,
  * so don't change it unless you know what you are doing.
  */
 #define TASK_SIZE      0x7fff8000UL
-#define STACK_TOP      TASK_SIZE
+#define STACK_TOP      ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
@@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count;
 #define TASK_SIZE32    0x7fff8000UL
 #define TASK_SIZE      0x10000000000UL
 #define STACK_TOP      \
-      (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
+       (((test_thread_flag(TIF_32BIT_ADDR) ?                           \
+          TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
index 3b6da33..c841912 100644 (file)
                .endm
 #else
                .macro  get_saved_sp    /* Uniprocessor variation */
+#ifdef CONFIG_CPU_LOONGSON2F
+               /*
+                * Clear BTB (branch target buffer), forbid RAS (return address
+                * stack) to workaround the Out-of-order Issue in Loongson2F
+                * via its diagnostic register.
+                */
+               move    k0, ra
+               jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             jal     1f
+                nop
+1:             move    ra, k0
+               li      k0, 3
+               mtc0    k0, $22
+#endif /* CONFIG_CPU_LOONGSON2F */
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
                lui     k1, %hi(kernelsp)
 #else
index b99bd07..11a8b52 100644 (file)
@@ -84,6 +84,7 @@ Ip_u2s3u1(_lw);
 Ip_u1u2u3(_mfc0);
 Ip_u1u2u3(_mtc0);
 Ip_u2u1u3(_ori);
+Ip_u3u1u2(_or);
 Ip_u2s3u1(_pref);
 Ip_0(_rfe);
 Ip_u2s3u1(_sc);
@@ -102,6 +103,7 @@ Ip_0(_tlbwr);
 Ip_u3u1u2(_xor);
 Ip_u2u1u3(_xori);
 Ip_u2u1msbu3(_dins);
+Ip_u1(_syscall);
 
 /* Handle labels. */
 struct uasm_label {
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
new file mode 100644 (file)
index 0000000..cca56aa
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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) 2009 Cavium Networks
+ */
+
+#ifndef __ASM_VDSO_H
+#define __ASM_VDSO_H
+
+#include <linux/types.h>
+
+
+#ifdef CONFIG_32BIT
+struct mips_vdso {
+       u32 signal_trampoline[2];
+       u32 rt_signal_trampoline[2];
+};
+#else  /* !CONFIG_32BIT */
+struct mips_vdso {
+       u32 o32_signal_trampoline[2];
+       u32 o32_rt_signal_trampoline[2];
+       u32 rt_signal_trampoline[2];
+       u32 n32_rt_signal_trampoline[2];
+};
+#endif /* CONFIG_32BIT */
+
+#endif /* __ASM_VDSO_H */
index ef20957..7a6ac50 100644 (file)
@@ -6,7 +6,7 @@ extra-y         := head.o init_task.o vmlinux.lds
 
 obj-y          += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
                   ptrace.o reset.o setup.o signal.o syscall.o \
-                  time.o topology.o traps.o unaligned.o watch.o
+                  time.o topology.o traps.o unaligned.o watch.o vdso.o
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
index d7ca256..cefc6e2 100644 (file)
@@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
        spin_unlock_irqrestore(&loongson2_wait_lock, flags);
 }
 EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
+
+MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
+MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
+MODULE_LICENSE("GPL");
index 463b71b..9996094 100644 (file)
@@ -63,8 +63,13 @@ void __noreturn cpu_idle(void)
 
                        smtc_idle_loop_hook();
 #endif
-                       if (cpu_wait)
+
+                       if (cpu_wait) {
+                               /* Don't trace irqs off for idle */
+                               stop_critical_timings();
                                (*cpu_wait)();
+                               start_critical_timings();
+                       }
                }
 #ifdef CONFIG_HOTPLUG_CPU
                if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
index 6c8e8c4..10263b4 100644 (file)
  */
 extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
                                 size_t frame_size);
-/*
- * install trampoline code to get back from the sig handler
- */
-extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
-
 /* Check and clear pending FPU exceptions in saved CSR */
 extern int fpcsr_pending(unsigned int __user *fpcsr);
 
index d0c68b5..2099d5a 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/ucontext.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
 extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe {
        u32 sf_ass[4];          /* argument save space for o32 */
-       u32 sf_code[2];         /* signal trampoline */
+       u32 sf_pad[2];          /* Was: signal trampoline */
        struct sigcontext sf_sc;
        sigset_t sf_mask;
 };
 
 struct rt_sigframe {
        u32 rs_ass[4];          /* argument save space for o32 */
-       u32 rs_code[2];         /* signal trampoline */
+       u32 rs_pad[2];          /* Was: signal trampoline */
        struct siginfo rs_info;
        struct ucontext rs_uc;
 };
 
-#else
-
-struct sigframe {
-       u32 sf_ass[4];                  /* argument save space for o32 */
-       u32 sf_pad[2];
-       struct sigcontext sf_sc;        /* hw context */
-       sigset_t sf_mask;
-       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-struct rt_sigframe {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
-       struct siginfo rs_info;
-       struct ucontext rs_uc;
-       u32 rs_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-#endif
-
 /*
  * Helper routines
  */
@@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
        return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 }
 
-int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
-{
-       int err;
-
-       /*
-        * Set up the return code ...
-        *
-        *         li      v0, __NR__foo_sigreturn
-        *         syscall
-        */
-
-       err = __put_user(0x24020000 + syscall, tramp + 0);
-       err |= __put_user(0x0000000c         , tramp + 1);
-       if (ICACHE_REFILLS_WORKAROUND_WAR) {
-               err |= __put_user(0, tramp + 2);
-               err |= __put_user(0, tramp + 3);
-               err |= __put_user(0, tramp + 4);
-               err |= __put_user(0, tramp + 5);
-               err |= __put_user(0, tramp + 6);
-               err |= __put_user(0, tramp + 7);
-       }
-       flush_cache_sigtramp((unsigned long) tramp);
-
-       return err;
-}
-
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
@@ -484,8 +432,8 @@ badframe:
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct k_sigaction *ka,
+                      struct pt_regs *regs, int signr, sigset_t *set)
 {
        struct sigframe __user *frame;
        int err = 0;
@@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
-
        err |= setup_sigcontext(regs, &frame->sf_sc);
        err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
        if (err)
@@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->sf_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -529,8 +475,9 @@ give_sigsegv:
 }
 #endif
 
-static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
+                         struct pt_regs *regs, int signr, sigset_t *set,
+                         siginfo_t *info)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
@@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
-
        /* Create siginfo.  */
        err |= copy_siginfo_to_user(&frame->rs_info, info);
 
@@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -590,8 +535,11 @@ give_sigsegv:
 struct mips_abi mips_abi = {
 #ifdef CONFIG_TRAD_SIGNALS
        .setup_frame    = setup_frame,
+       .signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
 #endif
        .setup_rt_frame = setup_rt_frame,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, rt_signal_trampoline),
        .restart        = __NR_restart_syscall
 };
 
@@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 {
        int ret;
+       struct mips_abi *abi = current->thread.abi;
+       void *vdso = current->mm->context.vdso;
 
        switch(regs->regs[0]) {
        case ERESTART_RESTARTBLOCK:
@@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
        regs->regs[0] = 0;              /* Don't deal with this again.  */
 
        if (sig_uses_siginfo(ka))
-               ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
+               ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
+                                         ka, regs, sig, oldset, info);
        else
-               ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
+               ret = abi->setup_frame(vdso + abi->signal_return_offset,
+                                      ka, regs, sig, oldset);
 
        spin_lock_irq(&current->sighand->siglock);
        sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
index 03abaf0..a0ed0e0 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/system.h>
 #include <asm/fpu.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
@@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_O32_sigreturn             4119
-#define __NR_O32_rt_sigreturn          4193
 #define __NR_O32_restart_syscall        4253
 
 /* 32-bit compatibility types */
@@ -77,47 +76,20 @@ struct ucontext32 {
        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-/*
- * Horribly complicated - with the bloody RM9000 workarounds enabled
- * the signal trampolines is moving to the end of the structure so we can
- * increase the alignment without breaking software compatibility.
- */
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
 struct sigframe32 {
        u32 sf_ass[4];          /* argument save space for o32 */
-       u32 sf_code[2];         /* signal trampoline */
+       u32 sf_pad[2];          /* Was: signal trampoline */
        struct sigcontext32 sf_sc;
        compat_sigset_t sf_mask;
 };
 
 struct rt_sigframe32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_code[2];                 /* signal trampoline */
+       u32 rs_pad[2];                  /* Was: signal trampoline */
        compat_siginfo_t rs_info;
        struct ucontext32 rs_uc;
 };
 
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
-struct sigframe32 {
-       u32 sf_ass[4];                  /* argument save space for o32 */
-       u32 sf_pad[2];
-       struct sigcontext32 sf_sc;      /* hw context */
-       compat_sigset_t sf_mask;
-       u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
-};
-
-struct rt_sigframe32 {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
-       compat_siginfo_t rs_info;
-       struct ucontext32 rs_uc;
-       u32 rs_code[8] __attribute__((aligned(32)));    /* signal trampoline */
-};
-
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 /*
  * sigcontext handlers
  */
@@ -598,8 +570,8 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
+                         struct pt_regs *regs, int signr, sigset_t *set)
 {
        struct sigframe32 __user *frame;
        int err = 0;
@@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
-
        err |= setup_sigcontext32(regs, &frame->sf_sc);
        err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 
@@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->sf_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -644,8 +614,9 @@ give_sigsegv:
        return -EFAULT;
 }
 
-static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
-       int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
+                            struct pt_regs *regs, int signr, sigset_t *set,
+                            siginfo_t *info)
 {
        struct rt_sigframe32 __user *frame;
        int err = 0;
@@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
-
        /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -709,7 +678,11 @@ give_sigsegv:
  */
 struct mips_abi mips_abi_32 = {
        .setup_frame    = setup_frame_32,
+       .signal_return_offset =
+               offsetof(struct mips_vdso, o32_signal_trampoline),
        .setup_rt_frame = setup_rt_frame_32,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, o32_rt_signal_trampoline),
        .restart        = __NR_O32_restart_syscall
 };
 
index bb277e8..2c5df81 100644 (file)
 #include <asm/fpu.h>
 #include <asm/cpu-features.h>
 #include <asm/war.h>
+#include <asm/vdso.h>
 
 #include "signal-common.h"
 
 /*
  * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  */
-#define __NR_N32_rt_sigreturn          6211
 #define __NR_N32_restart_syscall       6214
 
 extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
@@ -67,27 +67,13 @@ struct ucontextn32 {
        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
 };
 
-#if ICACHE_REFILLS_WORKAROUND_WAR == 0
-
-struct rt_sigframe_n32 {
-       u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_code[2];                 /* signal trampoline */
-       struct compat_siginfo rs_info;
-       struct ucontextn32 rs_uc;
-};
-
-#else  /* ICACHE_REFILLS_WORKAROUND_WAR */
-
 struct rt_sigframe_n32 {
        u32 rs_ass[4];                  /* argument save space for o32 */
-       u32 rs_pad[2];
+       u32 rs_pad[2];                  /* Was: signal trampoline */
        struct compat_siginfo rs_info;
        struct ucontextn32 rs_uc;
-       u32 rs_code[8] ____cacheline_aligned;           /* signal trampoline */
 };
 
-#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
-
 extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
 
 asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
@@ -173,7 +159,7 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_rt_frame_n32(struct k_sigaction * ka,
+static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
        struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
 {
        struct rt_sigframe_n32 __user *frame;
@@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto give_sigsegv;
 
-       install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
-
        /* Create siginfo.  */
        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 
@@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
-       regs->regs[31] = (unsigned long) frame->rs_code;
+       regs->regs[31] = (unsigned long) sig_return;
        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
@@ -235,5 +219,7 @@ give_sigsegv:
 
 struct mips_abi mips_abi_n32 = {
        .setup_rt_frame = setup_rt_frame_n32,
+       .rt_signal_return_offset =
+               offsetof(struct mips_vdso, n32_rt_signal_trampoline),
        .restart        = __NR_N32_restart_syscall
 };
index 25e825a..a95dea5 100644 (file)
@@ -182,7 +182,7 @@ static int vpemask[2][8] = {
        {0, 0, 0, 0, 0, 0, 0, 1}
 };
 int tcnoprog[NR_CPUS];
-static atomic_t idle_hook_initialized = {0};
+static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
 static int clock_hang_reported[NR_CPUS];
 
 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
index 9587abc..dd81b0f 100644 (file)
@@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
        int do_color_align;
        unsigned long task_size;
 
-       task_size = STACK_TOP;
+#ifdef CONFIG_32BIT
+       task_size = TASK_SIZE;
+#else /* Must be CONFIG_64BIT*/
+       task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
+#endif
 
        if (len > task_size)
                return -ENOMEM;
index 4e00f9b..1a4dd65 100644 (file)
@@ -1599,7 +1599,7 @@ void __init trap_init(void)
                ebase = (unsigned long)
                        __alloc_bootmem(size, 1 << fls(size), 0);
        } else {
-               ebase = CAC_BASE;
+               ebase = CKSEG0;
                if (cpu_has_mips_r2)
                        ebase += (read_c0_ebase() & 0x3ffff000);
        }
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
new file mode 100644 (file)
index 0000000..b773c11
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * 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) 2009, 2010 Cavium Networks, Inc.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+
+#include <asm/vdso.h>
+#include <asm/uasm.h>
+
+/*
+ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+ */
+#define __NR_O32_sigreturn             4119
+#define __NR_O32_rt_sigreturn          4193
+#define __NR_N32_rt_sigreturn          6211
+
+static struct page *vdso_page;
+
+static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
+{
+       uasm_i_addiu(&tramp, 2, 0, sigreturn);  /* li v0, sigreturn */
+       uasm_i_syscall(&tramp, 0);
+}
+
+static int __init init_vdso(void)
+{
+       struct mips_vdso *vdso;
+
+       vdso_page = alloc_page(GFP_KERNEL);
+       if (!vdso_page)
+               panic("Cannot allocate vdso");
+
+       vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+       if (!vdso)
+               panic("Cannot map vdso");
+       clear_page(vdso);
+
+       install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
+#ifdef CONFIG_32BIT
+       install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
+#else
+       install_trampoline(vdso->n32_rt_signal_trampoline,
+                          __NR_N32_rt_sigreturn);
+       install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
+       install_trampoline(vdso->o32_rt_signal_trampoline,
+                          __NR_O32_rt_sigreturn);
+#endif
+
+       vunmap(vdso);
+
+       pr_notice("init_vdso successfull\n");
+
+       return 0;
+}
+device_initcall(init_vdso);
+
+static unsigned long vdso_addr(unsigned long start)
+{
+       return STACK_TOP;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+       int ret;
+       unsigned long addr;
+       struct mm_struct *mm = current->mm;
+
+       down_write(&mm->mmap_sem);
+
+       addr = vdso_addr(mm->start_stack);
+
+       addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
+       if (IS_ERR_VALUE(addr)) {
+               ret = addr;
+               goto up_fail;
+       }
+
+       ret = install_special_mapping(mm, addr, PAGE_SIZE,
+                                     VM_READ|VM_EXEC|
+                                     VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+                                     VM_ALWAYSDUMP,
+                                     &vdso_page);
+
+       if (ret)
+               goto up_fail;
+
+       mm->context.vdso = (void *)addr;
+
+up_fail:
+       up_write(&mm->mmap_sem);
+       return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
+               return "[vdso]";
+       return NULL;
+}
index 6b3b1de..5995969 100644 (file)
@@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
 
 void __udelay(unsigned long us)
 {
-       unsigned int lpj = current_cpu_data.udelay_val;
+       unsigned int lpj = raw_current_cpu_data.udelay_val;
 
        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
 }
@@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
 
 void __ndelay(unsigned long ns)
 {
-       unsigned int lpj = current_cpu_data.udelay_val;
+       unsigned int lpj = raw_current_cpu_data.udelay_val;
 
        __delay((ns * 0x00000005ull * HZ * lpj) >> 32);
 }
index 3f19d1c..05909d5 100644 (file)
@@ -17,8 +17,7 @@ struct DWstruct {
 #error I feel sick.
 #endif
 
-typedef union
-{
+typedef union {
        struct DWstruct s;
        long long ll;
 } DWunion;
index be8627b..12af739 100644 (file)
@@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
 }
 
 unsigned long _page_cachable_default;
-EXPORT_SYMBOL_GPL(_page_cachable_default);
+EXPORT_SYMBOL(_page_cachable_default);
 
 static inline void setup_protection_map(void)
 {
index 0de0e41..d1f68aa 100644 (file)
@@ -788,10 +788,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
         * create the plain linear handler
         */
        if (bcm1250_m3_war()) {
-               UASM_i_MFC0(&p, K0, C0_BADVADDR);
-               UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+               unsigned int segbits = 44;
+
+               uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+               uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
                uasm_i_xor(&p, K0, K0, K1);
-               UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+               uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+               uasm_i_dsrl(&p, K0, K0, 12 + 1);
+               uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
+               uasm_i_or(&p, K0, K0, K1);
                uasm_il_bnez(&p, &r, K0, label_leave);
                /* No need for uasm_i_nop */
        }
@@ -1312,10 +1317,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
        memset(relocs, 0, sizeof(relocs));
 
        if (bcm1250_m3_war()) {
-               UASM_i_MFC0(&p, K0, C0_BADVADDR);
-               UASM_i_MFC0(&p, K1, C0_ENTRYHI);
+               unsigned int segbits = 44;
+
+               uasm_i_dmfc0(&p, K0, C0_BADVADDR);
+               uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
                uasm_i_xor(&p, K0, K0, K1);
-               UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+               uasm_i_dsrl32(&p, K1, K0, 62 - 32);
+               uasm_i_dsrl(&p, K0, K0, 12 + 1);
+               uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
+               uasm_i_or(&p, K0, K0, K1);
                uasm_il_bnez(&p, &r, K0, label_leave);
                /* No need for uasm_i_nop */
        }
index 1581e98..611d564 100644 (file)
@@ -31,7 +31,8 @@ enum fields {
        BIMM = 0x040,
        JIMM = 0x080,
        FUNC = 0x100,
-       SET = 0x200
+       SET = 0x200,
+       SCIMM = 0x400
 };
 
 #define OP_MASK                0x3f
@@ -52,6 +53,8 @@ enum fields {
 #define FUNC_SH                0
 #define SET_MASK       0x7
 #define SET_SH         0
+#define SCIMM_MASK     0xfffff
+#define SCIMM_SH       6
 
 enum opcode {
        insn_invalid,
@@ -61,10 +64,10 @@ enum opcode {
        insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
        insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
        insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
-       insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
+       insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
        insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
        insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
-       insn_dins
+       insn_dins, insn_syscall
 };
 
 struct insn {
@@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = {
        { insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_mfc0,  M(cop0_op, mfc_op, 0, 0, 0, 0),  RT | RD | SET},
        { insn_mtc0,  M(cop0_op, mtc_op, 0, 0, 0, 0),  RT | RD | SET},
+       { insn_or,  M(spec_op, 0, 0, 0, 0, or_op),  RS | RT | RD },
        { insn_ori,  M(ori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
        { insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
        { insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
@@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = {
        { insn_xor,  M(spec_op, 0, 0, 0, 0, xor_op),  RS | RT | RD },
        { insn_xori,  M(xori_op, 0, 0, 0, 0, 0),  RS | RT | UIMM },
        { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
+       { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
        { insn_invalid, 0, 0 }
 };
 
@@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg)
        return (arg >> 2) & JIMM_MASK;
 }
 
+static inline __cpuinit u32 build_scimm(u32 arg)
+{
+       if (arg & ~SCIMM_MASK)
+               printk(KERN_WARNING "Micro-assembler field overflow\n");
+
+       return (arg & SCIMM_MASK) << SCIMM_SH;
+}
+
 static inline __cpuinit u32 build_func(u32 arg)
 {
        if (arg & ~FUNC_MASK)
@@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
                op |= build_func(va_arg(ap, u32));
        if (ip->fields & SET)
                op |= build_set(va_arg(ap, u32));
+       if (ip->fields & SCIMM)
+               op |= build_scimm(va_arg(ap, u32));
        va_end(ap);
 
        **buf = op;
@@ -373,6 +388,7 @@ I_u2s3u1(_lw)
 I_u1u2u3(_mfc0)
 I_u1u2u3(_mtc0)
 I_u2u1u3(_ori)
+I_u3u1u2(_or)
 I_u2s3u1(_pref)
 I_0(_rfe)
 I_u2s3u1(_sc)
@@ -391,6 +407,7 @@ I_0(_tlbwr)
 I_u3u1u2(_xor)
 I_u2u1u3(_xori)
 I_u2u1msbu3(_dins);
+I_u1(_syscall);
 
 /* Handle labels. */
 void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
index 2bb4057..d657ee0 100644 (file)
@@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
 };
 
 #ifdef CONFIG_CS5536
+DEFINE_RAW_SPINLOCK(msr_lock);
+
 void _rdmsr(u32 msr, u32 *hi, u32 *lo)
 {
        struct pci_bus bus = {
                .number = PCI_BUS_CS5536
        };
        u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&msr_lock, flags);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
        loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
        loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+       raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_rdmsr);
 
@@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
                .number = PCI_BUS_CS5536
        };
        u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&msr_lock, flags);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
        loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
+       raw_spin_unlock_irqrestore(&msr_lock, flags);
 }
 EXPORT_SYMBOL(_wrmsr);
 #endif
index 0444da1..92da315 100644 (file)
@@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
        return ret;
 }
 
+int sb1250_m3_workaround_needed(void)
+{
+       switch (soc_type) {
+       case K_SYS_SOC_TYPE_BCM1250:
+       case K_SYS_SOC_TYPE_BCM1250_ALT:
+       case K_SYS_SOC_TYPE_BCM1250_ALT2:
+       case K_SYS_SOC_TYPE_BCM1125:
+       case K_SYS_SOC_TYPE_BCM1125H:
+               return soc_pass < K_SYS_REVISION_BCM1250_C0;
+
+       default:
+               return 0;
+       }
+}
+
 static int __init setup_bcm112x(void)
 {
        int ret = 0;
index 25da07f..604af29 100644 (file)
@@ -1004,7 +1004,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        struct kvm_vcpu *vcpu;
        ulong ga, ga_end;
        int is_dirty = 0;
-       int r, n;
+       int r;
+       unsigned long n;
 
        mutex_lock(&kvm->slots_lock);
 
@@ -1022,7 +1023,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                kvm_for_each_vcpu(n, vcpu, kvm)
                        kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
-               n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+               n = kvm_dirty_bitmap_bytes(memslot);
                memset(memslot->dirty_bitmap, 0, n);
        }
 
index 7ae71cc..bcd6884 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.33-rc2
-# Mon Jan  4 09:03:07 2010
+# Linux kernel version: 2.6.34-rc3
+# Fri Apr  9 09:57:10 2010
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -17,6 +17,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
 CONFIG_NO_IOMEM=y
 CONFIG_NO_DMA=y
 CONFIG_GENERIC_LOCKBREAK=y
@@ -62,15 +63,11 @@ CONFIG_TREE_RCU=y
 # CONFIG_RCU_TRACE is not set
 CONFIG_RCU_FANOUT=64
 # CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
 # CONFIG_TREE_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=17
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
@@ -79,6 +76,7 @@ CONFIG_CGROUP_NS=y
 # CONFIG_CPUSETS is not set
 # CONFIG_CGROUP_CPUACCT is not set
 # CONFIG_RESOURCE_COUNTERS is not set
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
@@ -93,6 +91,7 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_GZIP=y
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
 CONFIG_ANON_INODES=y
@@ -126,6 +125,7 @@ CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
 CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -134,6 +134,7 @@ CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES=y
 
 #
@@ -246,6 +247,7 @@ CONFIG_64BIT=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
+# CONFIG_SCHED_BOOK is not set
 CONFIG_COMPAT=y
 CONFIG_SYSVIPC_COMPAT=y
 CONFIG_AUDIT_ARCH=y
@@ -345,13 +347,13 @@ CONFIG_PM_SLEEP=y
 CONFIG_HIBERNATION=y
 CONFIG_PM_STD_PARTITION=""
 # CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
 CONFIG_NET=y
 
 #
 # Networking options
 #
 CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
 CONFIG_XFRM=y
 # CONFIG_XFRM_USER is not set
@@ -529,6 +531,7 @@ CONFIG_NET_SCH_FIFO=y
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_NET_TCPPROBE is not set
+# CONFIG_NET_DROP_MONITOR is not set
 CONFIG_CAN=m
 CONFIG_CAN_RAW=m
 CONFIG_CAN_BCM=m
@@ -605,6 +608,7 @@ CONFIG_MISC_DEVICES=y
 #
 # SCSI device support
 #
+CONFIG_SCSI_MOD=y
 # CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 # CONFIG_SCSI_DMA is not set
@@ -863,6 +867,7 @@ CONFIG_MISC_FILESYSTEMS=y
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_SQUASHFS is not set
 # CONFIG_VXFS_FS is not set
@@ -891,6 +896,7 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -952,6 +958,7 @@ CONFIG_DEBUG_MUTEXES=y
 # CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
@@ -973,12 +980,17 @@ CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_TRACING=y
 CONFIG_TRACING_SUPPORT=y
 CONFIG_FTRACE=y
 # CONFIG_FUNCTION_TRACER is not set
@@ -995,10 +1007,15 @@ CONFIG_BRANCH_PROFILE_NONE=y
 # CONFIG_KMEMTRACE is not set
 # CONFIG_WORKQUEUE_TRACER is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_KPROBE_EVENT=y
+# CONFIG_RING_BUFFER_BENCHMARK is not set
 # CONFIG_DYNAMIC_DEBUG is not set
 CONFIG_SAMPLES=y
+# CONFIG_SAMPLE_TRACEPOINTS is not set
+# CONFIG_SAMPLE_TRACE_EVENTS is not set
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
+# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
 
 #
 # Security options
@@ -1032,6 +1049,7 @@ CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
 CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_AUTHENC=m
@@ -1119,7 +1137,7 @@ CONFIG_CRYPTO_SHA512_S390=m
 # CONFIG_CRYPTO_DES_S390 is not set
 # CONFIG_CRYPTO_AES_S390 is not set
 CONFIG_S390_PRNG=m
-# CONFIG_BINARY_PRINTF is not set
+CONFIG_BINARY_PRINTF=y
 
 #
 # Library routines
@@ -1136,14 +1154,16 @@ CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_LZO_COMPRESS=m
-CONFIG_LZO_DECOMPRESS=m
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_DECOMPRESS_GZIP=y
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
 CONFIG_NLATTR=y
 CONFIG_HAVE_KVM=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
+# CONFIG_VHOST_NET is not set
 CONFIG_VIRTIO=y
 CONFIG_VIRTIO_RING=y
 CONFIG_VIRTIO_BALLOON=m
index 9b5b918..89a504c 100644 (file)
@@ -105,7 +105,7 @@ extern char empty_zero_page[PAGE_SIZE];
 #ifndef __ASSEMBLY__
 /*
  * The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc,
+ * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
  * which should be enough for any sane case.
  * By putting vmalloc at the top, we maximise the gap between physical
  * memory and vmalloc to catch misplaced memory accesses. As a side
@@ -120,8 +120,8 @@ extern unsigned long VMALLOC_START;
 #define VMALLOC_END    0x7e000000UL
 #define VMEM_MAP_END   0x80000000UL
 #else /* __s390x__ */
-#define VMALLOC_SIZE   (1UL << 30)
-#define VMALLOC_END    0x3e040000000UL
+#define VMALLOC_SIZE   (128UL << 30)
+#define VMALLOC_END    0x3e000000000UL
 #define VMEM_MAP_END   0x40000000000UL
 #endif /* __s390x__ */
 
index 31d618a..2d92c2c 100644 (file)
@@ -82,7 +82,8 @@ asm(
        "       lm      6,15,24(15)\n"
 #endif
        "       br      14\n"
-       "       .size   savesys_ipl_nss, .-savesys_ipl_nss\n");
+       "       .size   savesys_ipl_nss, .-savesys_ipl_nss\n"
+       "       .previous\n");
 
 static __initdata char upper_command_line[COMMAND_LINE_SIZE];
 
index 4348f9b..6af7045 100644 (file)
@@ -964,7 +964,7 @@ cleanup_critical:
        clc     4(4,%r12),BASED(cleanup_table_io_work_loop)
        bl      BASED(0f)
        clc     4(4,%r12),BASED(cleanup_table_io_work_loop+4)
-       bl      BASED(cleanup_io_return)
+       bl      BASED(cleanup_io_work_loop)
 0:
        br      %r14
 
@@ -1039,6 +1039,12 @@ cleanup_sysc_leave_insn:
 
 cleanup_io_return:
        mvc     __LC_RETURN_PSW(4),0(%r12)
+       mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return)
+       la      %r12,__LC_RETURN_PSW
+       br      %r14
+
+cleanup_io_work_loop:
+       mvc     __LC_RETURN_PSW(4),0(%r12)
        mvc     __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
        la      %r12,__LC_RETURN_PSW
        br      %r14
index 29fd0f1..52106d5 100644 (file)
@@ -946,7 +946,7 @@ cleanup_critical:
        clc     8(8,%r12),BASED(cleanup_table_io_work_loop)
        jl      0f
        clc     8(8,%r12),BASED(cleanup_table_io_work_loop+8)
-       jl      cleanup_io_return
+       jl      cleanup_io_work_loop
 0:
        br      %r14
 
@@ -1021,6 +1021,12 @@ cleanup_sysc_leave_insn:
 
 cleanup_io_return:
        mvc     __LC_RETURN_PSW(8),0(%r12)
+       mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return)
+       la      %r12,__LC_RETURN_PSW
+       br      %r14
+
+cleanup_io_work_loop:
+       mvc     __LC_RETURN_PSW(8),0(%r12)
        mvc     __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
        la      %r12,__LC_RETURN_PSW
        br      %r14
index 14ef6f0..247b4c2 100644 (file)
@@ -165,10 +165,11 @@ static void tl_to_cores(struct tl_info *info)
                default:
                        clear_cores();
                        machine_has_topology = 0;
-                       return;
+                       goto out;
                }
                tle = next_tle(tle);
        }
+out:
        spin_unlock_irq(&topology_lock);
 }
 
index 8ea3144..90165e7 100644 (file)
@@ -71,12 +71,8 @@ static pte_t __ref *vmem_pte_alloc(void)
                pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t));
        if (!pte)
                return NULL;
-       if (MACHINE_HAS_HPAGE)
-               clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO,
-                           PTRS_PER_PTE * sizeof(pte_t));
-       else
-               clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
-                           PTRS_PER_PTE * sizeof(pte_t));
+       clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY,
+                   PTRS_PER_PTE * sizeof(pte_t));
        return pte;
 }
 
@@ -117,8 +113,7 @@ static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
                if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
                    (address + HPAGE_SIZE <= start + size) &&
                    (address >= HPAGE_SIZE)) {
-                       pte_val(pte) |= _SEGMENT_ENTRY_LARGE |
-                                       _SEGMENT_ENTRY_CO;
+                       pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
                        pmd_val(*pm_dir) = pte_val(pte);
                        address += HPAGE_SIZE - PAGE_SIZE;
                        continue;
index 6db5136..9908d47 100644 (file)
@@ -37,6 +37,9 @@ config SPARC64
        def_bool 64BIT
        select ARCH_SUPPORTS_MSI
        select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_GRAPH_TRACER
+       select HAVE_FUNCTION_GRAPH_FP_TEST
+       select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_KRETPROBES
        select HAVE_KPROBES
        select HAVE_LMB
index 9d3c889..1b4a831 100644 (file)
@@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
        bool "D-cache flush debugging"
        depends on SPARC64 && DEBUG_KERNEL
 
-config STACK_DEBUG
-       bool "Stack Overflow Detection Support"
-
 config MCOUNT
        bool
        depends on SPARC64
-       depends on STACK_DEBUG || FUNCTION_TRACER
+       depends on FUNCTION_TRACER
        default y
 
 config FRAME_POINTER
index 926397d..050ef35 100644 (file)
@@ -17,7 +17,7 @@ typedef struct {
        unsigned int    __nmi_count;
        unsigned long   clock_tick;     /* %tick's per second */
        unsigned long   __pad;
-       unsigned int    __pad1;
+       unsigned int    irq0_irqs;
        unsigned int    __pad2;
 
        /* Dcache line 2, rarely used */
index 8b49bf9..bfa1ea4 100644 (file)
@@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void)
  */
 static inline unsigned long __raw_local_irq_save(void)
 {
-       unsigned long flags = __raw_local_save_flags();
-
-       raw_local_irq_disable();
+       unsigned long flags, tmp;
+
+       /* Disable interrupts to PIL_NORMAL_MAX unless we already
+        * are using PIL_NMI, in which case PIL_NMI is retained.
+        *
+        * The only values we ever program into the %pil are 0,
+        * PIL_NORMAL_MAX and PIL_NMI.
+        *
+        * Since PIL_NMI is the largest %pil value and all bits are
+        * set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
+        * actually is.
+        */
+       __asm__ __volatile__(
+               "rdpr   %%pil, %0\n\t"
+               "or     %0, %2, %1\n\t"
+               "wrpr   %1, 0x0, %%pil"
+               : "=r" (flags), "=r" (tmp)
+               : "i" (PIL_NORMAL_MAX)
+               : "memory"
+       );
 
        return flags;
 }
index 9e2d944..4827a3a 100644 (file)
@@ -111,7 +111,7 @@ struct thread_info {
 #define THREAD_SHIFT PAGE_SHIFT
 #endif /* PAGE_SHIFT == 13 */
 
-#define PREEMPT_ACTIVE         0x4000000
+#define PREEMPT_ACTIVE         0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
index c631614..0c2dc1f 100644 (file)
@@ -13,6 +13,14 @@ extra-y     += init_task.o
 CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
 extra-y              += vmlinux.lds
 
+ifdef CONFIG_FUNCTION_TRACER
+# Do not profile debug and lowlevel utilities
+CFLAGS_REMOVE_ftrace.o := -pg
+CFLAGS_REMOVE_time_$(BITS).o := -pg
+CFLAGS_REMOVE_perf_event.o := -pg
+CFLAGS_REMOVE_pcr.o := -pg
+endif
+
 obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
 obj-$(CONFIG_SPARC32)   += etrap_32.o
 obj-$(CONFIG_SPARC32)   += rtrap_32.o
@@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB)        += kgdb_$(BITS).o
 
 
 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
-CFLAGS_REMOVE_ftrace.o := -pg
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 
 obj-$(CONFIG_EARLYFB) += btext.o
 obj-$(CONFIG_STACKTRACE)     += stacktrace.o
index 9103a56..03ab022 100644 (file)
@@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000;
 
 static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
 {
-       static u32 call;
+       u32 call;
        s32 off;
 
        off = ((s32)addr - (s32)ip);
@@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
        return 0;
 }
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+extern void ftrace_graph_call(void);
+
+int ftrace_enable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
+       return ftrace_modify_code(ip, old, new);
+}
+
+int ftrace_disable_ftrace_graph_caller(void)
+{
+       unsigned long ip = (unsigned long)(&ftrace_graph_call);
+       u32 old, new;
+
+       old = *(u32 *) &ftrace_graph_call;
+       new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
+
+       return ftrace_modify_code(ip, old, new);
+}
+
+#endif /* !CONFIG_DYNAMIC_FTRACE */
+
+/*
+ * Hook the return address and push it in the stack of return addrs
+ * in current thread info.
+ */
+unsigned long prepare_ftrace_return(unsigned long parent,
+                                   unsigned long self_addr,
+                                   unsigned long frame_pointer)
+{
+       unsigned long return_hooker = (unsigned long) &return_to_handler;
+       struct ftrace_graph_ent trace;
+
+       if (unlikely(atomic_read(&current->tracing_graph_pause)))
+               return parent + 8UL;
+
+       if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
+                                    frame_pointer) == -EBUSY)
+               return parent + 8UL;
+
+       trace.func = self_addr;
+
+       /* Only trace if the calling function expects to */
+       if (!ftrace_graph_entry(&trace)) {
+               current->curr_ret_stack--;
+               return parent + 8UL;
+       }
+
+       return return_hooker;
+}
+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
index e1cbdb9..830d70a 100644 (file)
@@ -20,7 +20,9 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/ftrace.h>
 #include <linux/irq.h>
+#include <linux/kmemleak.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -45,6 +47,7 @@
 
 #include "entry.h"
 #include "cpumap.h"
+#include "kstack.h"
 
 #define NUM_IVECS      (IMAP_INR + 1)
 
@@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
        bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
        if (unlikely(!bucket))
                return 0;
+
+       /* The only reference we store to the IRQ bucket is
+        * by physical address which kmemleak can't see, tell
+        * it that this object explicitly is not a leak and
+        * should be scanned.
+        */
+       kmemleak_not_leak(bucket);
+
        __flush_dcache_range((unsigned long) bucket,
                             ((unsigned long) bucket +
                              sizeof(struct ino_bucket)));
@@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq)
 void *hardirq_stack[NR_CPUS];
 void *softirq_stack[NR_CPUS];
 
-static __attribute__((always_inline)) void *set_hardirq_stack(void)
-{
-       void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
-
-       __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
-       if (orig_sp < sp ||
-           orig_sp > (sp + THREAD_SIZE)) {
-               sp += THREAD_SIZE - 192 - STACK_BIAS;
-               __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
-       }
-
-       return orig_sp;
-}
-static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
-{
-       __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
-}
-
-void handler_irq(int irq, struct pt_regs *regs)
+void __irq_entry handler_irq(int irq, struct pt_regs *regs)
 {
        unsigned long pstate, bucket_pa;
        struct pt_regs *old_regs;
index f5a0fd4..0a2bd0f 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <linux/kgdb.h>
 #include <linux/kdebug.h>
+#include <linux/ftrace.h>
 
 #include <asm/kdebug.h>
 #include <asm/ptrace.h>
@@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 }
 
 #ifdef CONFIG_SMP
-void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs)
 {
        unsigned long flags;
 
index 5247283..53dfb92 100644 (file)
@@ -61,4 +61,23 @@ check_magic:
 
 }
 
+static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
+{
+       void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
+
+       __asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
+       if (orig_sp < sp ||
+           orig_sp > (sp + THREAD_SIZE)) {
+               sp += THREAD_SIZE - 192 - STACK_BIAS;
+               __asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
+       }
+
+       return orig_sp;
+}
+
+static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
+{
+       __asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
+}
+
 #endif /* _KSTACK_H */
index b287b62..a4bd7ba 100644 (file)
@@ -23,6 +23,8 @@
 #include <asm/ptrace.h>
 #include <asm/pcr.h>
 
+#include "kstack.h"
+
 /* We don't have a real NMI on sparc64, but we can fake one
  * up using profiling counter overflow interrupts and interrupt
  * levels.
@@ -92,7 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
 notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 {
        unsigned int sum, touched = 0;
-       int cpu = smp_processor_id();
+       void *orig_sp;
 
        clear_softint(1 << irq);
 
@@ -100,13 +102,15 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
 
        nmi_enter();
 
+       orig_sp = set_hardirq_stack();
+
        if (notify_die(DIE_NMI, "nmi", regs, 0,
                       pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
                touched = 1;
        else
                pcr_ops->write(PCR_PIC_PRIV);
 
-       sum = kstat_irqs_cpu(0, cpu);
+       sum = local_cpu_data().irq0_irqs;
        if (__get_cpu_var(nmi_touch)) {
                __get_cpu_var(nmi_touch) = 0;
                touched = 1;
@@ -125,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
                pcr_ops->write(pcr_enable);
        }
 
+       restore_hardirq_stack(orig_sp);
+
        nmi_exit();
 }
 
index b775658..8a00058 100644 (file)
@@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm)
                struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
 
                if (!rp) {
-                       prom_printf("Cannot allocate IOMMU resource.\n");
-                       prom_halt();
+                       pr_info("%s: Cannot allocate IOMMU resource.\n",
+                               pbm->name);
+                       return;
                }
                rp->name = "IOMMU";
                rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
                rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
                rp->flags = IORESOURCE_BUSY;
-               request_resource(&pbm->mem_space, rp);
+               if (request_resource(&pbm->mem_space, rp)) {
+                       pr_info("%s: Unable to request IOMMU resource.\n",
+                               pbm->name);
+                       kfree(rp);
+               }
        }
 }
 
index 2d94e7a..c4a6a50 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/irq.h>
 
 #include <linux/perf_event.h>
+#include <linux/ftrace.h>
 
 #include <asm/pil.h>
 #include <asm/pcr.h>
@@ -34,7 +35,7 @@ unsigned int picl_shift;
  * Therefore in such situations we defer the work by signalling
  * a lower level cpu IRQ.
  */
-void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
+void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
 
index 83f1873..090b9e9 100644 (file)
@@ -130,7 +130,17 @@ rtrap_xcall:
                 nop
                call                    trace_hardirqs_on
                 nop
-               wrpr                    %l4, %pil
+               /* Do not actually set the %pil here.  We will do that
+                * below after we clear PSTATE_IE in the %pstate register.
+                * If we re-enable interrupts here, we can recurse down
+                * the hardirq stack potentially endlessly, causing a
+                * stack overflow.
+                *
+                * It is tempting to put this test and trace_hardirqs_on
+                * call at the 'rt_continue' label, but that will not work
+                * as that path hits unconditionally and we do not want to
+                * execute this in NMI return paths, for example.
+                */
 #endif
 rtrap_no_irq_enable:
                andcc                   %l1, TSTATE_PRIV, %l3
index 4c53345..b6a2b8f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/profile.h>
 #include <linux/bootmem.h>
 #include <linux/vmalloc.h>
+#include <linux/ftrace.h>
 #include <linux/cpu.h>
 #include <linux/slab.h>
 
@@ -823,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu)
                      &cpumask_of_cpu(cpu));
 }
 
-void smp_call_function_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
        generic_smp_call_function_interrupt();
 }
 
-void smp_call_function_single_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
        generic_smp_call_function_single_interrupt();
@@ -965,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
        put_cpu();
 }
 
-void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
 {
        struct mm_struct *mm;
        unsigned long flags;
@@ -1149,7 +1150,7 @@ void smp_release(void)
  */
 extern void prom_world(int);
 
-void smp_penguin_jailcell(int irq, struct pt_regs *regs)
+void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 
@@ -1365,7 +1366,7 @@ void smp_send_reschedule(int cpu)
                      &cpumask_of_cpu(cpu));
 }
 
-void smp_receive_signal_client(int irq, struct pt_regs *regs)
+void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
        clear_softint(1 << irq);
 }
index 67e1651..c7bbe6c 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/clocksource.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/ftrace.h>
 
 #include <asm/oplib.h>
 #include <asm/timer.h>
@@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = {
 };
 static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
 
-void timer_interrupt(int irq, struct pt_regs *regs)
+void __irq_entry timer_interrupt(int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs = set_irq_regs(regs);
        unsigned long tick_mask = tick_ops->softint_mask;
@@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs)
 
        irq_enter();
 
+       local_cpu_data().irq0_irqs++;
        kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
 
        if (unlikely(!evt->event_handler)) {
index 837dfc2..9da57f0 100644 (file)
@@ -2203,27 +2203,6 @@ void dump_stack(void)
 
 EXPORT_SYMBOL(dump_stack);
 
-static inline int is_kernel_stack(struct task_struct *task,
-                                 struct reg_window *rw)
-{
-       unsigned long rw_addr = (unsigned long) rw;
-       unsigned long thread_base, thread_end;
-
-       if (rw_addr < PAGE_OFFSET) {
-               if (task != &init_task)
-                       return 0;
-       }
-
-       thread_base = (unsigned long) task_stack_page(task);
-       thread_end = thread_base + sizeof(union thread_union);
-       if (rw_addr >= thread_base &&
-           rw_addr < thread_end &&
-           !(rw_addr & 0x7UL))
-               return 1;
-
-       return 0;
-}
-
 static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
 {
        unsigned long fp = rw->ins[6];
@@ -2252,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
        show_regs(regs);
        add_taint(TAINT_DIE);
        if (regs->tstate & TSTATE_PRIV) {
+               struct thread_info *tp = current_thread_info();
                struct reg_window *rw = (struct reg_window *)
                        (regs->u_regs[UREG_FP] + STACK_BIAS);
 
@@ -2259,8 +2239,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
                 * find some badly aligned kernel stack.
                 */
                while (rw &&
-                      count++ < 30&&
-                      is_kernel_stack(current, rw)) {
+                      count++ < 30 &&
+                      kstack_valid(tp, (unsigned long) rw)) {
                        printk("Caller[%016lx]: %pS\n", rw->ins[7],
                               (void *) rw->ins[7]);
 
index ebce430..c752c4c 100644 (file)
@@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn)
 }
 
 /* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */
-static inline int decode_access_size(unsigned int insn)
+static inline int decode_access_size(struct pt_regs *regs, unsigned int insn)
 {
        unsigned int tmp;
 
@@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn)
                return 2;
        else {
                printk("Impossible unaligned trap. insn=%08x\n", insn);
-               die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs);
+               die_if_kernel("Byte sized unaligned access?!?!", regs);
 
                /* GCC should never warn that control reaches the end
                 * of this function without returning a value because
@@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs)
 asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
 {
        enum direction dir = decode_direction(insn);
-       int size = decode_access_size(insn);
+       int size = decode_access_size(regs, insn);
        int orig_asi, asi;
 
        current_thread_info()->kern_una_regs = regs;
index 4e59925..0c1e678 100644 (file)
@@ -46,11 +46,16 @@ SECTIONS
                SCHED_TEXT
                LOCK_TEXT
                KPROBES_TEXT
+               IRQENTRY_TEXT
                *(.gnu.warning)
        } = 0
        _etext = .;
 
        RO_DATA(PAGE_SIZE)
+
+       /* Start of data section */
+       _sdata = .;
+
        .data1 : {
                *(.data1)
        }
index 24b8b12..3ad6cbd 100644 (file)
@@ -7,26 +7,11 @@
 
 #include <linux/linkage.h>
 
-#include <asm/ptrace.h>
-#include <asm/thread_info.h>
-
 /*
  * This is the main variant and is called by C code.  GCC's -pg option
  * automatically instruments every C function with a call to this.
  */
 
-#ifdef CONFIG_STACK_DEBUG
-
-#define OVSTACKSIZE    4096            /* lets hope this is enough */
-
-       .data
-       .align          8
-panicstring:
-       .asciz          "Stack overflow\n"
-       .align          8
-ovstack:
-       .skip           OVSTACKSIZE
-#endif
        .text
        .align          32
        .globl          _mcount
@@ -35,84 +20,48 @@ ovstack:
        .type           mcount,#function
 _mcount:
 mcount:
-#ifdef CONFIG_STACK_DEBUG
-       /*
-        * Check whether %sp is dangerously low.
-        */
-       ldub            [%g6 + TI_FPDEPTH], %g1
-       srl             %g1, 1, %g3
-       add             %g3, 1, %g3
-       sllx            %g3, 8, %g3                     ! each fpregs frame is 256b
-       add             %g3, 192, %g3
-       add             %g6, %g3, %g3                   ! where does task_struct+frame end?
-       sub             %g3, STACK_BIAS, %g3
-       cmp             %sp, %g3
-       bg,pt           %xcc, 1f
-        nop
-       lduh            [%g6 + TI_CPU], %g1
-       sethi           %hi(hardirq_stack), %g3
-       or              %g3, %lo(hardirq_stack), %g3
-       sllx            %g1, 3, %g1
-       ldx             [%g3 + %g1], %g7
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       bleu,pt         %xcc, 2f
-        sethi          %hi(THREAD_SIZE), %g3
-       add             %g7, %g3, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 1f
-2:      sethi          %hi(softirq_stack), %g3
-       or              %g3, %lo(softirq_stack), %g3
-       ldx             [%g3 + %g1], %g7
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       bleu,pt         %xcc, 3f
-        sethi          %hi(THREAD_SIZE), %g3
-       add             %g7, %g3, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 1f
-        nop
-       /* If we are already on ovstack, don't hop onto it
-        * again, we are already trying to output the stack overflow
-        * message.
-        */
-3:     sethi           %hi(ovstack), %g7               ! cant move to panic stack fast enough
-        or             %g7, %lo(ovstack), %g7
-       add             %g7, OVSTACKSIZE, %g3
-       sub             %g3, STACK_BIAS + 192, %g3
-       sub             %g7, STACK_BIAS, %g7
-       cmp             %sp, %g7
-       blu,pn          %xcc, 2f
-        cmp            %sp, %g3
-       bleu,pn         %xcc, 1f
-        nop
-2:     mov             %g3, %sp
-       sethi           %hi(panicstring), %g3
-       call            prom_printf
-        or             %g3, %lo(panicstring), %o0
-       call            prom_halt
-        nop
-1:
-#endif
 #ifdef CONFIG_FUNCTION_TRACER
 #ifdef CONFIG_DYNAMIC_FTRACE
-       mov             %o7, %o0
-       .globl          mcount_call
-mcount_call:
-       call            ftrace_stub
-        mov            %o0, %o7
+       /* Do nothing, the retl/nop below is all we need.  */
 #else
-       sethi           %hi(ftrace_trace_function), %g1
+       sethi           %hi(function_trace_stop), %g1
+       lduw            [%g1 + %lo(function_trace_stop)], %g2
+       brnz,pn         %g2, 2f
+        sethi          %hi(ftrace_trace_function), %g1
        sethi           %hi(ftrace_stub), %g2
        ldx             [%g1 + %lo(ftrace_trace_function)], %g1
        or              %g2, %lo(ftrace_stub), %g2
        cmp             %g1, %g2
        be,pn           %icc, 1f
-        mov            %i7, %o1
-       jmpl            %g1, %g0
-        mov            %o7, %o0
+        mov            %i7, %g3
+       save            %sp, -176, %sp
+       mov             %g3, %o1
+       jmpl            %g1, %o7
+        mov            %i7, %o0
+       ret
+        restore
        /* not reached */
 1:
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       sethi           %hi(ftrace_graph_return), %g1
+       ldx             [%g1 + %lo(ftrace_graph_return)], %g3
+       cmp             %g2, %g3
+       bne,pn          %xcc, 5f
+        sethi          %hi(ftrace_graph_entry_stub), %g2
+       sethi           %hi(ftrace_graph_entry), %g1
+       or              %g2, %lo(ftrace_graph_entry_stub), %g2
+       ldx             [%g1 + %lo(ftrace_graph_entry)], %g1
+       cmp             %g1, %g2
+       be,pt           %xcc, 2f
+        nop
+5:     mov             %i7, %g2
+       mov             %fp, %g3
+       save            %sp, -176, %sp
+       mov             %g2, %l0
+       ba,pt           %xcc, ftrace_graph_caller
+        mov            %g3, %l1
+#endif
+2:
 #endif
 #endif
        retl
@@ -131,14 +80,50 @@ ftrace_stub:
        .globl          ftrace_caller
        .type           ftrace_caller,#function
 ftrace_caller:
-       mov             %i7, %o1
-       mov             %o7, %o0
+       sethi           %hi(function_trace_stop), %g1
+       mov             %i7, %g2
+       lduw            [%g1 + %lo(function_trace_stop)], %g1
+       brnz,pn         %g1, ftrace_stub
+        mov            %fp, %g3
+       save            %sp, -176, %sp
+       mov             %g2, %o1
+       mov             %g2, %l0
+       mov             %g3, %l1
        .globl          ftrace_call
 ftrace_call:
        call            ftrace_stub
-        mov            %o0, %o7
-       retl
+        mov            %i7, %o0
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       .globl          ftrace_graph_call
+ftrace_graph_call:
+       call            ftrace_stub
         nop
+#endif
+       ret
+        restore
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+       .size           ftrace_graph_call,.-ftrace_graph_call
+#endif
+       .size           ftrace_call,.-ftrace_call
        .size           ftrace_caller,.-ftrace_caller
 #endif
 #endif
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(ftrace_graph_caller)
+       mov             %l0, %o0
+       mov             %i7, %o1
+       call            prepare_ftrace_return
+        mov            %l1, %o2
+       ret
+        restore        %o0, -8, %i7
+END(ftrace_graph_caller)
+
+ENTRY(return_to_handler)
+       save            %sp, -176, %sp
+       call            ftrace_return_to_handler
+        mov            %fp, %o0
+       jmpl            %o0 + 8, %g0
+        restore
+END(return_to_handler)
+#endif
index 59b4556..e790bc1 100644 (file)
@@ -626,7 +626,7 @@ ia32_sys_call_table:
        .quad stub32_sigreturn
        .quad stub32_clone              /* 120 */
        .quad sys_setdomainname
-       .quad sys_uname
+       .quad sys_newuname
        .quad sys_modify_ldt
        .quad compat_sys_adjtimex
        .quad sys32_mprotect            /* 125 */
index ba19ad4..86a0ff0 100644 (file)
@@ -21,6 +21,7 @@
 #define _ASM_X86_AMD_IOMMU_TYPES_H
 
 #include <linux/types.h>
+#include <linux/mutex.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
 
 /* constants to configure the command buffer */
 #define CMD_BUFFER_SIZE    8192
+#define CMD_BUFFER_UNINITIALIZED 1
 #define CMD_BUFFER_ENTRIES 512
 #define MMIO_CMD_SIZE_SHIFT 56
 #define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT)
@@ -237,6 +239,7 @@ struct protection_domain {
        struct list_head list;  /* for list of all protection domains */
        struct list_head dev_list; /* List of all devices in this domain */
        spinlock_t lock;        /* mostly used to lock the page table*/
+       struct mutex api_lock;  /* protect page tables in the iommu-api path */
        u16 id;                 /* the domain id written to the device table */
        int mode;               /* paging mode (0-6 levels) */
        u64 *pt_root;           /* page table root pointer */
index ba0eed8..b60f292 100644 (file)
 
 #ifndef __ASSEMBLY__
 #include <asm/hw_irq.h>
-#include <asm/kvm_para.h>
 
 /*G:030
  * But first, how does our Guest contact the Host to ask for privileged
  * operations?  There are two ways: the direct way is to make a "hypercall",
  * to make requests of the Host Itself.
  *
- * We use the KVM hypercall mechanism, though completely different hypercall
- * numbers. Seventeen hypercalls are available: the hypercall number is put in
- * the %eax register, and the arguments (when required) are placed in %ebx,
- * %ecx, %edx and %esi.  If a return value makes sense, it's returned in %eax.
+ * Our hypercall mechanism uses the highest unused trap code (traps 32 and
+ * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * available: the hypercall number is put in the %eax register, and the
+ * arguments (when required) are placed in %ebx, %ecx, %edx and %esi.
+ * If a return value makes sense, it's returned in %eax.
  *
  * Grossly invalid calls result in Sudden Death at the hands of the vengeful
  * Host, rather than returning failure.  This reflects Winston Churchill's
  * definition of a gentleman: "someone who is only rude intentionally".
-:*/
+ */
+static inline unsigned long
+hcall(unsigned long call,
+      unsigned long arg1, unsigned long arg2, unsigned long arg3,
+      unsigned long arg4)
+{
+       /* "int" is the Intel instruction to trigger a trap. */
+       asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
+                    /* The call in %eax (aka "a") might be overwritten */
+                    : "=a"(call)
+                      /* The arguments are in %eax, %ebx, %ecx, %edx & %esi */
+                    : "a"(call), "b"(arg1), "c"(arg2), "d"(arg3), "S"(arg4)
+                      /* "memory" means this might write somewhere in memory.
+                       * This isn't true for all calls, but it's safe to tell
+                       * gcc that it might happen so it doesn't get clever. */
+                    : "memory");
+       return call;
+}
 
 /* Can't use our min() macro here: needs to be a constant */
 #define LGUEST_IRQS (NR_IRQS < 32 ? NR_IRQS: 32)
index f3dadb5..f854d89 100644 (file)
@@ -118,7 +118,7 @@ static bool check_device(struct device *dev)
                return false;
 
        /* No device or no PCI device */
-       if (!dev || dev->bus != &pci_bus_type)
+       if (dev->bus != &pci_bus_type)
                return false;
 
        devid = get_device_id(dev);
@@ -392,6 +392,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
        u32 tail, head;
        u8 *target;
 
+       WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);
        tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
        target = iommu->cmd_buf + tail;
        memcpy_toio(target, cmd, sizeof(*cmd));
@@ -2186,7 +2187,7 @@ static void prealloc_protection_domains(void)
        struct dma_ops_domain *dma_dom;
        u16 devid;
 
-       while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
+       for_each_pci_dev(dev) {
 
                /* Do we handle this device? */
                if (!check_device(&dev->dev))
@@ -2298,7 +2299,7 @@ static void cleanup_domain(struct protection_domain *domain)
        list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
                struct device *dev = dev_data->dev;
 
-               do_detach(dev);
+               __detach_device(dev);
                atomic_set(&dev_data->bind, 0);
        }
 
@@ -2327,6 +2328,7 @@ static struct protection_domain *protection_domain_alloc(void)
                return NULL;
 
        spin_lock_init(&domain->lock);
+       mutex_init(&domain->api_lock);
        domain->id = domain_id_alloc();
        if (!domain->id)
                goto out_err;
@@ -2379,9 +2381,7 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom)
 
        free_pagetable(domain);
 
-       domain_id_free(domain->id);
-
-       kfree(domain);
+       protection_domain_free(domain);
 
        dom->priv = NULL;
 }
@@ -2456,6 +2456,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom,
        iova  &= PAGE_MASK;
        paddr &= PAGE_MASK;
 
+       mutex_lock(&domain->api_lock);
+
        for (i = 0; i < npages; ++i) {
                ret = iommu_map_page(domain, iova, paddr, prot, PM_MAP_4k);
                if (ret)
@@ -2465,6 +2467,8 @@ static int amd_iommu_map_range(struct iommu_domain *dom,
                paddr += PAGE_SIZE;
        }
 
+       mutex_unlock(&domain->api_lock);
+
        return 0;
 }
 
@@ -2477,12 +2481,16 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom,
 
        iova  &= PAGE_MASK;
 
+       mutex_lock(&domain->api_lock);
+
        for (i = 0; i < npages; ++i) {
                iommu_unmap_page(domain, iova, PM_MAP_4k);
                iova  += PAGE_SIZE;
        }
 
        iommu_flush_tlb_pde(domain);
+
+       mutex_unlock(&domain->api_lock);
 }
 
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
index 42f5350..6360abf 100644 (file)
@@ -138,9 +138,9 @@ int amd_iommus_present;
 bool amd_iommu_np_cache __read_mostly;
 
 /*
- * Set to true if ACPI table parsing and hardware intialization went properly
+ * The ACPI table parsing functions set this variable on an error
  */
-static bool amd_iommu_initialized;
+static int __initdata amd_iommu_init_err;
 
 /*
  * List of protection domains - used during resume
@@ -391,9 +391,11 @@ static int __init find_last_devid_acpi(struct acpi_table_header *table)
         */
        for (i = 0; i < table->length; ++i)
                checksum += p[i];
-       if (checksum != 0)
+       if (checksum != 0) {
                /* ACPI table corrupt */
-               return -ENODEV;
+               amd_iommu_init_err = -ENODEV;
+               return 0;
+       }
 
        p += IVRS_HEADER_LENGTH;
 
@@ -436,7 +438,7 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
        if (cmd_buf == NULL)
                return NULL;
 
-       iommu->cmd_buf_size = CMD_BUFFER_SIZE;
+       iommu->cmd_buf_size = CMD_BUFFER_SIZE | CMD_BUFFER_UNINITIALIZED;
 
        return cmd_buf;
 }
@@ -472,12 +474,13 @@ static void iommu_enable_command_buffer(struct amd_iommu *iommu)
                    &entry, sizeof(entry));
 
        amd_iommu_reset_cmd_buffer(iommu);
+       iommu->cmd_buf_size &= ~(CMD_BUFFER_UNINITIALIZED);
 }
 
 static void __init free_command_buffer(struct amd_iommu *iommu)
 {
        free_pages((unsigned long)iommu->cmd_buf,
-                  get_order(iommu->cmd_buf_size));
+                  get_order(iommu->cmd_buf_size & ~(CMD_BUFFER_UNINITIALIZED)));
 }
 
 /* allocates the memory where the IOMMU will log its events to */
@@ -920,11 +923,16 @@ static int __init init_iommu_all(struct acpi_table_header *table)
                                    h->mmio_phys);
 
                        iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL);
-                       if (iommu == NULL)
-                               return -ENOMEM;
+                       if (iommu == NULL) {
+                               amd_iommu_init_err = -ENOMEM;
+                               return 0;
+                       }
+
                        ret = init_iommu_one(iommu, h);
-                       if (ret)
-                               return ret;
+                       if (ret) {
+                               amd_iommu_init_err = ret;
+                               return 0;
+                       }
                        break;
                default:
                        break;
@@ -934,8 +942,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)
        }
        WARN_ON(p != end);
 
-       amd_iommu_initialized = true;
-
        return 0;
 }
 
@@ -1211,6 +1217,10 @@ static int __init amd_iommu_init(void)
        if (acpi_table_parse("IVRS", find_last_devid_acpi) != 0)
                return -ENODEV;
 
+       ret = amd_iommu_init_err;
+       if (ret)
+               goto out;
+
        dev_table_size     = tbl_size(DEV_TABLE_ENTRY_SIZE);
        alias_table_size   = tbl_size(ALIAS_TABLE_ENTRY_SIZE);
        rlookup_table_size = tbl_size(RLOOKUP_TABLE_ENTRY_SIZE);
@@ -1270,12 +1280,19 @@ static int __init amd_iommu_init(void)
        if (acpi_table_parse("IVRS", init_iommu_all) != 0)
                goto free;
 
-       if (!amd_iommu_initialized)
+       if (amd_iommu_init_err) {
+               ret = amd_iommu_init_err;
                goto free;
+       }
 
        if (acpi_table_parse("IVRS", init_memory_definitions) != 0)
                goto free;
 
+       if (amd_iommu_init_err) {
+               ret = amd_iommu_init_err;
+               goto free;
+       }
+
        ret = sysdev_class_register(&amd_iommu_sysdev_class);
        if (ret)
                goto free;
@@ -1288,6 +1305,8 @@ static int __init amd_iommu_init(void)
        if (ret)
                goto free;
 
+       enable_iommus();
+
        if (iommu_pass_through)
                ret = amd_iommu_init_passthrough();
        else
@@ -1300,8 +1319,6 @@ static int __init amd_iommu_init(void)
 
        amd_iommu_init_notifier();
 
-       enable_iommus();
-
        if (iommu_pass_through)
                goto out;
 
@@ -1315,6 +1332,7 @@ out:
        return ret;
 
 free:
+       disable_iommus();
 
        amd_iommu_uninit_devices();
 
index 3704997..b5d8b0b 100644 (file)
@@ -393,6 +393,7 @@ void __init gart_iommu_hole_init(void)
        for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
                int bus;
                int dev_base, dev_limit;
+               u32 ctl;
 
                bus = bus_dev_ranges[i].bus;
                dev_base = bus_dev_ranges[i].dev_base;
@@ -406,7 +407,19 @@ void __init gart_iommu_hole_init(void)
                        gart_iommu_aperture = 1;
                        x86_init.iommu.iommu_init = gart_iommu_init;
 
-                       aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
+                       ctl = read_pci_config(bus, slot, 3,
+                                             AMD64_GARTAPERTURECTL);
+
+                       /*
+                        * Before we do anything else disable the GART. It may
+                        * still be enabled if we boot into a crash-kernel here.
+                        * Reconfiguring the GART while it is enabled could have
+                        * unknown side-effects.
+                        */
+                       ctl &= ~GARTEN;
+                       write_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL, ctl);
+
+                       aper_order = (ctl >> 1) & 7;
                        aper_size = (32 * 1024 * 1024) << aper_order;
                        aper_base = read_pci_config(bus, slot, 3, AMD64_GARTAPERTUREBASE) & 0x7fff;
                        aper_base <<= 25;
index a4849c1..ebd4c51 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/cpu.h>
 #include <asm/reboot.h>
 #include <asm/virtext.h>
-#include <asm/x86_init.h>
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
@@ -103,10 +102,5 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 #ifdef CONFIG_HPET_TIMER
        hpet_disable();
 #endif
-
-#ifdef CONFIG_X86_64
-       x86_platform.iommu_shutdown();
-#endif
-
        crash_save_cpu(regs, safe_smp_processor_id());
 }
index e39e771..e1a93be 100644 (file)
@@ -14,6 +14,8 @@
 #define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
 #endif
 
+#include <linux/uaccess.h>
+
 extern void
 show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
                unsigned long *stack, unsigned long bp, char *log_lvl);
@@ -42,8 +44,10 @@ static inline unsigned long rewind_frame_pointer(int n)
        get_bp(frame);
 
 #ifdef CONFIG_FRAME_POINTER
-       while (n--)
-               frame = frame->next_frame;
+       while (n--) {
+               if (probe_kernel_address(&frame->next_frame, frame))
+                       break;
+       }
 #endif
 
        return (unsigned long)frame;
index 68cd24f..0f7f130 100644 (file)
@@ -565,6 +565,9 @@ static void enable_gart_translations(void)
 
                enable_gart_translation(dev, __pa(agp_gatt_table));
        }
+
+       /* Flush the GART-TLB to remove stale entries */
+       k8_flush_garts();
 }
 
 /*
index 48aeee8..19a8906 100644 (file)
@@ -1490,8 +1490,8 @@ static int mmu_zap_unsync_children(struct kvm *kvm,
                for_each_sp(pages, sp, parents, i) {
                        kvm_mmu_zap_page(kvm, sp);
                        mmu_pages_clear_parents(&parents);
+                       zapped++;
                }
-               zapped += pages.nr;
                kvm_mmu_pages_init(parent, &parents, &pages);
        }
 
@@ -1542,14 +1542,16 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
         */
 
        if (used_pages > kvm_nr_mmu_pages) {
-               while (used_pages > kvm_nr_mmu_pages) {
+               while (used_pages > kvm_nr_mmu_pages &&
+                       !list_empty(&kvm->arch.active_mmu_pages)) {
                        struct kvm_mmu_page *page;
 
                        page = container_of(kvm->arch.active_mmu_pages.prev,
                                            struct kvm_mmu_page, link);
-                       kvm_mmu_zap_page(kvm, page);
+                       used_pages -= kvm_mmu_zap_page(kvm, page);
                        used_pages--;
                }
+               kvm_nr_mmu_pages = used_pages;
                kvm->arch.n_free_mmu_pages = 0;
        }
        else
@@ -1596,7 +1598,8 @@ static void mmu_unshadow(struct kvm *kvm, gfn_t gfn)
                    && !sp->role.invalid) {
                        pgprintk("%s: zap %lx %x\n",
                                 __func__, gfn, sp->role.word);
-                       kvm_mmu_zap_page(kvm, sp);
+                       if (kvm_mmu_zap_page(kvm, sp))
+                               nn = bucket->first;
                }
        }
 }
index 445c594..2ba5820 100644 (file)
@@ -706,29 +706,28 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
        if (err)
                goto free_svm;
 
+       err = -ENOMEM;
        page = alloc_page(GFP_KERNEL);
-       if (!page) {
-               err = -ENOMEM;
+       if (!page)
                goto uninit;
-       }
 
-       err = -ENOMEM;
        msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
        if (!msrpm_pages)
-               goto uninit;
+               goto free_page1;
 
        nested_msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER);
        if (!nested_msrpm_pages)
-               goto uninit;
-
-       svm->msrpm = page_address(msrpm_pages);
-       svm_vcpu_init_msrpm(svm->msrpm);
+               goto free_page2;
 
        hsave_page = alloc_page(GFP_KERNEL);
        if (!hsave_page)
-               goto uninit;
+               goto free_page3;
+
        svm->nested.hsave = page_address(hsave_page);
 
+       svm->msrpm = page_address(msrpm_pages);
+       svm_vcpu_init_msrpm(svm->msrpm);
+
        svm->nested.msrpm = page_address(nested_msrpm_pages);
 
        svm->vmcb = page_address(page);
@@ -744,6 +743,12 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id)
 
        return &svm->vcpu;
 
+free_page3:
+       __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page2:
+       __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER);
+free_page1:
+       __free_page(page);
 uninit:
        kvm_vcpu_uninit(&svm->vcpu);
 free_svm:
index 686492e..bc933cf 100644 (file)
@@ -77,6 +77,8 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO);
 #define KVM_PMODE_VM_CR4_ALWAYS_ON (X86_CR4_PAE | X86_CR4_VMXE)
 #define KVM_RMODE_VM_CR4_ALWAYS_ON (X86_CR4_VME | X86_CR4_PAE | X86_CR4_VMXE)
 
+#define RMODE_GUEST_OWNED_EFLAGS_BITS (~(X86_EFLAGS_IOPL | X86_EFLAGS_VM))
+
 /*
  * These 2 parameters are used to config the controls for Pause-Loop Exiting:
  * ple_gap:    upper bound on the amount of time between two successive
@@ -131,7 +133,7 @@ struct vcpu_vmx {
        } host_state;
        struct {
                int vm86_active;
-               u8 save_iopl;
+               ulong save_rflags;
                struct kvm_save_segment {
                        u16 selector;
                        unsigned long base;
@@ -818,18 +820,23 @@ static void vmx_fpu_deactivate(struct kvm_vcpu *vcpu)
 
 static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
-       unsigned long rflags;
+       unsigned long rflags, save_rflags;
 
        rflags = vmcs_readl(GUEST_RFLAGS);
-       if (to_vmx(vcpu)->rmode.vm86_active)
-               rflags &= ~(unsigned long)(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
+       if (to_vmx(vcpu)->rmode.vm86_active) {
+               rflags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+               save_rflags = to_vmx(vcpu)->rmode.save_rflags;
+               rflags |= save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
+       }
        return rflags;
 }
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
-       if (to_vmx(vcpu)->rmode.vm86_active)
+       if (to_vmx(vcpu)->rmode.vm86_active) {
+               to_vmx(vcpu)->rmode.save_rflags = rflags;
                rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
+       }
        vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
@@ -1483,8 +1490,8 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
        vmcs_write32(GUEST_TR_AR_BYTES, vmx->rmode.tr.ar);
 
        flags = vmcs_readl(GUEST_RFLAGS);
-       flags &= ~(X86_EFLAGS_IOPL | X86_EFLAGS_VM);
-       flags |= (vmx->rmode.save_iopl << IOPL_SHIFT);
+       flags &= RMODE_GUEST_OWNED_EFLAGS_BITS;
+       flags |= vmx->rmode.save_rflags & ~RMODE_GUEST_OWNED_EFLAGS_BITS;
        vmcs_writel(GUEST_RFLAGS, flags);
 
        vmcs_writel(GUEST_CR4, (vmcs_readl(GUEST_CR4) & ~X86_CR4_VME) |
@@ -1557,8 +1564,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
        vmcs_write32(GUEST_TR_AR_BYTES, 0x008b);
 
        flags = vmcs_readl(GUEST_RFLAGS);
-       vmx->rmode.save_iopl
-               = (flags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
+       vmx->rmode.save_rflags = flags;
 
        flags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
 
index 24cd0ee..3c4ca98 100644 (file)
@@ -433,8 +433,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 
 #ifdef CONFIG_X86_64
        if (cr0 & 0xffffffff00000000UL) {
-               printk(KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n",
-                      cr0, kvm_read_cr0(vcpu));
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -443,14 +441,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
        cr0 &= ~CR0_RESERVED_BITS;
 
        if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD)) {
-               printk(KERN_DEBUG "set_cr0: #GP, CD == 0 && NW == 1\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE)) {
-               printk(KERN_DEBUG "set_cr0: #GP, set PG flag "
-                      "and a clear PE flag\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -461,15 +456,11 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
                        int cs_db, cs_l;
 
                        if (!is_pae(vcpu)) {
-                               printk(KERN_DEBUG "set_cr0: #GP, start paging "
-                                      "in long mode while PAE is disabled\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
                        kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
                        if (cs_l) {
-                               printk(KERN_DEBUG "set_cr0: #GP, start paging "
-                                      "in long mode while CS.L == 1\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
 
@@ -477,8 +468,6 @@ void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
                } else
 #endif
                if (is_pae(vcpu) && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
-                       printk(KERN_DEBUG "set_cr0: #GP, pdptrs "
-                              "reserved bits\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -505,28 +494,23 @@ void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
        unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
 
        if (cr4 & CR4_RESERVED_BITS) {
-               printk(KERN_DEBUG "set_cr4: #GP, reserved bits\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (is_long_mode(vcpu)) {
                if (!(cr4 & X86_CR4_PAE)) {
-                       printk(KERN_DEBUG "set_cr4: #GP, clearing PAE while "
-                              "in long mode\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
        } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
                   && ((cr4 ^ old_cr4) & pdptr_bits)
                   && !load_pdptrs(vcpu, vcpu->arch.cr3)) {
-               printk(KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (cr4 & X86_CR4_VMXE) {
-               printk(KERN_DEBUG "set_cr4: #GP, setting VMXE\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -547,21 +531,16 @@ void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 
        if (is_long_mode(vcpu)) {
                if (cr3 & CR3_L_MODE_RESERVED_BITS) {
-                       printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
        } else {
                if (is_pae(vcpu)) {
                        if (cr3 & CR3_PAE_RESERVED_BITS) {
-                               printk(KERN_DEBUG
-                                      "set_cr3: #GP, reserved bits\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
                        if (is_paging(vcpu) && !load_pdptrs(vcpu, cr3)) {
-                               printk(KERN_DEBUG "set_cr3: #GP, pdptrs "
-                                      "reserved bits\n");
                                kvm_inject_gp(vcpu, 0);
                                return;
                        }
@@ -593,7 +572,6 @@ EXPORT_SYMBOL_GPL(kvm_set_cr3);
 void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
 {
        if (cr8 & CR8_RESERVED_BITS) {
-               printk(KERN_DEBUG "set_cr8: #GP, reserved bits 0x%lx\n", cr8);
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -649,15 +627,12 @@ static u32 emulated_msrs[] = {
 static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 {
        if (efer & efer_reserved_bits) {
-               printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
-                      efer);
                kvm_inject_gp(vcpu, 0);
                return;
        }
 
        if (is_paging(vcpu)
            && (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) {
-               printk(KERN_DEBUG "set_efer: #GP, change LME while paging\n");
                kvm_inject_gp(vcpu, 0);
                return;
        }
@@ -667,7 +642,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 
                feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
                if (!feat || !(feat->edx & bit(X86_FEATURE_FXSR_OPT))) {
-                       printk(KERN_DEBUG "set_efer: #GP, enable FFXSR w/o CPUID capability\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -678,7 +652,6 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
 
                feat = kvm_find_cpuid_entry(vcpu, 0x80000001, 0);
                if (!feat || !(feat->ecx & bit(X86_FEATURE_SVM))) {
-                       printk(KERN_DEBUG "set_efer: #GP, enable SVM w/o SVM\n");
                        kvm_inject_gp(vcpu, 0);
                        return;
                }
@@ -967,9 +940,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                if (msr >= MSR_IA32_MC0_CTL &&
                    msr < MSR_IA32_MC0_CTL + 4 * bank_num) {
                        u32 offset = msr - MSR_IA32_MC0_CTL;
-                       /* only 0 or all 1s can be written to IA32_MCi_CTL */
+                       /* only 0 or all 1s can be written to IA32_MCi_CTL
+                        * some Linux kernels though clear bit 10 in bank 4 to
+                        * workaround a BIOS/GART TBL issue on AMD K8s, ignore
+                        * this to avoid an uncatched #GP in the guest
+                        */
                        if ((offset & 0x3) == 0 &&
-                           data != 0 && data != ~(u64)0)
+                           data != 0 && (data | (1 << 10)) != ~(u64)0)
                                return -1;
                        vcpu->arch.mce_banks[offset] = data;
                        break;
@@ -2635,8 +2612,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
                                      struct kvm_dirty_log *log)
 {
-       int r, n, i;
+       int r, i;
        struct kvm_memory_slot *memslot;
+       unsigned long n;
        unsigned long is_dirty = 0;
        unsigned long *dirty_bitmap = NULL;
 
@@ -2651,7 +2629,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
 
        r = -ENOMEM;
        dirty_bitmap = vmalloc(n);
@@ -4483,7 +4461,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                kvm_set_cr8(vcpu, kvm_run->cr8);
 
        if (vcpu->arch.pio.cur_count) {
+               vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
                r = complete_pio(vcpu);
+               srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
                if (r)
                        goto out;
        }
@@ -5146,6 +5126,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
        int ret = 0;
        u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
        u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
+       u32 desc_limit;
 
        old_tss_base = kvm_mmu_gva_to_gpa_write(vcpu, old_tss_base, NULL);
 
@@ -5168,7 +5149,10 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
                }
        }
 
-       if (!nseg_desc.p || get_desc_limit(&nseg_desc) < 0x67) {
+       desc_limit = get_desc_limit(&nseg_desc);
+       if (!nseg_desc.p ||
+           ((desc_limit < 0x67 && (nseg_desc.type & 8)) ||
+            desc_limit < 0x2b)) {
                kvm_queue_exception_e(vcpu, TS_VECTOR, tss_selector & 0xfffc);
                return 1;
        }
index 7e59dc1..2bdf628 100644 (file)
@@ -115,7 +115,7 @@ static void async_hcall(unsigned long call, unsigned long arg1,
        local_irq_save(flags);
        if (lguest_data.hcall_status[next_call] != 0xFF) {
                /* Table full, so do normal hcall which will flush table. */
-               kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+               hcall(call, arg1, arg2, arg3, arg4);
        } else {
                lguest_data.hcalls[next_call].arg0 = call;
                lguest_data.hcalls[next_call].arg1 = arg1;
@@ -145,46 +145,45 @@ static void async_hcall(unsigned long call, unsigned long arg1,
  * So, when we're in lazy mode, we call async_hcall() to store the call for
  * future processing:
  */
-static void lazy_hcall1(unsigned long call,
-                      unsigned long arg1)
+static void lazy_hcall1(unsigned long call, unsigned long arg1)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall1(call, arg1);
+               hcall(call, arg1, 0, 0, 0);
        else
                async_hcall(call, arg1, 0, 0, 0);
 }
 
 /* You can imagine what lazy_hcall2, 3 and 4 look like. :*/
 static void lazy_hcall2(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2)
+                       unsigned long arg1,
+                       unsigned long arg2)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall2(call, arg1, arg2);
+               hcall(call, arg1, arg2, 0, 0);
        else
                async_hcall(call, arg1, arg2, 0, 0);
 }
 
 static void lazy_hcall3(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3)
+                       unsigned long arg1,
+                       unsigned long arg2,
+                       unsigned long arg3)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall3(call, arg1, arg2, arg3);
+               hcall(call, arg1, arg2, arg3, 0);
        else
                async_hcall(call, arg1, arg2, arg3, 0);
 }
 
 #ifdef CONFIG_X86_PAE
 static void lazy_hcall4(unsigned long call,
-                      unsigned long arg1,
-                      unsigned long arg2,
-                      unsigned long arg3,
-                      unsigned long arg4)
+                       unsigned long arg1,
+                       unsigned long arg2,
+                       unsigned long arg3,
+                       unsigned long arg4)
 {
        if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_NONE)
-               kvm_hypercall4(call, arg1, arg2, arg3, arg4);
+               hcall(call, arg1, arg2, arg3, arg4);
        else
                async_hcall(call, arg1, arg2, arg3, arg4);
 }
@@ -196,13 +195,13 @@ static void lazy_hcall4(unsigned long call,
 :*/
 static void lguest_leave_lazy_mmu_mode(void)
 {
-       kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
        paravirt_leave_lazy_mmu();
 }
 
 static void lguest_end_context_switch(struct task_struct *next)
 {
-       kvm_hypercall0(LHCALL_FLUSH_ASYNC);
+       hcall(LHCALL_FLUSH_ASYNC, 0, 0, 0, 0);
        paravirt_end_context_switch(next);
 }
 
@@ -286,7 +285,7 @@ static void lguest_write_idt_entry(gate_desc *dt,
        /* Keep the local copy up to date. */
        native_write_idt_entry(dt, entrynum, g);
        /* Tell Host about this new entry. */
-       kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1]);
+       hcall(LHCALL_LOAD_IDT_ENTRY, entrynum, desc[0], desc[1], 0);
 }
 
 /*
@@ -300,7 +299,7 @@ static void lguest_load_idt(const struct desc_ptr *desc)
        struct desc_struct *idt = (void *)desc->address;
 
        for (i = 0; i < (desc->size+1)/8; i++)
-               kvm_hypercall3(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b);
+               hcall(LHCALL_LOAD_IDT_ENTRY, i, idt[i].a, idt[i].b, 0);
 }
 
 /*
@@ -321,7 +320,7 @@ static void lguest_load_gdt(const struct desc_ptr *desc)
        struct desc_struct *gdt = (void *)desc->address;
 
        for (i = 0; i < (desc->size+1)/8; i++)
-               kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b);
+               hcall(LHCALL_LOAD_GDT_ENTRY, i, gdt[i].a, gdt[i].b, 0);
 }
 
 /*
@@ -334,8 +333,8 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum,
 {
        native_write_gdt_entry(dt, entrynum, desc, type);
        /* Tell Host about this new entry. */
-       kvm_hypercall3(LHCALL_LOAD_GDT_ENTRY, entrynum,
-                      dt[entrynum].a, dt[entrynum].b);
+       hcall(LHCALL_LOAD_GDT_ENTRY, entrynum,
+             dt[entrynum].a, dt[entrynum].b, 0);
 }
 
 /*
@@ -931,7 +930,7 @@ static int lguest_clockevent_set_next_event(unsigned long delta,
        }
 
        /* Please wake us this far in the future. */
-       kvm_hypercall1(LHCALL_SET_CLOCKEVENT, delta);
+       hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0, 0);
        return 0;
 }
 
@@ -942,7 +941,7 @@ static void lguest_clockevent_set_mode(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
                /* A 0 argument shuts the clock down. */
-               kvm_hypercall0(LHCALL_SET_CLOCKEVENT);
+               hcall(LHCALL_SET_CLOCKEVENT, 0, 0, 0, 0);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
                /* This is what we expect. */
@@ -1100,7 +1099,7 @@ static void set_lguest_basic_apic_ops(void)
 /* STOP!  Until an interrupt comes in. */
 static void lguest_safe_halt(void)
 {
-       kvm_hypercall0(LHCALL_HALT);
+       hcall(LHCALL_HALT, 0, 0, 0, 0);
 }
 
 /*
@@ -1112,8 +1111,8 @@ static void lguest_safe_halt(void)
  */
 static void lguest_power_off(void)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa("Power down"),
-                                       LGUEST_SHUTDOWN_POWEROFF);
+       hcall(LHCALL_SHUTDOWN, __pa("Power down"),
+             LGUEST_SHUTDOWN_POWEROFF, 0, 0);
 }
 
 /*
@@ -1123,7 +1122,7 @@ static void lguest_power_off(void)
  */
 static int lguest_panic(struct notifier_block *nb, unsigned long l, void *p)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF);
+       hcall(LHCALL_SHUTDOWN, __pa(p), LGUEST_SHUTDOWN_POWEROFF, 0, 0);
        /* The hcall won't return, but to keep gcc happy, we're "done". */
        return NOTIFY_DONE;
 }
@@ -1162,7 +1161,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
                len = sizeof(scratch) - 1;
        scratch[len] = '\0';
        memcpy(scratch, buf, len);
-       kvm_hypercall1(LHCALL_NOTIFY, __pa(scratch));
+       hcall(LHCALL_NOTIFY, __pa(scratch), 0, 0, 0);
 
        /* This routine returns the number of bytes actually written. */
        return len;
@@ -1174,7 +1173,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
  */
 static void lguest_restart(char *reason)
 {
-       kvm_hypercall2(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART);
+       hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0, 0);
 }
 
 /*G:050
index 27eac0f..4f420c2 100644 (file)
@@ -32,7 +32,7 @@ ENTRY(lguest_entry)
         */
        movl $LHCALL_LGUEST_INIT, %eax
        movl $lguest_data - __PAGE_OFFSET, %ebx
-       .byte 0x0f,0x01,0xc1 /* KVM_HYPERCALL */
+       int $LGUEST_TRAP_ENTRY
 
        /* Set up the initial stack so we can run C code. */
        movl $(init_thread_union+THREAD_SIZE),%esp
index 62a5921..f9e89f4 100644 (file)
@@ -78,8 +78,9 @@ config BLK_DEV_INTEGRITY
        Protection.  If in doubt, say N.
 
 config BLK_CGROUP
-       tristate
+       tristate "Block cgroup support"
        depends on CGROUPS
+       depends on CFQ_GROUP_IOSCHED
        default n
        ---help---
        Generic block IO controller cgroup interface. This is the common
index d9a9db5..f5ed5a1 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>     /* for max_pfn/max_low_pfn */
 #include <linux/gcd.h>
+#include <linux/lcm.h>
 #include <linux/jiffies.h>
 #include <linux/gfp.h>
 
@@ -462,16 +463,6 @@ void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
 }
 EXPORT_SYMBOL(blk_queue_stack_limits);
 
-static unsigned int lcm(unsigned int a, unsigned int b)
-{
-       if (a && b)
-               return (a * b) / gcd(a, b);
-       else if (b)
-               return b;
-
-       return a;
-}
-
 /**
  * blk_stack_limits - adjust queue_limits for stacked devices
  * @t: the stacking driver limits (top device)
index c2b821f..306759b 100644 (file)
@@ -107,6 +107,19 @@ static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
        return queue_var_show(max_sectors_kb, (page));
 }
 
+static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
+{
+       return queue_var_show(queue_max_segments(q), (page));
+}
+
+static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
+{
+       if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
+               return queue_var_show(queue_max_segment_size(q), (page));
+
+       return queue_var_show(PAGE_CACHE_SIZE, (page));
+}
+
 static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)
 {
        return queue_var_show(queue_logical_block_size(q), page);
@@ -281,6 +294,16 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
        .show = queue_max_hw_sectors_show,
 };
 
+static struct queue_sysfs_entry queue_max_segments_entry = {
+       .attr = {.name = "max_segments", .mode = S_IRUGO },
+       .show = queue_max_segments_show,
+};
+
+static struct queue_sysfs_entry queue_max_segment_size_entry = {
+       .attr = {.name = "max_segment_size", .mode = S_IRUGO },
+       .show = queue_max_segment_size_show,
+};
+
 static struct queue_sysfs_entry queue_iosched_entry = {
        .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
        .show = elv_iosched_show,
@@ -356,6 +379,8 @@ static struct attribute *default_attrs[] = {
        &queue_ra_entry.attr,
        &queue_max_hw_sectors_entry.attr,
        &queue_max_sectors_entry.attr,
+       &queue_max_segments_entry.attr,
+       &queue_max_segment_size_entry.attr,
        &queue_iosched_entry.attr,
        &queue_hw_sector_size_entry.attr,
        &queue_logical_block_size_entry.attr,
index fc98a48..838834b 100644 (file)
@@ -48,6 +48,7 @@ static const int cfq_hist_divisor = 4;
 #define CFQ_SERVICE_SHIFT       12
 
 #define CFQQ_SEEK_THR          (sector_t)(8 * 100)
+#define CFQQ_CLOSE_THR         (sector_t)(8 * 1024)
 #define CFQQ_SECT_THR_NONROT   (sector_t)(2 * 32)
 #define CFQQ_SEEKY(cfqq)       (hweight32(cfqq->seek_history) > 32/8)
 
@@ -948,6 +949,11 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create)
        unsigned int major, minor;
 
        cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
+       if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
+               sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+               cfqg->blkg.dev = MKDEV(major, minor);
+               goto done;
+       }
        if (cfqg || !create)
                goto done;
 
@@ -1518,7 +1524,8 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
                                   struct cfq_queue *cfqq)
 {
        if (cfqq) {
-               cfq_log_cfqq(cfqd, cfqq, "set_active");
+               cfq_log_cfqq(cfqd, cfqq, "set_active wl_prio:%d wl_type:%d",
+                               cfqd->serving_prio, cfqd->serving_type);
                cfqq->slice_start = 0;
                cfqq->dispatch_start = jiffies;
                cfqq->allocated_slice = 0;
@@ -1661,9 +1668,9 @@ static inline sector_t cfq_dist_from_last(struct cfq_data *cfqd,
 }
 
 static inline int cfq_rq_close(struct cfq_data *cfqd, struct cfq_queue *cfqq,
-                              struct request *rq, bool for_preempt)
+                              struct request *rq)
 {
-       return cfq_dist_from_last(cfqd, rq) <= CFQQ_SEEK_THR;
+       return cfq_dist_from_last(cfqd, rq) <= CFQQ_CLOSE_THR;
 }
 
 static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
@@ -1690,7 +1697,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
         * will contain the closest sector.
         */
        __cfqq = rb_entry(parent, struct cfq_queue, p_node);
-       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
                return __cfqq;
 
        if (blk_rq_pos(__cfqq->next_rq) < sector)
@@ -1701,7 +1708,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
                return NULL;
 
        __cfqq = rb_entry(node, struct cfq_queue, p_node);
-       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq, false))
+       if (cfq_rq_close(cfqd, cur_cfqq, __cfqq->next_rq))
                return __cfqq;
 
        return NULL;
@@ -1722,6 +1729,8 @@ static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
 {
        struct cfq_queue *cfqq;
 
+       if (cfq_class_idle(cur_cfqq))
+               return NULL;
        if (!cfq_cfqq_sync(cur_cfqq))
                return NULL;
        if (CFQQ_SEEKY(cur_cfqq))
@@ -1788,7 +1797,11 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq)
         * Otherwise, we do only if they are the last ones
         * in their service tree.
         */
-       return service_tree->count == 1 && cfq_cfqq_sync(cfqq);
+       if (service_tree->count == 1 && cfq_cfqq_sync(cfqq))
+               return 1;
+       cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d",
+                       service_tree->count);
+       return 0;
 }
 
 static void cfq_arm_slice_timer(struct cfq_data *cfqd)
@@ -1833,8 +1846,11 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
         * time slice.
         */
        if (sample_valid(cic->ttime_samples) &&
-           (cfqq->slice_end - jiffies < cic->ttime_mean))
+           (cfqq->slice_end - jiffies < cic->ttime_mean)) {
+               cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d",
+                               cic->ttime_mean);
                return;
+       }
 
        cfq_mark_cfqq_wait_request(cfqq);
 
@@ -2042,6 +2058,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg)
                slice = max(slice, 2 * cfqd->cfq_slice_idle);
 
        slice = max_t(unsigned, slice, CFQ_MIN_TT);
+       cfq_log(cfqd, "workload slice:%d", slice);
        cfqd->workload_expires = jiffies + slice;
        cfqd->noidle_tree_requires_idle = false;
 }
@@ -2189,10 +2206,13 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
        struct cfq_queue *cfqq;
        int dispatched = 0;
 
-       while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL)
+       /* Expire the timeslice of the current active queue first */
+       cfq_slice_expired(cfqd, 0);
+       while ((cfqq = cfq_get_next_queue_forced(cfqd)) != NULL) {
+               __cfq_set_active_queue(cfqd, cfqq);
                dispatched += __cfq_forced_dispatch_cfqq(cfqq);
+       }
 
-       cfq_slice_expired(cfqd, 0);
        BUG_ON(cfqd->busy_queues);
 
        cfq_log(cfqd, "forced_dispatch=%d", dispatched);
@@ -3104,7 +3124,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
         * if this request is as-good as one we would expect from the
         * current cfqq, let it preempt
         */
-       if (cfq_rq_close(cfqd, cfqq, rq, true))
+       if (cfq_rq_close(cfqd, cfqq, rq))
                return true;
 
        return false;
@@ -3308,6 +3328,7 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
                if (cfq_should_wait_busy(cfqd, cfqq)) {
                        cfqq->slice_end = jiffies + cfqd->cfq_slice_idle;
                        cfq_mark_cfqq_wait_busy(cfqq);
+                       cfq_log_cfqq(cfqd, cfqq, "will busy wait");
                }
 
                /*
index df75676..76e3702 100644 (file)
@@ -154,7 +154,7 @@ static struct elevator_type *elevator_get(const char *name)
 
                spin_unlock(&elv_list_lock);
 
-               sprintf(elv, "%s-iosched", name);
+               snprintf(elv, sizeof(elv), "%s-iosched", name);
 
                request_module("%s", elv);
                spin_lock(&elv_list_lock);
index a610ebe..2fbfe51 100644 (file)
@@ -471,13 +471,18 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
                /* allow full data read from EC address space */
                if (obj_desc->field.region_obj->region.space_id ==
                        ACPI_ADR_SPACE_EC) {
-                       if (obj_desc->common_field.bit_length > 8)
-                               obj_desc->common_field.access_bit_width =
-                               ACPI_ROUND_UP(obj_desc->common_field.
-                                                       bit_length, 8);
+                       if (obj_desc->common_field.bit_length > 8) {
+                               unsigned width =
+                                       ACPI_ROUND_BITS_UP_TO_BYTES(
+                                       obj_desc->common_field.bit_length);
+                               // access_bit_width is u8, don't overflow it
+                               if (width > 8)
+                                       width = 8;
                                obj_desc->common_field.access_byte_width =
-                               ACPI_DIV_8(obj_desc->common_field.
-                                                       access_bit_width);
+                                                       width;
+                               obj_desc->common_field.access_bit_width =
+                                                       8 * width;
+                       }
                }
 
                ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
index 4f4aa58..933442f 100644 (file)
@@ -313,7 +313,7 @@ static ssize_t
 print_block_size(struct sysdev_class *class, struct sysdev_class_attribute *attr,
                 char *buf)
 {
-       return sprintf(buf, "%#lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
+       return sprintf(buf, "%lx\n", (unsigned long)PAGES_PER_SECTION * PAGE_SIZE);
 }
 
 static SYSDEV_CLASS_ATTR(block_size_bytes, 0444, print_block_size, NULL);
index 459f1bc..c5f22bb 100644 (file)
@@ -2533,7 +2533,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
        Controller->RequestQueue[n] = RequestQueue;
        blk_queue_bounce_limit(RequestQueue, Controller->BounceBufferLimit);
        RequestQueue->queuedata = Controller;
-       blk_queue_max_hw_segments(RequestQueue, Controller->DriverScatterGatherLimit);
        blk_queue_max_segments(RequestQueue, Controller->DriverScatterGatherLimit);
        blk_queue_max_hw_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
        disk->queue = RequestQueue;
index 17956ff..df01899 100644 (file)
@@ -536,7 +536,9 @@ static void atodb_endio(struct bio *bio, int error)
        put_ldev(mdev);
 }
 
+/* sector to word */
 #define S2W(s) ((s)<<(BM_EXT_SHIFT-BM_BLOCK_SHIFT-LN2_BPL))
+
 /* activity log to on disk bitmap -- prepare bio unless that sector
  * is already covered by previously prepared bios */
 static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
@@ -546,13 +548,20 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
 {
        struct bio *bio;
        struct page *page;
-       sector_t on_disk_sector = enr + mdev->ldev->md.md_offset
-                                     + mdev->ldev->md.bm_offset;
+       sector_t on_disk_sector;
        unsigned int page_offset = PAGE_SIZE;
        int offset;
        int i = 0;
        int err = -ENOMEM;
 
+       /* We always write aligned, full 4k blocks,
+        * so we can ignore the logical_block_size (for now) */
+       enr &= ~7U;
+       on_disk_sector = enr + mdev->ldev->md.md_offset
+                            + mdev->ldev->md.bm_offset;
+
+       D_ASSERT(!(on_disk_sector & 7U));
+
        /* Check if that enr is already covered by an already created bio.
         * Caution, bios[] is not NULL terminated,
         * but only initialized to all NULL.
@@ -588,7 +597,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
 
        offset = S2W(enr);
        drbd_bm_get_lel(mdev, offset,
-                       min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset),
+                       min_t(size_t, S2W(8), drbd_bm_words(mdev) - offset),
                        kmap(page) + page_offset);
        kunmap(page);
 
@@ -597,7 +606,7 @@ static int atodb_prepare_unless_covered(struct drbd_conf *mdev,
        bio->bi_bdev = mdev->ldev->md_bdev;
        bio->bi_sector = on_disk_sector;
 
-       if (bio_add_page(bio, page, MD_SECTOR_SIZE, page_offset) != MD_SECTOR_SIZE)
+       if (bio_add_page(bio, page, 4096, page_offset) != 4096)
                goto out_put_page;
 
        atomic_inc(&wc->count);
@@ -1327,7 +1336,7 @@ int drbd_rs_del_all(struct drbd_conf *mdev)
                /* ok, ->resync is there. */
                for (i = 0; i < mdev->resync->nr_elements; i++) {
                        e = lc_element_by_index(mdev->resync, i);
-                       bm_ext = e ? lc_entry(e, struct bm_extent, lce) : NULL;
+                       bm_ext = lc_entry(e, struct bm_extent, lce);
                        if (bm_ext->lce.lc_number == LC_FREE)
                                continue;
                        if (bm_ext->lce.lc_number == mdev->resync_wenr) {
index 3d6f3d9..3390716 100644 (file)
@@ -67,7 +67,7 @@ struct drbd_bitmap {
        size_t   bm_words;
        size_t   bm_number_of_pages;
        sector_t bm_dev_capacity;
-       struct semaphore bm_change; /* serializes resize operations */
+       struct mutex bm_change; /* serializes resize operations */
 
        atomic_t bm_async_io;
        wait_queue_head_t bm_io_wait;
@@ -115,7 +115,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why)
                return;
        }
 
-       trylock_failed = down_trylock(&b->bm_change);
+       trylock_failed = !mutex_trylock(&b->bm_change);
 
        if (trylock_failed) {
                dev_warn(DEV, "%s going to '%s' but bitmap already locked for '%s' by %s\n",
@@ -126,7 +126,7 @@ void drbd_bm_lock(struct drbd_conf *mdev, char *why)
                    b->bm_task == mdev->receiver.task ? "receiver" :
                    b->bm_task == mdev->asender.task  ? "asender"  :
                    b->bm_task == mdev->worker.task   ? "worker"   : "?");
-               down(&b->bm_change);
+               mutex_lock(&b->bm_change);
        }
        if (__test_and_set_bit(BM_LOCKED, &b->bm_flags))
                dev_err(DEV, "FIXME bitmap already locked in bm_lock\n");
@@ -148,7 +148,7 @@ void drbd_bm_unlock(struct drbd_conf *mdev)
 
        b->bm_why  = NULL;
        b->bm_task = NULL;
-       up(&b->bm_change);
+       mutex_unlock(&b->bm_change);
 }
 
 /* word offset to long pointer */
@@ -296,7 +296,7 @@ int drbd_bm_init(struct drbd_conf *mdev)
        if (!b)
                return -ENOMEM;
        spin_lock_init(&b->bm_lock);
-       init_MUTEX(&b->bm_change);
+       mutex_init(&b->bm_change);
        init_waitqueue_head(&b->bm_io_wait);
 
        mdev->bitmap = b;
index d9301e8..e5e86a7 100644 (file)
@@ -261,6 +261,9 @@ static inline const char *cmdname(enum drbd_packets cmd)
                [P_OV_REQUEST]          = "OVRequest",
                [P_OV_REPLY]            = "OVReply",
                [P_OV_RESULT]           = "OVResult",
+               [P_CSUM_RS_REQUEST]     = "CsumRSRequest",
+               [P_RS_IS_IN_SYNC]       = "CsumRSIsInSync",
+               [P_COMPRESSED_BITMAP]   = "CBitmap",
                [P_MAX_CMD]             = NULL,
        };
 
@@ -443,13 +446,18 @@ struct p_rs_param_89 {
        char csums_alg[SHARED_SECRET_MAX];
 } __packed;
 
+enum drbd_conn_flags {
+       CF_WANT_LOSE = 1,
+       CF_DRY_RUN = 2,
+};
+
 struct p_protocol {
        struct p_header head;
        u32 protocol;
        u32 after_sb_0p;
        u32 after_sb_1p;
        u32 after_sb_2p;
-       u32 want_lose;
+       u32 conn_flags;
        u32 two_primaries;
 
               /* Since protocol version 87 and higher. */
@@ -791,6 +799,8 @@ enum {
                                 * while this is set. */
        RESIZE_PENDING,         /* Size change detected locally, waiting for the response from
                                 * the peer, if it changed there as well. */
+       CONN_DRY_RUN,           /* Expect disconnect after resync handshake. */
+       GOT_PING_ACK,           /* set when we receive a ping_ack packet, misc wait gets woken */
 };
 
 struct drbd_bitmap; /* opaque for drbd_conf */
index ab871e0..67e0fc5 100644 (file)
@@ -1668,7 +1668,7 @@ int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc)
 int drbd_send_protocol(struct drbd_conf *mdev)
 {
        struct p_protocol *p;
-       int size, rv;
+       int size, cf, rv;
 
        size = sizeof(struct p_protocol);
 
@@ -1685,9 +1685,21 @@ int drbd_send_protocol(struct drbd_conf *mdev)
        p->after_sb_0p   = cpu_to_be32(mdev->net_conf->after_sb_0p);
        p->after_sb_1p   = cpu_to_be32(mdev->net_conf->after_sb_1p);
        p->after_sb_2p   = cpu_to_be32(mdev->net_conf->after_sb_2p);
-       p->want_lose     = cpu_to_be32(mdev->net_conf->want_lose);
        p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
 
+       cf = 0;
+       if (mdev->net_conf->want_lose)
+               cf |= CF_WANT_LOSE;
+       if (mdev->net_conf->dry_run) {
+               if (mdev->agreed_pro_version >= 92)
+                       cf |= CF_DRY_RUN;
+               else {
+                       dev_err(DEV, "--dry-run is not supported by peer");
+                       return 0;
+               }
+       }
+       p->conn_flags    = cpu_to_be32(cf);
+
        if (mdev->agreed_pro_version >= 87)
                strcpy(p->integrity_alg, mdev->net_conf->integrity_alg);
 
@@ -3161,14 +3173,18 @@ void drbd_free_bc(struct drbd_backing_dev *ldev)
 void drbd_free_sock(struct drbd_conf *mdev)
 {
        if (mdev->data.socket) {
+               mutex_lock(&mdev->data.mutex);
                kernel_sock_shutdown(mdev->data.socket, SHUT_RDWR);
                sock_release(mdev->data.socket);
                mdev->data.socket = NULL;
+               mutex_unlock(&mdev->data.mutex);
        }
        if (mdev->meta.socket) {
+               mutex_lock(&mdev->meta.mutex);
                kernel_sock_shutdown(mdev->meta.socket, SHUT_RDWR);
                sock_release(mdev->meta.socket);
                mdev->meta.socket = NULL;
+               mutex_unlock(&mdev->meta.mutex);
        }
 }
 
index 4df3b40..6429d2b 100644 (file)
@@ -285,8 +285,8 @@ int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
                }
 
                if (r == SS_NO_UP_TO_DATE_DISK && force &&
-                   (mdev->state.disk == D_INCONSISTENT ||
-                    mdev->state.disk == D_OUTDATED)) {
+                   (mdev->state.disk < D_UP_TO_DATE &&
+                    mdev->state.disk >= D_INCONSISTENT)) {
                        mask.disk = D_MASK;
                        val.disk  = D_UP_TO_DATE;
                        forced = 1;
@@ -407,7 +407,7 @@ static int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
        }
 
        reply->ret_code =
-               drbd_set_role(mdev, R_PRIMARY, primary_args.overwrite_peer);
+               drbd_set_role(mdev, R_PRIMARY, primary_args.primary_force);
 
        return 0;
 }
@@ -941,6 +941,25 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
 
        drbd_md_set_sector_offsets(mdev, nbc);
 
+       /* allocate a second IO page if logical_block_size != 512 */
+       logical_block_size = bdev_logical_block_size(nbc->md_bdev);
+       if (logical_block_size == 0)
+               logical_block_size = MD_SECTOR_SIZE;
+
+       if (logical_block_size != MD_SECTOR_SIZE) {
+               if (!mdev->md_io_tmpp) {
+                       struct page *page = alloc_page(GFP_NOIO);
+                       if (!page)
+                               goto force_diskless_dec;
+
+                       dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
+                            logical_block_size, MD_SECTOR_SIZE);
+                       dev_warn(DEV, "Workaround engaged (has performance impact).\n");
+
+                       mdev->md_io_tmpp = page;
+               }
+       }
+
        if (!mdev->bitmap) {
                if (drbd_bm_init(mdev)) {
                        retcode = ERR_NOMEM;
@@ -980,25 +999,6 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp
                goto force_diskless_dec;
        }
 
-       /* allocate a second IO page if logical_block_size != 512 */
-       logical_block_size = bdev_logical_block_size(nbc->md_bdev);
-       if (logical_block_size == 0)
-               logical_block_size = MD_SECTOR_SIZE;
-
-       if (logical_block_size != MD_SECTOR_SIZE) {
-               if (!mdev->md_io_tmpp) {
-                       struct page *page = alloc_page(GFP_NOIO);
-                       if (!page)
-                               goto force_diskless_dec;
-
-                       dev_warn(DEV, "Meta data's bdev logical_block_size = %d != %d\n",
-                            logical_block_size, MD_SECTOR_SIZE);
-                       dev_warn(DEV, "Workaround engaged (has performance impact).\n");
-
-                       mdev->md_io_tmpp = page;
-               }
-       }
-
        /* Reset the "barriers don't work" bits here, then force meta data to
         * be written, to ensure we determine if barriers are supported. */
        if (nbc->dc.no_md_flush)
index d065c64..ed9f1de 100644 (file)
@@ -2513,6 +2513,10 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
        }
 
        if (hg == -100) {
+               /* FIXME this log message is not correct if we end up here
+                * after an attempted attach on a diskless node.
+                * We just refuse to attach -- well, we drop the "connection"
+                * to that disk, in a way... */
                dev_alert(DEV, "Split-Brain detected, dropping connection!\n");
                drbd_khelper(mdev, "split-brain");
                return C_MASK;
@@ -2538,6 +2542,16 @@ static enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_rol
                }
        }
 
+       if (mdev->net_conf->dry_run || test_bit(CONN_DRY_RUN, &mdev->flags)) {
+               if (hg == 0)
+                       dev_info(DEV, "dry-run connect: No resync, would become Connected immediately.\n");
+               else
+                       dev_info(DEV, "dry-run connect: Would become %s, doing a %s resync.",
+                                drbd_conn_str(hg > 0 ? C_SYNC_SOURCE : C_SYNC_TARGET),
+                                abs(hg) >= 2 ? "full" : "bit-map based");
+               return C_MASK;
+       }
+
        if (abs(hg) >= 2) {
                dev_info(DEV, "Writing the whole bitmap, full sync required after drbd_sync_handshake.\n");
                if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake"))
@@ -2585,7 +2599,7 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h)
        struct p_protocol *p = (struct p_protocol *)h;
        int header_size, data_size;
        int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
-       int p_want_lose, p_two_primaries;
+       int p_want_lose, p_two_primaries, cf;
        char p_integrity_alg[SHARED_SECRET_MAX] = "";
 
        header_size = sizeof(*p) - sizeof(*h);
@@ -2598,8 +2612,14 @@ static int receive_protocol(struct drbd_conf *mdev, struct p_header *h)
        p_after_sb_0p   = be32_to_cpu(p->after_sb_0p);
        p_after_sb_1p   = be32_to_cpu(p->after_sb_1p);
        p_after_sb_2p   = be32_to_cpu(p->after_sb_2p);
-       p_want_lose     = be32_to_cpu(p->want_lose);
        p_two_primaries = be32_to_cpu(p->two_primaries);
+       cf              = be32_to_cpu(p->conn_flags);
+       p_want_lose = cf & CF_WANT_LOSE;
+
+       clear_bit(CONN_DRY_RUN, &mdev->flags);
+
+       if (cf & CF_DRY_RUN)
+               set_bit(CONN_DRY_RUN, &mdev->flags);
 
        if (p_proto != mdev->net_conf->wire_protocol) {
                dev_err(DEV, "incompatible communication protocols\n");
@@ -3118,13 +3138,16 @@ static int receive_state(struct drbd_conf *mdev, struct p_header *h)
 
                put_ldev(mdev);
                if (nconn == C_MASK) {
+                       nconn = C_CONNECTED;
                        if (mdev->state.disk == D_NEGOTIATING) {
                                drbd_force_state(mdev, NS(disk, D_DISKLESS));
-                               nconn = C_CONNECTED;
                        } else if (peer_state.disk == D_NEGOTIATING) {
                                dev_err(DEV, "Disk attach process on the peer node was aborted.\n");
                                peer_state.disk = D_DISKLESS;
+                               real_peer_disk = D_DISKLESS;
                        } else {
+                               if (test_and_clear_bit(CONN_DRY_RUN, &mdev->flags))
+                                       return FALSE;
                                D_ASSERT(oconn == C_WF_REPORT_PARAMS);
                                drbd_force_state(mdev, NS(conn, C_DISCONNECTING));
                                return FALSE;
@@ -3594,10 +3617,7 @@ static void drbd_disconnect(struct drbd_conf *mdev)
 
        /* asender does not clean up anything. it must not interfere, either */
        drbd_thread_stop(&mdev->asender);
-
-       mutex_lock(&mdev->data.mutex);
        drbd_free_sock(mdev);
-       mutex_unlock(&mdev->data.mutex);
 
        spin_lock_irq(&mdev->req_lock);
        _drbd_wait_ee_list_empty(mdev, &mdev->active_ee);
@@ -4054,6 +4074,8 @@ static int got_PingAck(struct drbd_conf *mdev, struct p_header *h)
 {
        /* restore idle timeout */
        mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
+       if (!test_and_set_bit(GOT_PING_ACK, &mdev->flags))
+               wake_up(&mdev->misc_wait);
 
        return TRUE;
 }
index b453c2b..44bf6d1 100644 (file)
@@ -938,7 +938,8 @@ int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 
                if (eq) {
                        drbd_set_in_sync(mdev, e->sector, e->size);
-                       mdev->rs_same_csum++;
+                       /* rs_same_csums unit is BM_BLOCK_SIZE */
+                       mdev->rs_same_csum += e->size >> BM_BLOCK_SHIFT;
                        ok = drbd_send_ack(mdev, P_RS_IS_IN_SYNC, e);
                } else {
                        inc_rs_pending(mdev);
@@ -1288,6 +1289,14 @@ int drbd_alter_sa(struct drbd_conf *mdev, int na)
        return retcode;
 }
 
+static void ping_peer(struct drbd_conf *mdev)
+{
+       clear_bit(GOT_PING_ACK, &mdev->flags);
+       request_ping(mdev);
+       wait_event(mdev->misc_wait,
+                  test_bit(GOT_PING_ACK, &mdev->flags) || mdev->state.conn < C_CONNECTED);
+}
+
 /**
  * drbd_start_resync() - Start the resync process
  * @mdev:      DRBD device.
@@ -1371,7 +1380,6 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
                _drbd_pause_after(mdev);
        }
        write_unlock_irq(&global_state_lock);
-       drbd_state_unlock(mdev);
        put_ldev(mdev);
 
        if (r == SS_SUCCESS) {
@@ -1382,11 +1390,8 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 
                if (mdev->rs_total == 0) {
                        /* Peer still reachable? Beware of failing before-resync-target handlers! */
-                       request_ping(mdev);
-                       __set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(mdev->net_conf->ping_timeo*HZ/9); /* 9 instead 10 */
+                       ping_peer(mdev);
                        drbd_resync_finished(mdev);
-                       return;
                }
 
                /* ns.conn may already be != mdev->state.conn,
@@ -1398,6 +1403,7 @@ void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side)
 
                drbd_md_sync(mdev);
        }
+       drbd_state_unlock(mdev);
 }
 
 int drbd_worker(struct drbd_thread *thi)
index cb69929..8546d12 100644 (file)
@@ -237,6 +237,8 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
                if (ret)
                        goto fail;
 
+               file_update_time(file);
+
                transfer_result = lo_do_transfer(lo, WRITE, page, offset,
                                bvec->bv_page, bv_offs, size, IV);
                copied = size;
index 8866ca3..71acf4e 100644 (file)
@@ -341,11 +341,11 @@ static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
               && (j++ < PCD_SPIN))
                udelay(PCD_DELAY);
 
-       if ((r & (IDE_ERR & stop)) || (j >= PCD_SPIN)) {
+       if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
                s = read_reg(cd, 7);
                e = read_reg(cd, 1);
                p = read_reg(cd, 2);
-               if (j >= PCD_SPIN)
+               if (j > PCD_SPIN)
                        e |= 0x100;
                if (fun)
                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
index ddb4f9a..c059aab 100644 (file)
@@ -391,11 +391,11 @@ static int pf_wait(struct pf_unit *pf, int go, int stop, char *fun, char *msg)
               && (j++ < PF_SPIN))
                udelay(PF_SPIN_DEL);
 
-       if ((r & (STAT_ERR & stop)) || (j >= PF_SPIN)) {
+       if ((r & (STAT_ERR & stop)) || (j > PF_SPIN)) {
                s = read_reg(pf, 7);
                e = read_reg(pf, 1);
                p = read_reg(pf, 2);
-               if (j >= PF_SPIN)
+               if (j > PF_SPIN)
                        e |= 0x100;
                if (fun)
                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
index 1e4006e..bc5825f 100644 (file)
@@ -274,11 +274,11 @@ static int pt_wait(struct pt_unit *tape, int go, int stop, char *fun, char *msg)
               && (j++ < PT_SPIN))
                udelay(PT_SPIN_DEL);
 
-       if ((r & (STAT_ERR & stop)) || (j >= PT_SPIN)) {
+       if ((r & (STAT_ERR & stop)) || (j > PT_SPIN)) {
                s = read_reg(pi, 7);
                e = read_reg(pi, 1);
                p = read_reg(pi, 2);
-               if (j >= PT_SPIN)
+               if (j > PT_SPIN)
                        e |= 0x100;
                if (fun)
                        printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
index 4b12b82..2138a7a 100644 (file)
@@ -348,14 +348,13 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
        set_capacity(vblk->disk, cap);
 
        /* We can handle whatever the host told us to handle. */
-       blk_queue_max_phys_segments(q, vblk->sg_elems-2);
-       blk_queue_max_hw_segments(q, vblk->sg_elems-2);
+       blk_queue_max_segments(q, vblk->sg_elems-2);
 
        /* No need to bounce any requests */
        blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
 
        /* No real sector limit. */
-       blk_queue_max_sectors(q, -1U);
+       blk_queue_max_hw_sectors(q, -1U);
 
        /* Host can optionally specify maximum segment size and number of
         * segments. */
index d41331b..aa4248e 100644 (file)
@@ -1817,8 +1817,6 @@ static int intel_845_configure(void)
        pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
        /* clear any possible error conditions */
        pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
-
-       intel_i830_setup_flush();
        return 0;
 }
 
@@ -2188,7 +2186,6 @@ static const struct agp_bridge_driver intel_845_driver = {
        .agp_destroy_page       = agp_generic_destroy_page,
        .agp_destroy_pages      = agp_generic_destroy_pages,
        .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
-       .chipset_flush          = intel_i830_chipset_flush,
 };
 
 static const struct agp_bridge_driver intel_850_driver = {
index c9bc896..90b199f 100644 (file)
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
 
        xoutb(0, REG_FLAGS1(iobase));   /* clear detectCMM */
        /* last check before exit */
-       if (!io_detect_cm4000(iobase, dev))
-               count = -ENODEV;
+       if (!io_detect_cm4000(iobase, dev)) {
+               rc = -ENODEV;
+               goto release_io;
+       }
 
        if (test_bit(IS_INVREV, &dev->flags) && count > 0)
                str_invert_revert(dev->rbuf, count);
 
        if (copy_to_user(buf, dev->rbuf, count))
-               return -EFAULT;
+               rc = -EFAULT;
 
 release_io:
        clear_bit(LOCK_IO, &dev->flags);
index 702dcc9..14a34d9 100644 (file)
@@ -960,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
                u.packet.header_length = GET_HEADER_LENGTH(control);
 
                if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
+                       if (u.packet.header_length % 4 != 0)
+                               return -EINVAL;
                        header_length = u.packet.header_length;
                } else {
                        /*
@@ -969,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
                        if (ctx->header_size == 0) {
                                if (u.packet.header_length > 0)
                                        return -EINVAL;
-                       } else if (u.packet.header_length % ctx->header_size != 0) {
+                       } else if (u.packet.header_length == 0 ||
+                                  u.packet.header_length % ctx->header_size != 0) {
                                return -EINVAL;
                        }
                        header_length = 0;
@@ -1354,24 +1357,24 @@ static int dispatch_ioctl(struct client *client,
                return -ENODEV;
 
        if (_IOC_TYPE(cmd) != '#' ||
-           _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers))
+           _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
+           _IOC_SIZE(cmd) > sizeof(buffer))
                return -EINVAL;
 
-       if (_IOC_DIR(cmd) & _IOC_WRITE) {
-               if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-                   copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
+       if (_IOC_DIR(cmd) == _IOC_READ)
+               memset(&buffer, 0, _IOC_SIZE(cmd));
+
+       if (_IOC_DIR(cmd) & _IOC_WRITE)
+               if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
                        return -EFAULT;
-       }
 
        ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer);
        if (ret < 0)
                return ret;
 
-       if (_IOC_DIR(cmd) & _IOC_READ) {
-               if (_IOC_SIZE(cmd) > sizeof(buffer) ||
-                   copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
+       if (_IOC_DIR(cmd) & _IOC_READ)
+               if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
                        return -EFAULT;
-       }
 
        return ret;
 }
index 2cc6e87..18f41d7 100644 (file)
@@ -85,6 +85,8 @@ static struct edid_quirk {
 
        /* Envision Peripherals, Inc. EN-7100e */
        { "EPI", 59264, EDID_QUIRK_135_CLOCK_TOO_HIGH },
+       /* Envision EN2028 */
+       { "EPI", 8232, EDID_QUIRK_PREFER_LARGE_60 },
 
        /* Funai Electronics PM36B */
        { "FCM", 13600, EDID_QUIRK_PREFER_LARGE_75 |
index b743411..a0c365f 100644 (file)
@@ -516,8 +516,6 @@ void drm_put_dev(struct drm_device *dev)
        }
        driver = dev->driver;
 
-       drm_vblank_cleanup(dev);
-
        drm_lastclose(dev);
 
        if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
@@ -537,6 +535,8 @@ void drm_put_dev(struct drm_device *dev)
                dev->agp = NULL;
        }
 
+       drm_vblank_cleanup(dev);
+
        list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
                drm_rmmap(dev, r_list->map);
        drm_ht_remove(&dev->map_hash);
index b574503..a0b8447 100644 (file)
@@ -226,7 +226,7 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data)
                } else {
                        struct drm_i915_gem_object *obj_priv;
 
-                       obj_priv = obj->driver_private;
+                       obj_priv = to_intel_bo(obj);
                        seq_printf(m, "Fenced object[%2d] = %p: %s "
                                   "%08x %08zx %08x %s %08x %08x %d",
                                   i, obj, get_pin_flag(obj_priv),
index 4b26919..0af3dcc 100644 (file)
@@ -80,14 +80,14 @@ const static struct intel_device_info intel_i915g_info = {
        .is_i915g = 1, .is_i9xx = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i915gm_info = {
-       .is_i9xx = 1,  .is_mobile = 1, .has_fbc = 1,
+       .is_i9xx = 1,  .is_mobile = 1,
        .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945g_info = {
        .is_i9xx = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 const static struct intel_device_info intel_i945gm_info = {
-       .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1, .has_fbc = 1,
+       .is_i945gm = 1, .is_i9xx = 1, .is_mobile = 1,
        .has_hotplug = 1, .cursor_needs_physical = 1,
 };
 
@@ -361,7 +361,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
            !dev_priv->mm.suspended) {
                drm_i915_ring_buffer_t *ring = &dev_priv->ring;
                struct drm_gem_object *obj = ring->ring_obj;
-               struct drm_i915_gem_object *obj_priv = obj->driver_private;
+               struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
                dev_priv->mm.suspended = 0;
 
                /* Stop the ring if it's running. */
index aba8260..6960849 100644 (file)
@@ -611,6 +611,8 @@ typedef struct drm_i915_private {
        /* Reclocking support */
        bool render_reclock_avail;
        bool lvds_downclock_avail;
+       /* indicate whether the LVDS EDID is OK */
+       bool lvds_edid_good;
        /* indicates the reduced downclock for LVDS*/
        int lvds_downclock;
        struct work_struct idle_work;
@@ -731,6 +733,8 @@ struct drm_i915_gem_object {
        atomic_t pending_flip;
 };
 
+#define to_intel_bo(x) ((struct drm_i915_gem_object *) (x)->driver_private)
+
 /**
  * Request queue structure.
  *
index 368d726..80871c6 100644 (file)
@@ -163,7 +163,7 @@ fast_shmem_read(struct page **pages,
 static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj)
 {
        drm_i915_private_t *dev_priv = obj->dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
                obj_priv->tiling_mode != I915_TILING_NONE;
@@ -264,7 +264,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
                          struct drm_i915_gem_pread *args,
                          struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        ssize_t remain;
        loff_t offset, page_base;
        char __user *user_data;
@@ -285,7 +285,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
 
        while (remain > 0) {
@@ -354,7 +354,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
                          struct drm_i915_gem_pread *args,
                          struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct mm_struct *mm = current->mm;
        struct page **user_pages;
        ssize_t remain;
@@ -403,7 +403,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
 
        while (remain > 0) {
@@ -479,7 +479,7 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Bounds check source.
         *
@@ -581,7 +581,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
                         struct drm_i915_gem_pwrite *args,
                         struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        drm_i915_private_t *dev_priv = dev->dev_private;
        ssize_t remain;
        loff_t offset, page_base;
@@ -605,7 +605,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret)
                goto fail;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = obj_priv->gtt_offset + args->offset;
 
        while (remain > 0) {
@@ -655,7 +655,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                         struct drm_i915_gem_pwrite *args,
                         struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        drm_i915_private_t *dev_priv = dev->dev_private;
        ssize_t remain;
        loff_t gtt_page_base, offset;
@@ -699,7 +699,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret)
                goto out_unpin_object;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = obj_priv->gtt_offset + args->offset;
 
        while (remain > 0) {
@@ -761,7 +761,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
                           struct drm_i915_gem_pwrite *args,
                           struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        ssize_t remain;
        loff_t offset, page_base;
        char __user *user_data;
@@ -781,7 +781,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
        obj_priv->dirty = 1;
 
@@ -829,7 +829,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
                           struct drm_i915_gem_pwrite *args,
                           struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct mm_struct *mm = current->mm;
        struct page **user_pages;
        ssize_t remain;
@@ -877,7 +877,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj,
        if (ret != 0)
                goto fail_put_pages;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        offset = args->offset;
        obj_priv->dirty = 1;
 
@@ -952,7 +952,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Bounds check destination.
         *
@@ -1034,7 +1034,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EBADF;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
 
@@ -1096,7 +1096,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
        DRM_INFO("%s: sw_finish %d (%p %zd)\n",
                 __func__, args->handle, obj, obj->size);
 #endif
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        /* Pinned buffers may be scanout, so flush the cache */
        if (obj_priv->pin_count)
@@ -1167,7 +1167,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        struct drm_gem_object *obj = vma->vm_private_data;
        struct drm_device *dev = obj->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        pgoff_t page_offset;
        unsigned long pfn;
        int ret = 0;
@@ -1234,7 +1234,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        struct drm_gem_mm *mm = dev->mm_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_map_list *list;
        struct drm_local_map *map;
        int ret = 0;
@@ -1305,7 +1305,7 @@ void
 i915_gem_release_mmap(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (dev->dev_mapping)
                unmap_mapping_range(dev->dev_mapping,
@@ -1316,7 +1316,7 @@ static void
 i915_gem_free_mmap_offset(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_gem_mm *mm = dev->mm_private;
        struct drm_map_list *list;
 
@@ -1347,7 +1347,7 @@ static uint32_t
 i915_gem_get_gtt_alignment(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int start, i;
 
        /*
@@ -1406,7 +1406,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 
        mutex_lock(&dev->struct_mutex);
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->madv != I915_MADV_WILLNEED) {
                DRM_ERROR("Attempting to mmap a purgeable buffer\n");
@@ -1450,7 +1450,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
 void
 i915_gem_object_put_pages(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size / PAGE_SIZE;
        int i;
 
@@ -1486,7 +1486,7 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        /* Add a reference if we're newly entering the active list. */
        if (!obj_priv->active) {
@@ -1506,7 +1506,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        BUG_ON(!obj_priv->active);
        list_move_tail(&obj_priv->list, &dev_priv->mm.flushing_list);
@@ -1517,7 +1517,7 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj)
 static void
 i915_gem_object_truncate(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct inode *inode;
 
        inode = obj->filp->f_path.dentry->d_inode;
@@ -1538,7 +1538,7 @@ i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
        if (obj_priv->pin_count != 0)
@@ -1965,7 +1965,7 @@ static int
 i915_gem_object_wait_rendering(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret;
 
        /* This function only exists to support waiting for existing rendering,
@@ -1997,7 +1997,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret = 0;
 
 #if WATCH_BUF
@@ -2173,7 +2173,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size)
 #if WATCH_LRU
                        DRM_INFO("%s: evicting %p\n", __func__, obj);
 #endif
-                       obj_priv = obj->driver_private;
+                       obj_priv = to_intel_bo(obj);
                        BUG_ON(obj_priv->pin_count != 0);
                        BUG_ON(obj_priv->active);
 
@@ -2244,7 +2244,7 @@ int
 i915_gem_object_get_pages(struct drm_gem_object *obj,
                          gfp_t gfpmask)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count, i;
        struct address_space *mapping;
        struct inode *inode;
@@ -2297,7 +2297,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint64_t val;
 
@@ -2319,7 +2319,7 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint64_t val;
 
@@ -2339,7 +2339,7 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        int tile_width;
        uint32_t fence_reg, val;
@@ -2381,7 +2381,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
        struct drm_gem_object *obj = reg->obj;
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int regnum = obj_priv->fence_reg;
        uint32_t val;
        uint32_t pitch_val;
@@ -2425,7 +2425,7 @@ static int i915_find_fence_reg(struct drm_device *dev)
                if (!reg->obj)
                        return i;
 
-               obj_priv = reg->obj->driver_private;
+               obj_priv = to_intel_bo(reg->obj);
                if (!obj_priv->pin_count)
                    avail++;
        }
@@ -2480,7 +2480,7 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_i915_fence_reg *reg = NULL;
        int ret;
 
@@ -2547,7 +2547,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (IS_GEN6(dev)) {
                I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 +
@@ -2583,7 +2583,7 @@ int
 i915_gem_object_put_fence_reg(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (obj_priv->fence_reg == I915_FENCE_REG_NONE)
                return 0;
@@ -2621,7 +2621,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        struct drm_mm_node *free_space;
        gfp_t gfpmask =  __GFP_NORETRY | __GFP_NOWARN;
        int ret;
@@ -2728,7 +2728,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
 void
 i915_gem_clflush_object(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object      *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object      *obj_priv = to_intel_bo(obj);
 
        /* If we don't have a page list set up, then we're not pinned
         * to GPU, and we can ignore the cache flush because it'll happen
@@ -2829,7 +2829,7 @@ i915_gem_object_flush_write_domain(struct drm_gem_object *obj)
 int
 i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
@@ -2879,7 +2879,7 @@ int
 i915_gem_object_set_to_display_plane(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_write_domain, old_read_domains;
        int ret;
 
@@ -3092,7 +3092,7 @@ static void
 i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 {
        struct drm_device               *dev = obj->dev;
-       struct drm_i915_gem_object      *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object      *obj_priv = to_intel_bo(obj);
        uint32_t                        invalidate_domains = 0;
        uint32_t                        flush_domains = 0;
        uint32_t                        old_read_domains;
@@ -3177,7 +3177,7 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
 static void
 i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (!obj_priv->page_cpu_valid)
                return;
@@ -3217,7 +3217,7 @@ static int
 i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
                                          uint64_t offset, uint64_t size)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        uint32_t old_read_domains;
        int i, ret;
 
@@ -3286,7 +3286,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int i, ret;
        void __iomem *reloc_page;
        bool need_fence;
@@ -3337,7 +3337,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
                        i915_gem_object_unpin(obj);
                        return -EBADF;
                }
-               target_obj_priv = target_obj->driver_private;
+               target_obj_priv = to_intel_bo(target_obj);
 
 #if WATCH_RELOC
                DRM_INFO("%s: obj %p offset %08x target %d "
@@ -3689,7 +3689,7 @@ i915_gem_wait_for_pending_flip(struct drm_device *dev,
                prepare_to_wait(&dev_priv->pending_flip_queue,
                                &wait, TASK_INTERRUPTIBLE);
                for (i = 0; i < count; i++) {
-                       obj_priv = object_list[i]->driver_private;
+                       obj_priv = to_intel_bo(object_list[i]);
                        if (atomic_read(&obj_priv->pending_flip) > 0)
                                break;
                }
@@ -3798,7 +3798,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                        goto err;
                }
 
-               obj_priv = object_list[i]->driver_private;
+               obj_priv = to_intel_bo(object_list[i]);
                if (obj_priv->in_execbuffer) {
                        DRM_ERROR("Object %p appears more than once in object list\n",
                                   object_list[i]);
@@ -3924,7 +3924,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 
        for (i = 0; i < args->buffer_count; i++) {
                struct drm_gem_object *obj = object_list[i];
-               struct drm_i915_gem_object *obj_priv = obj->driver_private;
+               struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
                uint32_t old_write_domain = obj->write_domain;
 
                obj->write_domain = obj->pending_write_domain;
@@ -3999,7 +3999,7 @@ err:
 
        for (i = 0; i < args->buffer_count; i++) {
                if (object_list[i]) {
-                       obj_priv = object_list[i]->driver_private;
+                       obj_priv = to_intel_bo(object_list[i]);
                        obj_priv->in_execbuffer = false;
                }
                drm_gem_object_unreference(object_list[i]);
@@ -4177,7 +4177,7 @@ int
 i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int ret;
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -4210,7 +4210,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        i915_verify_inactive(dev, __FILE__, __LINE__);
        obj_priv->pin_count--;
@@ -4250,7 +4250,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
                mutex_unlock(&dev->struct_mutex);
                return -EBADF;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->madv != I915_MADV_WILLNEED) {
                DRM_ERROR("Attempting to pin a purgeable buffer\n");
@@ -4307,7 +4307,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
                return -EBADF;
        }
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        if (obj_priv->pin_filp != file_priv) {
                DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
                          args->handle);
@@ -4349,7 +4349,7 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
         */
        i915_gem_retire_requests(dev);
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        /* Don't count being on the flushing list against the object being
         * done.  Otherwise, a buffer left on the flushing list but not getting
         * flushed (because nobody's flushing that domain) won't ever return
@@ -4395,7 +4395,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
        }
 
        mutex_lock(&dev->struct_mutex);
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->pin_count) {
                drm_gem_object_unreference(obj);
@@ -4456,7 +4456,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
 void i915_gem_free_object(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        trace_i915_gem_object_destroy(obj);
 
@@ -4565,7 +4565,7 @@ i915_gem_init_hws(struct drm_device *dev)
                DRM_ERROR("Failed to allocate status page\n");
                return -ENOMEM;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
 
        ret = i915_gem_object_pin(obj, 4096);
@@ -4609,7 +4609,7 @@ i915_gem_cleanup_hws(struct drm_device *dev)
                return;
 
        obj = dev_priv->hws_obj;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        kunmap(obj_priv->pages[0]);
        i915_gem_object_unpin(obj);
@@ -4643,7 +4643,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
                i915_gem_cleanup_hws(dev);
                return -ENOMEM;
        }
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        ret = i915_gem_object_pin(obj, 4096);
        if (ret != 0) {
@@ -4936,7 +4936,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
        int ret;
        int page_count;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        if (!obj_priv->phys_obj)
                return;
 
@@ -4975,7 +4975,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
        if (id > I915_MAX_PHYS_OBJECT)
                return -EINVAL;
 
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (obj_priv->phys_obj) {
                if (obj_priv->phys_obj->id == id)
@@ -5026,7 +5026,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
                     struct drm_i915_gem_pwrite *args,
                     struct drm_file *file_priv)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        void *obj_addr;
        int ret;
        char __user *user_data;
index e602614..35507cf 100644 (file)
@@ -72,7 +72,7 @@ void
 i915_gem_dump_object(struct drm_gem_object *obj, int len,
                     const char *where, uint32_t mark)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page;
 
        DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
@@ -137,7 +137,7 @@ void
 i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page;
        uint32_t *gtt_mapping;
        uint32_t *backing_map = NULL;
index c01c878..449157f 100644 (file)
@@ -240,7 +240,7 @@ bool
 i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode)
 {
        struct drm_device *dev = obj->dev;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
 
        if (obj_priv->gtt_space == NULL)
                return true;
@@ -280,7 +280,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) {
                drm_gem_object_unreference_unlocked(obj);
@@ -364,7 +364,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data,
        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
        if (obj == NULL)
                return -EINVAL;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
 
@@ -427,7 +427,7 @@ i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;
 
@@ -456,7 +456,7 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj)
 {
        struct drm_device *dev = obj->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        int page_count = obj->size >> PAGE_SHIFT;
        int i;
 
index 49c458b..6421481 100644 (file)
@@ -260,10 +260,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
 
        if (mode_config->num_connector) {
                list_for_each_entry(connector, &mode_config->connector_list, head) {
-                       struct intel_output *intel_output = to_intel_output(connector);
+                       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        
-                       if (intel_output->hot_plug)
-                               (*intel_output->hot_plug) (intel_output);
+                       if (intel_encoder->hot_plug)
+                               (*intel_encoder->hot_plug) (intel_encoder);
                }
        }
        /* Just fire off a uevent and let userspace tell us what to do */
@@ -444,7 +444,7 @@ i915_error_object_create(struct drm_device *dev,
        if (src == NULL)
                return NULL;
 
-       src_priv = src->driver_private;
+       src_priv = to_intel_bo(src);
        if (src_priv->pages == NULL)
                return NULL;
 
index 38110ce..759c2ef 100644 (file)
@@ -247,19 +247,19 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
 
 static bool intel_crt_detect_ddc(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        /* CRT should always be at 0, but check anyway */
-       if (intel_output->type != INTEL_OUTPUT_ANALOG)
+       if (intel_encoder->type != INTEL_OUTPUT_ANALOG)
                return false;
 
-       return intel_ddc_probe(intel_output);
+       return intel_ddc_probe(intel_encoder);
 }
 
 static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -387,8 +387,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_output *intel_output)
 static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc;
        int dpms_mode;
        enum drm_connector_status status;
@@ -405,13 +405,13 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
 
        /* for pre-945g platforms use load detect */
        if (encoder->crtc && encoder->crtc->enabled) {
-               status = intel_crt_load_detect(encoder->crtc, intel_output);
+               status = intel_crt_load_detect(encoder->crtc, intel_encoder);
        } else {
-               crtc = intel_get_load_detect_pipe(intel_output,
+               crtc = intel_get_load_detect_pipe(intel_encoder,
                                                  NULL, &dpms_mode);
                if (crtc) {
-                       status = intel_crt_load_detect(crtc, intel_output);
-                       intel_release_load_detect_pipe(intel_output, dpms_mode);
+                       status = intel_crt_load_detect(crtc, intel_encoder);
+                       intel_release_load_detect_pipe(intel_encoder, dpms_mode);
                } else
                        status = connector_status_unknown;
        }
@@ -421,9 +421,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
 
 static void intel_crt_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       intel_i2c_destroy(intel_output->ddc_bus);
+       intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
        kfree(connector);
@@ -432,28 +432,28 @@ static void intel_crt_destroy(struct drm_connector *connector)
 static int intel_crt_get_modes(struct drm_connector *connector)
 {
        int ret;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct i2c_adapter *ddcbus;
        struct drm_device *dev = connector->dev;
 
 
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        if (ret || !IS_G4X(dev))
                goto end;
 
-       ddcbus = intel_output->ddc_bus;
+       ddcbus = intel_encoder->ddc_bus;
        /* Try to probe digital port for output in DVI-I -> VGA mode. */
-       intel_output->ddc_bus =
+       intel_encoder->ddc_bus =
                intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D");
 
-       if (!intel_output->ddc_bus) {
-               intel_output->ddc_bus = ddcbus;
+       if (!intel_encoder->ddc_bus) {
+               intel_encoder->ddc_bus = ddcbus;
                dev_printk(KERN_ERR, &connector->dev->pdev->dev,
                           "DDC bus registration failed for CRTDDC_D.\n");
                goto end;
        }
        /* Try to get modes by GPIOD port */
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        intel_i2c_destroy(ddcbus);
 
 end:
@@ -506,23 +506,23 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {
 void intel_crt_init(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 i2c_reg;
 
-       intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
-       if (!intel_output)
+       intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL);
+       if (!intel_encoder)
                return;
 
-       connector = &intel_output->base;
-       drm_connector_init(dev, &intel_output->base,
+       connector = &intel_encoder->base;
+       drm_connector_init(dev, &intel_encoder->base,
                           &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_crt_enc_funcs,
                         DRM_MODE_ENCODER_DAC);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
 
        /* Set up the DDC bus. */
        if (HAS_PCH_SPLIT(dev))
@@ -533,22 +533,22 @@ void intel_crt_init(struct drm_device *dev)
                if (dev_priv->crt_ddc_bus != 0)
                        i2c_reg = dev_priv->crt_ddc_bus;
        }
-       intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
-       if (!intel_output->ddc_bus) {
+       intel_encoder->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
+       if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
                return;
        }
 
-       intel_output->type = INTEL_OUTPUT_ANALOG;
-       intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+       intel_encoder->type = INTEL_OUTPUT_ANALOG;
+       intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                   (1 << INTEL_ANALOG_CLONE_BIT) |
                                   (1 << INTEL_SDVO_LVDS_CLONE_BIT);
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs);
        drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
 
        drm_sysfs_connector_add(connector);
index e7e753b..e7356fb 100644 (file)
@@ -747,16 +747,16 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
     list_for_each_entry(l_entry, &mode_config->connector_list, head) {
            if (l_entry->encoder &&
                l_entry->encoder->crtc == crtc) {
-                   struct intel_output *intel_output = to_intel_output(l_entry);
-                   if (intel_output->type == type)
+                   struct intel_encoder *intel_encoder = to_intel_encoder(l_entry);
+                   if (intel_encoder->type == type)
                            return true;
            }
     }
     return false;
 }
 
-struct drm_connector *
-intel_pipe_get_output (struct drm_crtc *crtc)
+static struct drm_connector *
+intel_pipe_get_connector (struct drm_crtc *crtc)
 {
     struct drm_device *dev = crtc->dev;
     struct drm_mode_config *mode_config = &dev->mode_config;
@@ -1003,7 +1003,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_framebuffer *fb = crtc->fb;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int plane, i;
        u32 fbc_ctl, fbc_ctl2;
@@ -1080,7 +1080,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_framebuffer *fb = crtc->fb;
        struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-       struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA :
                     DPFC_CTL_PLANEB);
@@ -1176,7 +1176,7 @@ static void intel_update_fbc(struct drm_crtc *crtc,
                return;
 
        intel_fb = to_intel_framebuffer(fb);
-       obj_priv = intel_fb->obj->driver_private;
+       obj_priv = to_intel_bo(intel_fb->obj);
 
        /*
         * If FBC is already on, we just have to verify that we can
@@ -1243,7 +1243,7 @@ out_disable:
 static int
 intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
 {
-       struct drm_i915_gem_object *obj_priv = obj->driver_private;
+       struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
        u32 alignment;
        int ret;
 
@@ -1323,7 +1323,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
        intel_fb = to_intel_framebuffer(crtc->fb);
        obj = intel_fb->obj;
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
 
        mutex_lock(&dev->struct_mutex);
        ret = intel_pin_and_fence_fb_obj(dev, obj);
@@ -1401,7 +1401,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 
        if (old_fb) {
                intel_fb = to_intel_framebuffer(old_fb);
-               obj_priv = intel_fb->obj->driver_private;
+               obj_priv = to_intel_bo(intel_fb->obj);
                i915_gem_object_unpin(intel_fb->obj);
        }
        intel_increase_pllclock(crtc, true);
@@ -2917,7 +2917,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE;
        int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS;
        int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
-       int refclk, num_outputs = 0;
+       int refclk, num_connectors = 0;
        intel_clock_t clock, reduced_clock;
        u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf;
        bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
@@ -2943,19 +2943,19 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        drm_vblank_pre_modeset(dev, pipe);
 
        list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
                if (!connector->encoder || connector->encoder->crtc != crtc)
                        continue;
 
-               switch (intel_output->type) {
+               switch (intel_encoder->type) {
                case INTEL_OUTPUT_LVDS:
                        is_lvds = true;
                        break;
                case INTEL_OUTPUT_SDVO:
                case INTEL_OUTPUT_HDMI:
                        is_sdvo = true;
-                       if (intel_output->needs_tv_clock)
+                       if (intel_encoder->needs_tv_clock)
                                is_tv = true;
                        break;
                case INTEL_OUTPUT_DVO:
@@ -2975,10 +2975,10 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                        break;
                }
 
-               num_outputs++;
+               num_connectors++;
        }
 
-       if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+       if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) {
                refclk = dev_priv->lvds_ssc_freq * 1000;
                DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
                                        refclk / 1000);
@@ -3049,8 +3049,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                if (is_edp) {
                        struct drm_connector *edp;
                        target_clock = mode->clock;
-                       edp = intel_pipe_get_output(crtc);
-                       intel_edp_link_config(to_intel_output(edp),
+                       edp = intel_pipe_get_connector(crtc);
+                       intel_edp_link_config(to_intel_encoder(edp),
                                        &lane, &link_bw);
                } else {
                        /* DP over FDI requires target mode clock
@@ -3231,7 +3231,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                /* XXX: just matching BIOS for now */
                /*      dpll |= PLL_REF_INPUT_TVCLKINBC; */
                dpll |= 3;
-       else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+       else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2)
                dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
        else
                dpll |= PLL_REF_INPUT_DREFCLK;
@@ -3511,7 +3511,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        if (!bo)
                return -ENOENT;
 
-       obj_priv = bo->driver_private;
+       obj_priv = to_intel_bo(bo);
 
        if (bo->size < width * height * 4) {
                DRM_ERROR("buffer is to small\n");
@@ -3655,9 +3655,9 @@ static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
  * detection.
  *
  * It will be up to the load-detect code to adjust the pipe as appropriate for
- * its requirements.  The pipe will be connected to no other outputs.
+ * its requirements.  The pipe will be connected to no other encoders.
  *
- * Currently this code will only succeed if there is a pipe with no outputs
+ * Currently this code will only succeed if there is a pipe with no encoders
  * configured for it.  In the future, it could choose to temporarily disable
  * some outputs to free up a pipe for its use.
  *
@@ -3670,14 +3670,14 @@ static struct drm_display_mode load_detect_mode = {
                 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
 };
 
-struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
                                            struct drm_display_mode *mode,
                                            int *dpms_mode)
 {
        struct intel_crtc *intel_crtc;
        struct drm_crtc *possible_crtc;
        struct drm_crtc *supported_crtc =NULL;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = NULL;
        struct drm_device *dev = encoder->dev;
        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
@@ -3729,8 +3729,8 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
        }
 
        encoder->crtc = crtc;
-       intel_output->base.encoder = encoder;
-       intel_output->load_detect_temp = true;
+       intel_encoder->base.encoder = encoder;
+       intel_encoder->load_detect_temp = true;
 
        intel_crtc = to_intel_crtc(crtc);
        *dpms_mode = intel_crtc->dpms_mode;
@@ -3755,23 +3755,23 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
        return crtc;
 }
 
-void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
+void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder, int dpms_mode)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_crtc *crtc = encoder->crtc;
        struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
-       if (intel_output->load_detect_temp) {
+       if (intel_encoder->load_detect_temp) {
                encoder->crtc = NULL;
-               intel_output->base.encoder = NULL;
-               intel_output->load_detect_temp = false;
+               intel_encoder->base.encoder = NULL;
+               intel_encoder->load_detect_temp = false;
                crtc->enabled = drm_helper_crtc_in_use(crtc);
                drm_helper_disable_unused_functions(dev);
        }
 
-       /* Switch crtc and output back off if necessary */
+       /* Switch crtc and encoder back off if necessary */
        if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
                if (encoder->crtc == crtc)
                        encoder_funcs->dpms(encoder, dpms_mode);
@@ -4156,7 +4156,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
        work = intel_crtc->unpin_work;
        if (work == NULL || !work->pending) {
                if (work && !work->pending) {
-                       obj_priv = work->pending_flip_obj->driver_private;
+                       obj_priv = to_intel_bo(work->pending_flip_obj);
                        DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
                                         obj_priv,
                                         atomic_read(&obj_priv->pending_flip));
@@ -4181,7 +4181,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
 
        spin_unlock_irqrestore(&dev->event_lock, flags);
 
-       obj_priv = work->pending_flip_obj->driver_private;
+       obj_priv = to_intel_bo(work->pending_flip_obj);
 
        /* Initial scanout buffer will have a 0 pending flip count */
        if ((atomic_read(&obj_priv->pending_flip) == 0) ||
@@ -4252,7 +4252,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        ret = intel_pin_and_fence_fb_obj(dev, obj);
        if (ret != 0) {
                DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
-                         obj->driver_private);
+                         to_intel_bo(obj));
                kfree(work);
                intel_crtc->unpin_work = NULL;
                mutex_unlock(&dev->struct_mutex);
@@ -4266,7 +4266,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        crtc->fb = fb;
        i915_gem_object_flush_write_domain(obj);
        drm_vblank_get(dev, intel_crtc->pipe);
-       obj_priv = obj->driver_private;
+       obj_priv = to_intel_bo(obj);
        atomic_inc(&obj_priv->pending_flip);
        work->pending_flip_obj = obj;
 
@@ -4399,8 +4399,8 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
        int entry = 0;
 
         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               if (type_mask & intel_output->clone_mask)
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               if (type_mask & intel_encoder->clone_mask)
                        index_mask |= (1 << entry);
                entry++;
        }
@@ -4495,12 +4495,12 @@ static void intel_setup_outputs(struct drm_device *dev)
                intel_tv_init(dev);
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               struct drm_encoder *encoder = &intel_output->enc;
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               struct drm_encoder *encoder = &intel_encoder->enc;
 
-               encoder->possible_crtcs = intel_output->crtc_mask;
+               encoder->possible_crtcs = intel_encoder->crtc_mask;
                encoder->possible_clones = intel_connector_clones(dev,
-                                               intel_output->clone_mask);
+                                               intel_encoder->clone_mask);
        }
 }
 
@@ -4779,14 +4779,14 @@ void intel_init_clock_gating(struct drm_device *dev)
                struct drm_i915_gem_object *obj_priv = NULL;
 
                if (dev_priv->pwrctx) {
-                       obj_priv = dev_priv->pwrctx->driver_private;
+                       obj_priv = to_intel_bo(dev_priv->pwrctx);
                } else {
                        struct drm_gem_object *pwrctx;
 
                        pwrctx = intel_alloc_power_context(dev);
                        if (pwrctx) {
                                dev_priv->pwrctx = pwrctx;
-                               obj_priv = pwrctx->driver_private;
+                               obj_priv = to_intel_bo(pwrctx);
                        }
                }
 
@@ -4815,7 +4815,7 @@ static void intel_init_display(struct drm_device *dev)
                        dev_priv->display.fbc_enabled = g4x_fbc_enabled;
                        dev_priv->display.enable_fbc = g4x_enable_fbc;
                        dev_priv->display.disable_fbc = g4x_disable_fbc;
-               } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) {
+               } else if (IS_I965GM(dev)) {
                        dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
                        dev_priv->display.enable_fbc = i8xx_enable_fbc;
                        dev_priv->display.disable_fbc = i8xx_disable_fbc;
@@ -4957,7 +4957,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
        if (dev_priv->pwrctx) {
                struct drm_i915_gem_object *obj_priv;
 
-               obj_priv = dev_priv->pwrctx->driver_private;
+               obj_priv = to_intel_bo(dev_priv->pwrctx);
                I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN);
                I915_READ(PWRCTXA);
                i915_gem_object_unpin(dev_priv->pwrctx);
@@ -4978,9 +4978,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
 */
 struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       return &intel_output->enc;
+       return &intel_encoder->enc;
 }
 
 /*
index 8e283f7..77e40cf 100644 (file)
@@ -55,23 +55,23 @@ struct intel_dp_priv {
        uint8_t link_bw;
        uint8_t lane_count;
        uint8_t dpcd[4];
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct i2c_adapter adapter;
        struct i2c_algo_dp_aux_data algo;
 };
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
                    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]);
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP);
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP);
 
 void
-intel_edp_link_config (struct intel_output *intel_output,
+intel_edp_link_config (struct intel_encoder *intel_encoder,
                int *lane_num, int *link_bw)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
        *lane_num = dp_priv->lane_count;
        if (dp_priv->link_bw == DP_LINK_BW_1_62)
@@ -81,9 +81,9 @@ intel_edp_link_config (struct intel_output *intel_output,
 }
 
 static int
-intel_dp_max_lane_count(struct intel_output *intel_output)
+intel_dp_max_lane_count(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int max_lane_count = 4;
 
        if (dp_priv->dpcd[0] >= 0x11) {
@@ -99,9 +99,9 @@ intel_dp_max_lane_count(struct intel_output *intel_output)
 }
 
 static int
-intel_dp_max_link_bw(struct intel_output *intel_output)
+intel_dp_max_link_bw(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int max_link_bw = dp_priv->dpcd[1];
 
        switch (max_link_bw) {
@@ -127,11 +127,11 @@ intel_dp_link_clock(uint8_t link_bw)
 /* I think this is a fiction */
 static int
 intel_dp_link_required(struct drm_device *dev,
-                      struct intel_output *intel_output, int pixel_clock)
+                      struct intel_encoder *intel_encoder, int pixel_clock)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                return (pixel_clock * dev_priv->edp_bpp) / 8;
        else
                return pixel_clock * 3;
@@ -141,11 +141,11 @@ static int
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
-       int max_lanes = intel_dp_max_lane_count(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder));
+       int max_lanes = intel_dp_max_lane_count(intel_encoder);
 
-       if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
+       if (intel_dp_link_required(connector->dev, intel_encoder, mode->clock)
                        > max_link_clock * max_lanes)
                return MODE_CLOCK_HIGH;
 
@@ -209,13 +209,13 @@ intel_hrawclk(struct drm_device *dev)
 }
 
 static int
-intel_dp_aux_ch(struct intel_output *intel_output,
+intel_dp_aux_ch(struct intel_encoder *intel_encoder,
                uint8_t *send, int send_bytes,
                uint8_t *recv, int recv_size)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint32_t output_reg = dp_priv->output_reg;
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t ch_ctl = output_reg + 0x10;
        uint32_t ch_data = ch_ctl + 4;
@@ -230,7 +230,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
         * and would like to run at 2MHz. So, take the
         * hrawclk value and divide by 2 and use that
         */
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                aux_clock_divider = 225; /* eDP input clock at 450Mhz */
        else if (HAS_PCH_SPLIT(dev))
                aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */
@@ -313,7 +313,7 @@ intel_dp_aux_ch(struct intel_output *intel_output,
 
 /* Write data to the aux channel in native mode */
 static int
-intel_dp_aux_native_write(struct intel_output *intel_output,
+intel_dp_aux_native_write(struct intel_encoder *intel_encoder,
                          uint16_t address, uint8_t *send, int send_bytes)
 {
        int ret;
@@ -330,7 +330,7 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
        memcpy(&msg[4], send, send_bytes);
        msg_bytes = send_bytes + 4;
        for (;;) {
-               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1);
+               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1);
                if (ret < 0)
                        return ret;
                if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
@@ -345,15 +345,15 @@ intel_dp_aux_native_write(struct intel_output *intel_output,
 
 /* Write a single byte to the aux channel in native mode */
 static int
-intel_dp_aux_native_write_1(struct intel_output *intel_output,
+intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder,
                            uint16_t address, uint8_t byte)
 {
-       return intel_dp_aux_native_write(intel_output, address, &byte, 1);
+       return intel_dp_aux_native_write(intel_encoder, address, &byte, 1);
 }
 
 /* read bytes from a native aux channel */
 static int
-intel_dp_aux_native_read(struct intel_output *intel_output,
+intel_dp_aux_native_read(struct intel_encoder *intel_encoder,
                         uint16_t address, uint8_t *recv, int recv_bytes)
 {
        uint8_t msg[4];
@@ -372,7 +372,7 @@ intel_dp_aux_native_read(struct intel_output *intel_output,
        reply_bytes = recv_bytes + 1;
 
        for (;;) {
-               ret = intel_dp_aux_ch(intel_output, msg, msg_bytes,
+               ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes,
                                      reply, reply_bytes);
                if (ret == 0)
                        return -EPROTO;
@@ -398,7 +398,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
        struct intel_dp_priv *dp_priv = container_of(adapter,
                                                     struct intel_dp_priv,
                                                     adapter);
-       struct intel_output *intel_output = dp_priv->intel_output;
+       struct intel_encoder *intel_encoder = dp_priv->intel_encoder;
        uint16_t address = algo_data->address;
        uint8_t msg[5];
        uint8_t reply[2];
@@ -437,7 +437,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
        }
 
        for (;;) {
-         ret = intel_dp_aux_ch(intel_output,
+         ret = intel_dp_aux_ch(intel_encoder,
                                msg, msg_bytes,
                                reply, reply_bytes);
                if (ret < 0) {
@@ -465,9 +465,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
 }
 
 static int
-intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
+intel_dp_i2c_init(struct intel_encoder *intel_encoder, const char *name)
 {
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
 
        DRM_DEBUG_KMS("i2c_init %s\n", name);
        dp_priv->algo.running = false;
@@ -480,7 +480,7 @@ intel_dp_i2c_init(struct intel_output *intel_output, const char *name)
        strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1);
        dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0';
        dp_priv->adapter.algo_data = &dp_priv->algo;
-       dp_priv->adapter.dev.parent = &intel_output->base.kdev;
+       dp_priv->adapter.dev.parent = &intel_encoder->base.kdev;
        
        return i2c_dp_aux_add_bus(&dp_priv->adapter);
 }
@@ -489,18 +489,18 @@ static bool
 intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                    struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv   *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv   *dp_priv = intel_encoder->dev_priv;
        int lane_count, clock;
-       int max_lane_count = intel_dp_max_lane_count(intel_output);
-       int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0;
+       int max_lane_count = intel_dp_max_lane_count(intel_encoder);
+       int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0;
        static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };
 
        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
                for (clock = 0; clock <= max_clock; clock++) {
                        int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
 
-                       if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
+                       if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock)
                                        <= link_avail) {
                                dp_priv->link_bw = bws[clock];
                                dp_priv->lane_count = lane_count;
@@ -562,16 +562,16 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
        struct intel_dp_m_n m_n;
 
        /*
-        * Find the lane count in the intel_output private
+        * Find the lane count in the intel_encoder private
         */
        list_for_each_entry(connector, &mode_config->connector_list, head) {
-               struct intel_output *intel_output = to_intel_output(connector);
-               struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+               struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+               struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
                if (!connector->encoder || connector->encoder->crtc != crtc)
                        continue;
 
-               if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) {
+               if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
                        lane_count = dp_priv->lane_count;
                        break;
                }
@@ -626,9 +626,9 @@ static void
 intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                  struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-       struct drm_crtc *crtc = intel_output->enc.crtc;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+       struct drm_crtc *crtc = intel_encoder->enc.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
        dp_priv->DP = (DP_LINK_TRAIN_OFF |
@@ -667,7 +667,7 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        if (intel_crtc->pipe == 1)
                dp_priv->DP |= DP_PIPEB_SELECT;
 
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                /* don't miss out required setting for eDP */
                dp_priv->DP |= DP_PLL_ENABLE;
                if (adjusted_mode->clock < 200000)
@@ -702,22 +702,22 @@ static void ironlake_edp_backlight_off (struct drm_device *dev)
 static void
 intel_dp_dpms(struct drm_encoder *encoder, int mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        uint32_t dp_reg = I915_READ(dp_priv->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
                if (dp_reg & DP_PORT_EN) {
-                       intel_dp_link_down(intel_output, dp_priv->DP);
-                       if (IS_eDP(intel_output))
+                       intel_dp_link_down(intel_encoder, dp_priv->DP);
+                       if (IS_eDP(intel_encoder))
                                ironlake_edp_backlight_off(dev);
                }
        } else {
                if (!(dp_reg & DP_PORT_EN)) {
-                       intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
-                       if (IS_eDP(intel_output))
+                       intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
+                       if (IS_eDP(intel_encoder))
                                ironlake_edp_backlight_on(dev);
                }
        }
@@ -729,12 +729,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
  * link status information
  */
 static bool
-intel_dp_get_link_status(struct intel_output *intel_output,
+intel_dp_get_link_status(struct intel_encoder *intel_encoder,
                         uint8_t link_status[DP_LINK_STATUS_SIZE])
 {
        int ret;
 
-       ret = intel_dp_aux_native_read(intel_output,
+       ret = intel_dp_aux_native_read(intel_encoder,
                                       DP_LANE0_1_STATUS,
                                       link_status, DP_LINK_STATUS_SIZE);
        if (ret != DP_LINK_STATUS_SIZE)
@@ -752,13 +752,13 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE],
 static void
 intel_dp_save(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        dp_priv->save_DP = I915_READ(dp_priv->output_reg);
-       intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET,
+       intel_dp_aux_native_read(intel_encoder, DP_LINK_BW_SET,
                                 dp_priv->save_link_configuration,
                                 sizeof (dp_priv->save_link_configuration));
 }
@@ -825,7 +825,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing)
 }
 
 static void
-intel_get_adjust_train(struct intel_output *intel_output,
+intel_get_adjust_train(struct intel_encoder *intel_encoder,
                       uint8_t link_status[DP_LINK_STATUS_SIZE],
                       int lane_count,
                       uint8_t train_set[4])
@@ -942,15 +942,15 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count)
 }
 
 static bool
-intel_dp_set_link_train(struct intel_output *intel_output,
+intel_dp_set_link_train(struct intel_encoder *intel_encoder,
                        uint32_t dp_reg_value,
                        uint8_t dp_train_pat,
                        uint8_t train_set[4],
                        bool first)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        int ret;
 
        I915_WRITE(dp_priv->output_reg, dp_reg_value);
@@ -958,11 +958,11 @@ intel_dp_set_link_train(struct intel_output *intel_output,
        if (first)
                intel_wait_for_vblank(dev);
 
-       intel_dp_aux_native_write_1(intel_output,
+       intel_dp_aux_native_write_1(intel_encoder,
                                    DP_TRAINING_PATTERN_SET,
                                    dp_train_pat);
 
-       ret = intel_dp_aux_native_write(intel_output,
+       ret = intel_dp_aux_native_write(intel_encoder,
                                        DP_TRAINING_LANE0_SET, train_set, 4);
        if (ret != 4)
                return false;
@@ -971,12 +971,12 @@ intel_dp_set_link_train(struct intel_output *intel_output,
 }
 
 static void
-intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
+intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP,
                    uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE])
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint8_t train_set[4];
        uint8_t link_status[DP_LINK_STATUS_SIZE];
        int i;
@@ -987,7 +987,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
        int tries;
 
        /* Write the link configuration data */
-       intel_dp_aux_native_write(intel_output, 0x100,
+       intel_dp_aux_native_write(intel_encoder, 0x100,
                                  link_configuration, DP_LINK_CONFIGURATION_SIZE);
 
        DP |= DP_PORT_EN;
@@ -1001,14 +1001,14 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                uint32_t    signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count);
                DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
-               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1,
+               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_1,
                                             DP_TRAINING_PATTERN_1, train_set, first))
                        break;
                first = false;
                /* Set training pattern 1 */
 
                udelay(100);
-               if (!intel_dp_get_link_status(intel_output, link_status))
+               if (!intel_dp_get_link_status(intel_encoder, link_status))
                        break;
 
                if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) {
@@ -1033,7 +1033,7 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
                /* Compute new train_set as requested by target */
-               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
        }
 
        /* channel equalization */
@@ -1045,13 +1045,13 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels;
 
                /* channel eq pattern */
-               if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2,
+               if (!intel_dp_set_link_train(intel_encoder, DP | DP_LINK_TRAIN_PAT_2,
                                             DP_TRAINING_PATTERN_2, train_set,
                                             false))
                        break;
 
                udelay(400);
-               if (!intel_dp_get_link_status(intel_output, link_status))
+               if (!intel_dp_get_link_status(intel_encoder, link_status))
                        break;
 
                if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) {
@@ -1064,26 +1064,26 @@ intel_dp_link_train(struct intel_output *intel_output, uint32_t DP,
                        break;
 
                /* Compute new train_set as requested by target */
-               intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set);
+               intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set);
                ++tries;
        }
 
        I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF);
        POSTING_READ(dp_priv->output_reg);
-       intel_dp_aux_native_write_1(intel_output,
+       intel_dp_aux_native_write_1(intel_encoder,
                                    DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE);
 }
 
 static void
-intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
+intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        DRM_DEBUG_KMS("\n");
 
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                DP &= ~DP_PLL_ENABLE;
                I915_WRITE(dp_priv->output_reg, DP);
                POSTING_READ(dp_priv->output_reg);
@@ -1096,7 +1096,7 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
 
        udelay(17000);
 
-       if (IS_eDP(intel_output))
+       if (IS_eDP(intel_encoder))
                DP |= DP_LINK_TRAIN_OFF;
        I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN);
        POSTING_READ(dp_priv->output_reg);
@@ -1105,13 +1105,13 @@ intel_dp_link_down(struct intel_output *intel_output, uint32_t DP)
 static void
 intel_dp_restore(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        if (dp_priv->save_DP & DP_PORT_EN)
-               intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration);
+               intel_dp_link_train(intel_encoder, dp_priv->save_DP, dp_priv->save_link_configuration);
        else
-               intel_dp_link_down(intel_output,  dp_priv->save_DP);
+               intel_dp_link_down(intel_encoder,  dp_priv->save_DP);
 }
 
 /*
@@ -1124,32 +1124,32 @@ intel_dp_restore(struct drm_connector *connector)
  */
 
 static void
-intel_dp_check_link_status(struct intel_output *intel_output)
+intel_dp_check_link_status(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint8_t link_status[DP_LINK_STATUS_SIZE];
 
-       if (!intel_output->enc.crtc)
+       if (!intel_encoder->enc.crtc)
                return;
 
-       if (!intel_dp_get_link_status(intel_output, link_status)) {
-               intel_dp_link_down(intel_output, dp_priv->DP);
+       if (!intel_dp_get_link_status(intel_encoder, link_status)) {
+               intel_dp_link_down(intel_encoder, dp_priv->DP);
                return;
        }
 
        if (!intel_channel_eq_ok(link_status, dp_priv->lane_count))
-               intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration);
+               intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
 }
 
 static enum drm_connector_status
 ironlake_dp_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        enum drm_connector_status status;
 
        status = connector_status_disconnected;
-       if (intel_dp_aux_native_read(intel_output,
+       if (intel_dp_aux_native_read(intel_encoder,
                                     0x000, dp_priv->dpcd,
                                     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
        {
@@ -1168,10 +1168,10 @@ ironlake_dp_detect(struct drm_connector *connector)
 static enum drm_connector_status
 intel_dp_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
        uint32_t temp, bit;
        enum drm_connector_status status;
 
@@ -1210,7 +1210,7 @@ intel_dp_detect(struct drm_connector *connector)
                return connector_status_disconnected;
 
        status = connector_status_disconnected;
-       if (intel_dp_aux_native_read(intel_output,
+       if (intel_dp_aux_native_read(intel_encoder,
                                     0x000, dp_priv->dpcd,
                                     sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd))
        {
@@ -1222,20 +1222,20 @@ intel_dp_detect(struct drm_connector *connector)
 
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct drm_device *dev = intel_output->base.dev;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
 
        /* We should parse the EDID data and find out if it has an audio sink
         */
 
-       ret = intel_ddc_get_modes(intel_output);
+       ret = intel_ddc_get_modes(intel_encoder);
        if (ret)
                return ret;
 
        /* if eDP has no EDID, try to use fixed panel mode from VBT */
-       if (IS_eDP(intel_output)) {
+       if (IS_eDP(intel_encoder)) {
                if (dev_priv->panel_fixed_mode != NULL) {
                        struct drm_display_mode *mode;
                        mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
@@ -1249,13 +1249,13 @@ static int intel_dp_get_modes(struct drm_connector *connector)
 static void
 intel_dp_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = {
@@ -1291,12 +1291,12 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = {
 };
 
 void
-intel_dp_hot_plug(struct intel_output *intel_output)
+intel_dp_hot_plug(struct intel_encoder *intel_encoder)
 {
-       struct intel_dp_priv *dp_priv = intel_output->dev_priv;
+       struct intel_dp_priv *dp_priv = intel_encoder->dev_priv;
 
        if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON)
-               intel_dp_check_link_status(intel_output);
+               intel_dp_check_link_status(intel_encoder);
 }
 
 void
@@ -1304,53 +1304,53 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_dp_priv *dp_priv;
        const char *name = NULL;
 
-       intel_output = kcalloc(sizeof(struct intel_output) + 
+       intel_encoder = kcalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_dp_priv), 1, GFP_KERNEL);
-       if (!intel_output)
+       if (!intel_encoder)
                return;
 
-       dp_priv = (struct intel_dp_priv *)(intel_output + 1);
+       dp_priv = (struct intel_dp_priv *)(intel_encoder + 1);
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_dp_connector_funcs,
                           DRM_MODE_CONNECTOR_DisplayPort);
        drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
 
        if (output_reg == DP_A)
-               intel_output->type = INTEL_OUTPUT_EDP;
+               intel_encoder->type = INTEL_OUTPUT_EDP;
        else
-               intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
+               intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
 
        if (output_reg == DP_B || output_reg == PCH_DP_B)
-               intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
        else if (output_reg == DP_C || output_reg == PCH_DP_C)
-               intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
        else if (output_reg == DP_D || output_reg == PCH_DP_D)
-               intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
+               intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
 
-       if (IS_eDP(intel_output))
-               intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
+       if (IS_eDP(intel_encoder))
+               intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
 
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
        connector->interlace_allowed = true;
        connector->doublescan_allowed = 0;
 
-       dp_priv->intel_output = intel_output;
+       dp_priv->intel_encoder = intel_encoder;
        dp_priv->output_reg = output_reg;
        dp_priv->has_audio = false;
        dp_priv->dpms_mode = DRM_MODE_DPMS_ON;
-       intel_output->dev_priv = dp_priv;
+       intel_encoder->dev_priv = dp_priv;
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs,
                         DRM_MODE_ENCODER_TMDS);
-       drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_dp_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
        drm_sysfs_connector_add(connector);
 
        /* Set up the DDC bus. */
@@ -1378,10 +1378,10 @@ intel_dp_init(struct drm_device *dev, int output_reg)
                        break;
        }
 
-       intel_dp_i2c_init(intel_output, name);
+       intel_dp_i2c_init(intel_encoder, name);
 
-       intel_output->ddc_bus = &dp_priv->adapter;
-       intel_output->hot_plug = intel_dp_hot_plug;
+       intel_encoder->ddc_bus = &dp_priv->adapter;
+       intel_encoder->hot_plug = intel_dp_hot_plug;
 
        if (output_reg == DP_A) {
                /* initialize panel mode from VBT if available for eDP */
index 3a467ca..e302537 100644 (file)
@@ -95,7 +95,7 @@ struct intel_framebuffer {
 };
 
 
-struct intel_output {
+struct intel_encoder {
        struct drm_connector base;
 
        struct drm_encoder enc;
@@ -105,7 +105,7 @@ struct intel_output {
        bool load_detect_temp;
        bool needs_tv_clock;
        void *dev_priv;
-       void (*hot_plug)(struct intel_output *);
+       void (*hot_plug)(struct intel_encoder *);
        int crtc_mask;
        int clone_mask;
 };
@@ -152,15 +152,15 @@ struct intel_crtc {
 };
 
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
-#define to_intel_output(x) container_of(x, struct intel_output, base)
-#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
+#define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
+#define enc_to_intel_encoder(x) container_of(x, struct intel_encoder, enc)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
 
 struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg,
                                     const char *name);
 void intel_i2c_destroy(struct i2c_adapter *adapter);
-int intel_ddc_get_modes(struct intel_output *intel_output);
-extern bool intel_ddc_probe(struct intel_output *intel_output);
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder);
+extern bool intel_ddc_probe(struct intel_encoder *intel_encoder);
 void intel_i2c_quirk_set(struct drm_device *dev, bool enable);
 void intel_i2c_reset_gmbus(struct drm_device *dev);
 
@@ -175,7 +175,7 @@ extern void intel_dp_init(struct drm_device *dev, int dp_reg);
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
                 struct drm_display_mode *adjusted_mode);
-extern void intel_edp_link_config (struct intel_output *, int *, int *);
+extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 
 
 extern int intel_panel_fitter_pipe (struct drm_device *dev);
@@ -191,10 +191,10 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
 extern void intel_wait_for_vblank(struct drm_device *dev);
 extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
-extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
+extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
                                                   struct drm_display_mode *mode,
                                                   int *dpms_mode);
-extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
+extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
                                           int dpms_mode);
 
 extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
index 0427ca5..ebf213c 100644 (file)
@@ -80,8 +80,8 @@ static struct intel_dvo_device intel_dvo_devices[] = {
 static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_i915_private *dev_priv = encoder->dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        u32 dvo_reg = dvo->dvo_reg;
        u32 temp = I915_READ(dvo_reg);
 
@@ -99,8 +99,8 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
 static void intel_dvo_save(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* Each output should probably just save the registers it touches,
         * but for now, use more overkill.
@@ -115,8 +115,8 @@ static void intel_dvo_save(struct drm_connector *connector)
 static void intel_dvo_restore(struct drm_connector *connector)
 {
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        dvo->dev_ops->restore(dvo);
 
@@ -128,8 +128,8 @@ static void intel_dvo_restore(struct drm_connector *connector)
 static int intel_dvo_mode_valid(struct drm_connector *connector,
                                struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
@@ -150,8 +150,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
                                 struct drm_display_mode *mode,
                                 struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* If we have timings from the BIOS for the panel, put them in
         * to the adjusted mode.  The CRTC will be set up for this mode,
@@ -186,8 +186,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        int pipe = intel_crtc->pipe;
        u32 dvo_val;
        u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
@@ -241,23 +241,23 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
  */
 static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        return dvo->dev_ops->detect(dvo);
 }
 
 static int intel_dvo_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        /* We should probably have an i2c driver get_modes function for those
         * devices which will have a fixed set of modes determined by the chip
         * (TV-out, for example), but for now with just TMDS and LVDS,
         * that's not the case.
         */
-       intel_ddc_get_modes(intel_output);
+       intel_ddc_get_modes(intel_encoder);
        if (!list_empty(&connector->probed_modes))
                return 1;
 
@@ -275,8 +275,8 @@ static int intel_dvo_get_modes(struct drm_connector *connector)
 
 static void intel_dvo_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
 
        if (dvo) {
                if (dvo->dev_ops->destroy)
@@ -286,13 +286,13 @@ static void intel_dvo_destroy (struct drm_connector *connector)
                /* no need, in i830_dvoices[] now */
                //kfree(dvo);
        }
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 #ifdef RANDR_GET_CRTC_INTERFACE
@@ -300,8 +300,8 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
 
        return intel_pipe_to_crtc(pScrn, pipe);
@@ -352,8 +352,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_dvo_device *dvo = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_dvo_device *dvo = intel_encoder->dev_priv;
        uint32_t dvo_reg = dvo->dvo_reg;
        uint32_t dvo_val = I915_READ(dvo_reg);
        struct drm_display_mode *mode = NULL;
@@ -383,24 +383,24 @@ intel_dvo_get_current_mode (struct drm_connector *connector)
 
 void intel_dvo_init(struct drm_device *dev)
 {
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_dvo_device *dvo;
        struct i2c_adapter *i2cbus = NULL;
        int ret = 0;
        int i;
        int encoder_type = DRM_MODE_ENCODER_NONE;
-       intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
-       if (!intel_output)
+       intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL);
+       if (!intel_encoder)
                return;
 
        /* Set up the DDC bus */
-       intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
-       if (!intel_output->ddc_bus)
+       intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
+       if (!intel_encoder->ddc_bus)
                goto free_intel;
 
        /* Now, try to find a controller */
        for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
-               struct drm_connector *connector = &intel_output->base;
+               struct drm_connector *connector = &intel_encoder->base;
                int gpio;
 
                dvo = &intel_dvo_devices[i];
@@ -435,11 +435,11 @@ void intel_dvo_init(struct drm_device *dev)
                if (!ret)
                        continue;
 
-               intel_output->type = INTEL_OUTPUT_DVO;
-               intel_output->crtc_mask = (1 << 0) | (1 << 1);
+               intel_encoder->type = INTEL_OUTPUT_DVO;
+               intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
                switch (dvo->type) {
                case INTEL_DVO_CHIP_TMDS:
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                (1 << INTEL_DVO_TMDS_CLONE_BIT) |
                                (1 << INTEL_ANALOG_CLONE_BIT);
                        drm_connector_init(dev, connector,
@@ -448,7 +448,7 @@ void intel_dvo_init(struct drm_device *dev)
                        encoder_type = DRM_MODE_ENCODER_TMDS;
                        break;
                case INTEL_DVO_CHIP_LVDS:
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                (1 << INTEL_DVO_LVDS_CLONE_BIT);
                        drm_connector_init(dev, connector,
                                           &intel_dvo_connector_funcs,
@@ -463,16 +463,16 @@ void intel_dvo_init(struct drm_device *dev)
                connector->interlace_allowed = false;
                connector->doublescan_allowed = false;
 
-               intel_output->dev_priv = dvo;
-               intel_output->i2c_bus = i2cbus;
+               intel_encoder->dev_priv = dvo;
+               intel_encoder->i2c_bus = i2cbus;
 
-               drm_encoder_init(dev, &intel_output->enc,
+               drm_encoder_init(dev, &intel_encoder->enc,
                                 &intel_dvo_enc_funcs, encoder_type);
-               drm_encoder_helper_add(&intel_output->enc,
+               drm_encoder_helper_add(&intel_encoder->enc,
                                       &intel_dvo_helper_funcs);
 
-               drm_mode_connector_attach_encoder(&intel_output->base,
-                                                 &intel_output->enc);
+               drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                                 &intel_encoder->enc);
                if (dvo->type == INTEL_DVO_CHIP_LVDS) {
                        /* For our LVDS chipsets, we should hopefully be able
                         * to dig the fixed panel mode out of the BIOS data.
@@ -490,10 +490,10 @@ void intel_dvo_init(struct drm_device *dev)
                return;
        }
 
-       intel_i2c_destroy(intel_output->ddc_bus);
+       intel_i2c_destroy(intel_encoder->ddc_bus);
        /* Didn't find a chip, so tear down. */
        if (i2cbus != NULL)
                intel_i2c_destroy(i2cbus);
 free_intel:
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
index 69bbef9..8a0b3bc 100644 (file)
@@ -144,7 +144,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
                ret = -ENOMEM;
                goto out;
        }
-       obj_priv = fbo->driver_private;
+       obj_priv = to_intel_bo(fbo);
 
        mutex_lock(&dev->struct_mutex);
 
index 1ed02f6..48cade0 100644 (file)
@@ -51,8 +51,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        u32 sdvox;
 
        sdvox = SDVO_ENCODING_HDMI |
@@ -74,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        u32 temp;
 
        temp = I915_READ(hdmi_priv->sdvox_reg);
@@ -110,8 +110,8 @@ static void intel_hdmi_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
        hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);
 }
@@ -120,8 +120,8 @@ static void intel_hdmi_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
 
        I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);
        POSTING_READ(hdmi_priv->sdvox_reg);
@@ -151,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
        struct edid *edid = NULL;
        enum drm_connector_status status = connector_status_disconnected;
 
        hdmi_priv->has_hdmi_sink = false;
-       edid = drm_get_edid(&intel_output->base,
-                           intel_output->ddc_bus);
+       edid = drm_get_edid(&intel_encoder->base,
+                           intel_encoder->ddc_bus);
 
        if (edid) {
                if (edid->input & DRM_EDID_INPUT_DIGITAL) {
                        status = connector_status_connected;
                        hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
                }
-               intel_output->base.display_info.raw_edid = NULL;
+               intel_encoder->base.display_info.raw_edid = NULL;
                kfree(edid);
        }
 
@@ -174,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *connector)
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        /* We should parse the EDID data and find out if it's an HDMI sink so
         * we can send audio to it.
         */
 
-       return intel_ddc_get_modes(intel_output);
+       return intel_ddc_get_modes(intel_encoder);
 }
 
 static void intel_hdmi_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
@@ -230,63 +230,63 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_hdmi_priv *hdmi_priv;
 
-       intel_output = kcalloc(sizeof(struct intel_output) +
+       intel_encoder = kcalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
-       if (!intel_output)
+       if (!intel_encoder)
                return;
-       hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1);
+       hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
                           DRM_MODE_CONNECTOR_HDMIA);
        drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
 
-       intel_output->type = INTEL_OUTPUT_HDMI;
+       intel_encoder->type = INTEL_OUTPUT_HDMI;
 
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
        /* Set up the DDC bus. */
        if (sdvox_reg == SDVOB) {
-               intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
+               intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == SDVOC) {
-               intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
+               intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIB) {
-               intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
+               intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
                                                                "HDMIB");
                dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMIC) {
-               intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
+               intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
                                                                "HDMIC");
                dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
        } else if (sdvox_reg == HDMID) {
-               intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
-               intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
+               intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
+               intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
                                                                "HDMID");
                dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
        }
-       if (!intel_output->ddc_bus)
+       if (!intel_encoder->ddc_bus)
                goto err_connector;
 
        hdmi_priv->sdvox_reg = sdvox_reg;
-       intel_output->dev_priv = hdmi_priv;
+       intel_encoder->dev_priv = hdmi_priv;
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
                         DRM_MODE_ENCODER_TMDS);
-       drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base,
-                                         &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base,
+                                         &intel_encoder->enc);
        drm_sysfs_connector_add(connector);
 
        /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
@@ -302,7 +302,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 
 err_connector:
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 
        return;
 }
index 216e9f5..b66806a 100644 (file)
@@ -239,8 +239,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
        struct drm_encoder *tmp_encoder;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
        u32 pfit_control = 0, pfit_pgm_ratios = 0;
        int left_border = 0, right_border = 0, top_border = 0;
        int bottom_border = 0;
@@ -587,8 +587,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
 
        /*
         * The LVDS pin pair will already have been turned on in the
@@ -635,14 +635,16 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
 static int intel_lvds_get_modes(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret = 0;
 
-       ret = intel_ddc_get_modes(intel_output);
+       if (dev_priv->lvds_edid_good) {
+               ret = intel_ddc_get_modes(intel_encoder);
 
-       if (ret)
-               return ret;
+               if (ret)
+                       return ret;
+       }
 
        /* Didn't get an EDID, so
         * Set wide sync ranges so we get all modes
@@ -715,11 +717,11 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
 static void intel_lvds_destroy(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        if (dev_priv->lid_notifier.notifier_call)
                acpi_lid_notifier_unregister(&dev_priv->lid_notifier);
        drm_sysfs_connector_remove(connector);
@@ -732,13 +734,13 @@ static int intel_lvds_set_property(struct drm_connector *connector,
                                   uint64_t value)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output =
-                       to_intel_output(connector);
+       struct intel_encoder *intel_encoder =
+                       to_intel_encoder(connector);
 
        if (property == dev->mode_config.scaling_mode_property &&
                                connector->encoder) {
                struct drm_crtc *crtc = connector->encoder->crtc;
-               struct intel_lvds_priv *lvds_priv = intel_output->dev_priv;
+               struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv;
                if (value == DRM_MODE_SCALE_NONE) {
                        DRM_DEBUG_KMS("no scaling not supported\n");
                        return 0;
@@ -858,6 +860,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
                },
        },
+       {
+               .callback = intel_no_lvds_dmi_callback,
+               .ident = "Clientron U800",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Clientron"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
+               },
+       },
 
        { }     /* terminating entry */
 };
@@ -968,7 +978,7 @@ static int lvds_is_present_in_vbt(struct drm_device *dev)
 void intel_lvds_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct drm_connector *connector;
        struct drm_encoder *encoder;
        struct drm_display_mode *scan; /* *modes, *bios_mode; */
@@ -996,40 +1006,40 @@ void intel_lvds_init(struct drm_device *dev)
                gpio = PCH_GPIOC;
        }
 
-       intel_output = kzalloc(sizeof(struct intel_output) +
+       intel_encoder = kzalloc(sizeof(struct intel_encoder) +
                                sizeof(struct intel_lvds_priv), GFP_KERNEL);
-       if (!intel_output) {
+       if (!intel_encoder) {
                return;
        }
 
-       connector = &intel_output->base;
-       encoder = &intel_output->enc;
-       drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
+       connector = &intel_encoder->base;
+       encoder = &intel_encoder->enc;
+       drm_connector_init(dev, &intel_encoder->base, &intel_lvds_connector_funcs,
                           DRM_MODE_CONNECTOR_LVDS);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_lvds_enc_funcs,
                         DRM_MODE_ENCODER_LVDS);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-       intel_output->type = INTEL_OUTPUT_LVDS;
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+       intel_encoder->type = INTEL_OUTPUT_LVDS;
 
-       intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
-       intel_output->crtc_mask = (1 << 1);
+       intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
+       intel_encoder->crtc_mask = (1 << 1);
        drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
        drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
 
-       lvds_priv = (struct intel_lvds_priv *)(intel_output + 1);
-       intel_output->dev_priv = lvds_priv;
+       lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1);
+       intel_encoder->dev_priv = lvds_priv;
        /* create the scaling mode property */
        drm_mode_create_scaling_mode_property(dev);
        /*
         * the initial panel fitting mode will be FULL_SCREEN.
         */
 
-       drm_connector_attach_property(&intel_output->base,
+       drm_connector_attach_property(&intel_encoder->base,
                                      dev->mode_config.scaling_mode_property,
                                      DRM_MODE_SCALE_FULLSCREEN);
        lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN;
@@ -1044,8 +1054,8 @@ void intel_lvds_init(struct drm_device *dev)
         */
 
        /* Set up the DDC bus. */
-       intel_output->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
-       if (!intel_output->ddc_bus) {
+       intel_encoder->ddc_bus = intel_i2c_create(dev, gpio, "LVDSDDC_C");
+       if (!intel_encoder->ddc_bus) {
                dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
                           "failed.\n");
                goto failed;
@@ -1055,7 +1065,10 @@ void intel_lvds_init(struct drm_device *dev)
         * Attempt to get the fixed panel mode from DDC.  Assume that the
         * preferred mode is the right one.
         */
-       intel_ddc_get_modes(intel_output);
+       dev_priv->lvds_edid_good = true;
+
+       if (!intel_ddc_get_modes(intel_encoder))
+               dev_priv->lvds_edid_good = false;
 
        list_for_each_entry(scan, &connector->probed_modes, head) {
                mutex_lock(&dev->mode_config.mutex);
@@ -1133,9 +1146,9 @@ out:
 
 failed:
        DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        drm_connector_cleanup(connector);
        drm_encoder_cleanup(encoder);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
index 89d303d..8e5c83b 100644 (file)
@@ -34,7 +34,7 @@
  * intel_ddc_probe
  *
  */
-bool intel_ddc_probe(struct intel_output *intel_output)
+bool intel_ddc_probe(struct intel_encoder *intel_encoder)
 {
        u8 out_buf[] = { 0x0, 0x0};
        u8 buf[2];
@@ -54,9 +54,9 @@ bool intel_ddc_probe(struct intel_output *intel_output)
                }
        };
 
-       intel_i2c_quirk_set(intel_output->base.dev, true);
-       ret = i2c_transfer(intel_output->ddc_bus, msgs, 2);
-       intel_i2c_quirk_set(intel_output->base.dev, false);
+       intel_i2c_quirk_set(intel_encoder->base.dev, true);
+       ret = i2c_transfer(intel_encoder->ddc_bus, msgs, 2);
+       intel_i2c_quirk_set(intel_encoder->base.dev, false);
        if (ret == 2)
                return true;
 
@@ -69,19 +69,19 @@ bool intel_ddc_probe(struct intel_output *intel_output)
  *
  * Fetch the EDID information from @connector using the DDC bus.
  */
-int intel_ddc_get_modes(struct intel_output *intel_output)
+int intel_ddc_get_modes(struct intel_encoder *intel_encoder)
 {
        struct edid *edid;
        int ret = 0;
 
-       intel_i2c_quirk_set(intel_output->base.dev, true);
-       edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus);
-       intel_i2c_quirk_set(intel_output->base.dev, false);
+       intel_i2c_quirk_set(intel_encoder->base.dev, true);
+       edid = drm_get_edid(&intel_encoder->base, intel_encoder->ddc_bus);
+       intel_i2c_quirk_set(intel_encoder->base.dev, false);
        if (edid) {
-               drm_mode_connector_update_edid_property(&intel_output->base,
+               drm_mode_connector_update_edid_property(&intel_encoder->base,
                                                        edid);
-               ret = drm_add_edid_modes(&intel_output->base, edid);
-               intel_output->base.display_info.raw_edid = NULL;
+               ret = drm_add_edid_modes(&intel_encoder->base, edid);
+               intel_encoder->base.display_info.raw_edid = NULL;
                kfree(edid);
        }
 
index 60595fc..6d524a1 100644 (file)
@@ -724,7 +724,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
        int ret, tmp_width;
        struct overlay_registers *regs;
        bool scale_changed = false;
-       struct drm_i915_gem_object *bo_priv = new_bo->driver_private;
+       struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo);
        struct drm_device *dev = overlay->dev;
 
        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
@@ -809,7 +809,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
        intel_overlay_continue(overlay, scale_changed);
 
        overlay->old_vid_bo = overlay->vid_bo;
-       overlay->vid_bo = new_bo->driver_private;
+       overlay->vid_bo = to_intel_bo(new_bo);
 
        return 0;
 
@@ -1344,7 +1344,7 @@ void intel_setup_overlay(struct drm_device *dev)
        reg_bo = drm_gem_object_alloc(dev, PAGE_SIZE);
        if (!reg_bo)
                goto out_free;
-       overlay->reg_bo = reg_bo->driver_private;
+       overlay->reg_bo = to_intel_bo(reg_bo);
 
        if (OVERLAY_NONPHYSICAL(dev)) {
                ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
index 26e13a0..87d9536 100644 (file)
@@ -54,7 +54,7 @@ struct intel_sdvo_priv {
        u8 slave_addr;
 
        /* Register for the SDVO device: SDVOB or SDVOC */
-       int output_device;
+       int sdvo_reg;
 
        /* Active outputs controlled by this SDVO output */
        uint16_t controlled_output;
@@ -124,7 +124,7 @@ struct intel_sdvo_priv {
         */
        struct intel_sdvo_encode encode;
 
-       /* DDC bus used by this SDVO output */
+       /* DDC bus used by this SDVO encoder */
        uint8_t ddc_bus;
 
        /* Mac mini hack -- use the same DDC as the analog connector */
@@ -162,22 +162,22 @@ struct intel_sdvo_priv {
 };
 
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags);
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags);
 
 /**
  * Writes the SDVOB or SDVOC with the given value, but always writes both
  * SDVOB and SDVOC to work around apparent hardware issues (according to
  * comments in the BIOS).
  */
-static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
+static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val)
 {
-       struct drm_device *dev = intel_output->base.dev;
+       struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_sdvo_priv   *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv   *sdvo_priv = intel_encoder->dev_priv;
        u32 bval = val, cval = val;
        int i;
 
-       if (sdvo_priv->output_device == SDVOB) {
+       if (sdvo_priv->sdvo_reg == SDVOB) {
                cval = I915_READ(SDVOC);
        } else {
                bval = I915_READ(SDVOB);
@@ -196,10 +196,10 @@ static void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
        }
 }
 
-static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
+static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr,
                                 u8 *ch)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2];
        u8 buf[2];
        int ret;
@@ -222,7 +222,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
        out_buf[0] = addr;
        out_buf[1] = 0;
 
-       if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2)
+       if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2)
        {
                *ch = buf[0];
                return true;
@@ -232,10 +232,10 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
        return false;
 }
 
-static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
+static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr,
                                  u8 ch)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2];
        struct i2c_msg msgs[] = {
                {
@@ -249,7 +249,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
        out_buf[0] = addr;
        out_buf[1] = ch;
 
-       if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1)
+       if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1)
        {
                return true;
        }
@@ -353,13 +353,13 @@ static const struct _sdvo_cmd_name {
     SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA),
 };
 
-#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
-#define SDVO_PRIV(output)   ((struct intel_sdvo_priv *) (output)->dev_priv)
+#define SDVO_NAME(dev_priv) ((dev_priv)->sdvo_reg == SDVOB ? "SDVOB" : "SDVOC")
+#define SDVO_PRIV(encoder)   ((struct intel_sdvo_priv *) (encoder)->dev_priv)
 
-static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd,
                                   void *args, int args_len)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int i;
 
        DRM_DEBUG_KMS("%s: W: %02X ",
@@ -379,19 +379,19 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
        DRM_LOG_KMS("\n");
 }
 
-static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
+static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd,
                                 void *args, int args_len)
 {
        int i;
 
-       intel_sdvo_debug_write(intel_output, cmd, args, args_len);
+       intel_sdvo_debug_write(intel_encoder, cmd, args, args_len);
 
        for (i = 0; i < args_len; i++) {
-               intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
+               intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i,
                                      ((u8*)args)[i]);
        }
 
-       intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
+       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd);
 }
 
 static const char *cmd_status_names[] = {
@@ -404,11 +404,11 @@ static const char *cmd_status_names[] = {
        "Scaling not supported"
 };
 
-static void intel_sdvo_debug_response(struct intel_output *intel_output,
+static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder,
                                      void *response, int response_len,
                                      u8 status)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int i;
 
        DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv));
@@ -423,7 +423,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
        DRM_LOG_KMS("\n");
 }
 
-static u8 intel_sdvo_read_response(struct intel_output *intel_output,
+static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder,
                                   void *response, int response_len)
 {
        int i;
@@ -433,16 +433,16 @@ static u8 intel_sdvo_read_response(struct intel_output *intel_output,
        while (retry--) {
                /* Read the command response */
                for (i = 0; i < response_len; i++) {
-                       intel_sdvo_read_byte(intel_output,
+                       intel_sdvo_read_byte(intel_encoder,
                                             SDVO_I2C_RETURN_0 + i,
                                             &((u8 *)response)[i]);
                }
 
                /* read the return status */
-               intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
+               intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS,
                                     &status);
 
-               intel_sdvo_debug_response(intel_output, response, response_len,
+               intel_sdvo_debug_response(intel_encoder, response, response_len,
                                          status);
                if (status != SDVO_CMD_STATUS_PENDING)
                        return status;
@@ -470,10 +470,10 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
  * another I2C transaction after issuing the DDC bus switch, it will be
  * switched to the internal SDVO register.
  */
-static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
+static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder,
                                              u8 target)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u8 out_buf[2], cmd_buf[2], ret_value[2], ret;
        struct i2c_msg msgs[] = {
                {
@@ -497,10 +497,10 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
                },
        };
 
-       intel_sdvo_debug_write(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
+       intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH,
                                        &target, 1);
        /* write the DDC switch command argument */
-       intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0, target);
+       intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target);
 
        out_buf[0] = SDVO_I2C_OPCODE;
        out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH;
@@ -509,7 +509,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
        ret_value[0] = 0;
        ret_value[1] = 0;
 
-       ret = i2c_transfer(intel_output->i2c_bus, msgs, 3);
+       ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3);
        if (ret != 3) {
                /* failure in I2C transfer */
                DRM_DEBUG_KMS("I2c transfer returned %d\n", ret);
@@ -523,7 +523,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output,
        return;
 }
 
-static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
+static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1)
 {
        struct intel_sdvo_set_target_input_args targets = {0};
        u8 status;
@@ -534,10 +534,10 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
        if (target_1)
                targets.target_1 = 1;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets,
                             sizeof(targets));
 
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
@@ -548,13 +548,13 @@ static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool
  * This function is making an assumption about the layout of the response,
  * which should be checked against the docs.
  */
-static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
+static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2)
 {
        struct intel_sdvo_get_trained_inputs_response response;
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -563,29 +563,29 @@ static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, boo
        return true;
 }
 
-static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_get_active_outputs(struct intel_encoder *intel_encoder,
                                          u16 *outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, outputs, sizeof(*outputs));
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
+static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder,
                                          u16 outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
                             sizeof(outputs));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
+static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder,
                                               int mode)
 {
        u8 status, state = SDVO_ENCODER_STATE_ON;
@@ -605,24 +605,24 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output
                break;
        }
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
                             sizeof(state));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder,
                                                   int *clock_min,
                                                   int *clock_max)
 {
        struct intel_sdvo_pixel_clock_range clocks;
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
+       status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks));
 
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -634,31 +634,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_ou
        return true;
 }
 
-static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
+static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder,
                                         u16 outputs)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
                             sizeof(outputs));
 
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_get_timing(struct intel_encoder *intel_encoder, u8 cmd,
                                  struct intel_sdvo_dtd *dtd)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &dtd->part1,
+       intel_sdvo_write_cmd(intel_encoder, cmd, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
                                          sizeof(dtd->part1));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &dtd->part2,
+       intel_sdvo_write_cmd(intel_encoder, cmd + 1, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
                                          sizeof(dtd->part2));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -666,60 +666,60 @@ static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
        return true;
 }
 
-static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_input_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_get_timing(intel_output,
+       return intel_sdvo_get_timing(intel_encoder,
                                     SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_get_output_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_get_timing(intel_output,
+       return intel_sdvo_get_timing(intel_encoder,
                                     SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
+static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd,
                                  struct intel_sdvo_dtd *dtd)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1));
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
        return true;
 }
 
-static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_set_timing(intel_output,
+       return intel_sdvo_set_timing(intel_encoder,
                                     SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
 }
 
-static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
+static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder,
                                         struct intel_sdvo_dtd *dtd)
 {
-       return intel_sdvo_set_timing(intel_output,
+       return intel_sdvo_set_timing(intel_encoder,
                                     SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
 }
 
 static bool
-intel_sdvo_create_preferred_input_timing(struct intel_output *output,
+intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder,
                                         uint16_t clock,
                                         uint16_t width,
                                         uint16_t height)
 {
        struct intel_sdvo_preferred_input_timing_args args;
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        uint8_t status;
 
        memset(&args, 0, sizeof(args));
@@ -733,32 +733,33 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
            sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height))
                args.scaled = 1;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
+       intel_sdvo_write_cmd(intel_encoder,
+                            SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
                             &args, sizeof(args));
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
        return true;
 }
 
-static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
+static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder,
                                                  struct intel_sdvo_dtd *dtd)
 {
        bool status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(output, &dtd->part1,
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part1,
                                          sizeof(dtd->part1));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
                             NULL, 0);
 
-       status = intel_sdvo_read_response(output, &dtd->part2,
+       status = intel_sdvo_read_response(intel_encoder, &dtd->part2,
                                          sizeof(dtd->part2));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
@@ -766,12 +767,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct intel_output *output,
        return false;
 }
 
-static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
+static int intel_sdvo_get_clock_rate_mult(struct intel_encoder *intel_encoder)
 {
        u8 response, status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, 1);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, 1);
 
        if (status != SDVO_CMD_STATUS_SUCCESS) {
                DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n");
@@ -783,12 +784,12 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
        return response;
 }
 
-static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
+static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
-       status = intel_sdvo_read_response(intel_output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -877,13 +878,13 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
                mode->flags |= DRM_MODE_FLAG_PVSYNC;
 }
 
-static bool intel_sdvo_get_supp_encode(struct intel_output *output,
+static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder,
                                       struct intel_sdvo_encode *encode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
-       status = intel_sdvo_read_response(output, encode, sizeof(*encode));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode));
        if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */
                memset(encode, 0, sizeof(*encode));
                return false;
@@ -892,29 +893,30 @@ static bool intel_sdvo_get_supp_encode(struct intel_output *output,
        return true;
 }
 
-static bool intel_sdvo_set_encode(struct intel_output *output, uint8_t mode)
+static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder,
+                                 uint8_t mode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1);
-       status = intel_sdvo_read_response(output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
-static bool intel_sdvo_set_colorimetry(struct intel_output *output,
+static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder,
                                       uint8_t mode)
 {
        uint8_t status;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
-       status = intel_sdvo_read_response(output, NULL, 0);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        return (status == SDVO_CMD_STATUS_SUCCESS);
 }
 
 #if 0
-static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
+static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder)
 {
        int i, j;
        uint8_t set_buf_index[2];
@@ -923,43 +925,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_output *output)
        uint8_t buf[48];
        uint8_t *pos;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
-       intel_sdvo_read_response(output, &av_split, 1);
+       intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0);
+       intel_sdvo_read_response(encoder, &av_split, 1);
 
        for (i = 0; i <= av_split; i++) {
                set_buf_index[0] = i; set_buf_index[1] = 0;
-               intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX,
+               intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX,
                                     set_buf_index, 2);
-               intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
-               intel_sdvo_read_response(output, &buf_size, 1);
+               intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0);
+               intel_sdvo_read_response(encoder, &buf_size, 1);
 
                pos = buf;
                for (j = 0; j <= buf_size; j += 8) {
-                       intel_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA,
+                       intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA,
                                             NULL, 0);
-                       intel_sdvo_read_response(output, pos, 8);
+                       intel_sdvo_read_response(encoder, pos, 8);
                        pos += 8;
                }
        }
 }
 #endif
 
-static void intel_sdvo_set_hdmi_buf(struct intel_output *output, int index,
-                               uint8_t *data, int8_t size, uint8_t tx_rate)
+static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder,
+                                   int index,
+                                   uint8_t *data, int8_t size, uint8_t tx_rate)
 {
     uint8_t set_buf_index[2];
 
     set_buf_index[0] = index;
     set_buf_index[1] = 0;
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX,
+                        set_buf_index, 2);
 
     for (; size > 0; size -= 8) {
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8);
        data += 8;
     }
 
-    intel_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
+    intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1);
 }
 
 static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size)
@@ -1034,7 +1038,7 @@ struct dip_infoframe {
        } __attribute__ ((packed)) u;
 } __attribute__((packed));
 
-static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
+static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder,
                                         struct drm_display_mode * mode)
 {
        struct dip_infoframe avi_if = {
@@ -1045,15 +1049,16 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
 
        avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if,
                                                    4 + avi_if.len);
-       intel_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len,
+       intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if,
+                               4 + avi_if.len,
                                SDVO_HBUF_TX_VSYNC);
 }
 
-static void intel_sdvo_set_tv_format(struct intel_output *output)
+static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder)
 {
 
        struct intel_sdvo_tv_format format;
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        uint32_t format_map, i;
        uint8_t status;
 
@@ -1066,10 +1071,10 @@ static void intel_sdvo_set_tv_format(struct intel_output *output)
        memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ?
                        sizeof(format) : sizeof(format_map));
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format_map,
                             sizeof(format));
 
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
        if (status != SDVO_CMD_STATUS_SUCCESS)
                DRM_DEBUG_KMS("%s: Failed to set TV format\n",
                          SDVO_NAME(sdvo_priv));
@@ -1079,8 +1084,8 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                                  struct drm_display_mode *mode,
                                  struct drm_display_mode *adjusted_mode)
 {
-       struct intel_output *output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *dev_priv = output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv;
 
        if (dev_priv->is_tv) {
                struct intel_sdvo_dtd output_dtd;
@@ -1095,22 +1100,22 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
 
                /* Set output timings */
                intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             dev_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &output_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
                /* Set the input timing to the screen. Assume always input 0. */
-               intel_sdvo_set_target_input(output, true, false);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
-               success = intel_sdvo_create_preferred_input_timing(output,
+               success = intel_sdvo_create_preferred_input_timing(intel_encoder,
                                                                   mode->clock / 10,
                                                                   mode->hdisplay,
                                                                   mode->vdisplay);
                if (success) {
                        struct intel_sdvo_dtd input_dtd;
 
-                       intel_sdvo_get_preferred_input_timing(output,
+                       intel_sdvo_get_preferred_input_timing(intel_encoder,
                                                             &input_dtd);
                        intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
                        dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1133,16 +1138,16 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                intel_sdvo_get_dtd_from_mode(&output_dtd,
                                dev_priv->sdvo_lvds_fixed_mode);
 
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             dev_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &output_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &output_dtd);
 
                /* Set the input timing to the screen. Assume always input 0. */
-               intel_sdvo_set_target_input(output, true, false);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
 
 
                success = intel_sdvo_create_preferred_input_timing(
-                               output,
+                               intel_encoder,
                                mode->clock / 10,
                                mode->hdisplay,
                                mode->vdisplay);
@@ -1150,7 +1155,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
                if (success) {
                        struct intel_sdvo_dtd input_dtd;
 
-                       intel_sdvo_get_preferred_input_timing(output,
+                       intel_sdvo_get_preferred_input_timing(intel_encoder,
                                                             &input_dtd);
                        intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
                        dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags;
@@ -1182,8 +1187,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u32 sdvox = 0;
        int sdvo_pixel_multiply;
        struct intel_sdvo_in_out_map in_out;
@@ -1202,12 +1207,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
        in_out.in0 = sdvo_priv->controlled_output;
        in_out.in1 = 0;
 
-       intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP,
                             &in_out, sizeof(in_out));
-       status = intel_sdvo_read_response(output, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, NULL, 0);
 
        if (sdvo_priv->is_hdmi) {
-               intel_sdvo_set_avi_infoframe(output, mode);
+               intel_sdvo_set_avi_infoframe(intel_encoder, mode);
                sdvox |= SDVO_AUDIO_ENABLE;
        }
 
@@ -1224,16 +1229,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
         */
        if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) {
                /* Set the output timing to the screen */
-               intel_sdvo_set_target_output(output,
+               intel_sdvo_set_target_output(intel_encoder,
                                             sdvo_priv->controlled_output);
-               intel_sdvo_set_output_timing(output, &input_dtd);
+               intel_sdvo_set_output_timing(intel_encoder, &input_dtd);
        }
 
        /* Set the input timing to the screen. Assume always input 0. */
-       intel_sdvo_set_target_input(output, true, false);
+       intel_sdvo_set_target_input(intel_encoder, true, false);
 
        if (sdvo_priv->is_tv)
-               intel_sdvo_set_tv_format(output);
+               intel_sdvo_set_tv_format(intel_encoder);
 
        /* We would like to use intel_sdvo_create_preferred_input_timing() to
         * provide the device with a timing it can support, if it supports that
@@ -1241,29 +1246,29 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
         * output the preferred timing, and we don't support that currently.
         */
 #if 0
-       success = intel_sdvo_create_preferred_input_timing(output, clock,
+       success = intel_sdvo_create_preferred_input_timing(encoder, clock,
                                                           width, height);
        if (success) {
                struct intel_sdvo_dtd *input_dtd;
 
-               intel_sdvo_get_preferred_input_timing(output, &input_dtd);
-               intel_sdvo_set_input_timing(output, &input_dtd);
+               intel_sdvo_get_preferred_input_timing(encoder, &input_dtd);
+               intel_sdvo_set_input_timing(encoder, &input_dtd);
        }
 #else
-       intel_sdvo_set_input_timing(output, &input_dtd);
+       intel_sdvo_set_input_timing(intel_encoder, &input_dtd);
 #endif
 
        switch (intel_sdvo_get_pixel_multiplier(mode)) {
        case 1:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_1X);
                break;
        case 2:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_2X);
                break;
        case 4:
-               intel_sdvo_set_clock_rate_mult(output,
+               intel_sdvo_set_clock_rate_mult(intel_encoder,
                                               SDVO_CLOCK_RATE_MULT_4X);
                break;
        }
@@ -1274,8 +1279,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
                        SDVO_VSYNC_ACTIVE_HIGH |
                        SDVO_HSYNC_ACTIVE_HIGH;
        } else {
-               sdvox |= I915_READ(sdvo_priv->output_device);
-               switch (sdvo_priv->output_device) {
+               sdvox |= I915_READ(sdvo_priv->sdvo_reg);
+               switch (sdvo_priv->sdvo_reg) {
                case SDVOB:
                        sdvox &= SDVOB_PRESERVE_MASK;
                        break;
@@ -1299,26 +1304,26 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
 
        if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL)
                sdvox |= SDVO_STALL_SELECT;
-       intel_sdvo_write_sdvox(output, sdvox);
+       intel_sdvo_write_sdvox(intel_encoder, sdvox);
 }
 
 static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
 {
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        u32 temp;
 
        if (mode != DRM_MODE_DPMS_ON) {
-               intel_sdvo_set_active_outputs(intel_output, 0);
+               intel_sdvo_set_active_outputs(intel_encoder, 0);
                if (0)
-                       intel_sdvo_set_encoder_power_state(intel_output, mode);
+                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
 
                if (mode == DRM_MODE_DPMS_OFF) {
-                       temp = I915_READ(sdvo_priv->output_device);
+                       temp = I915_READ(sdvo_priv->sdvo_reg);
                        if ((temp & SDVO_ENABLE) != 0) {
-                               intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
+                               intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE);
                        }
                }
        } else {
@@ -1326,13 +1331,13 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
                int i;
                u8 status;
 
-               temp = I915_READ(sdvo_priv->output_device);
+               temp = I915_READ(sdvo_priv->sdvo_reg);
                if ((temp & SDVO_ENABLE) == 0)
-                       intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
+                       intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE);
                for (i = 0; i < 2; i++)
                  intel_wait_for_vblank(dev);
 
-               status = intel_sdvo_get_trained_inputs(intel_output, &input1,
+               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1,
                                                       &input2);
 
 
@@ -1346,8 +1351,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
                }
 
                if (0)
-                       intel_sdvo_set_encoder_power_state(intel_output, mode);
-               intel_sdvo_set_active_outputs(intel_output, sdvo_priv->controlled_output);
+                       intel_sdvo_set_encoder_power_state(intel_encoder, mode);
+               intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->controlled_output);
        }
        return;
 }
@@ -1356,22 +1361,22 @@ static void intel_sdvo_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int o;
 
-       sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
-       intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
+       sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_encoder);
+       intel_sdvo_get_active_outputs(intel_encoder, &sdvo_priv->save_active_outputs);
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               intel_sdvo_set_target_input(intel_output, true, false);
-               intel_sdvo_get_input_timing(intel_output,
+               intel_sdvo_set_target_input(intel_encoder, true, false);
+               intel_sdvo_get_input_timing(intel_encoder,
                                            &sdvo_priv->save_input_dtd_1);
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               intel_sdvo_set_target_input(intel_output, false, true);
-               intel_sdvo_get_input_timing(intel_output,
+               intel_sdvo_set_target_input(intel_encoder, false, true);
+               intel_sdvo_get_input_timing(intel_encoder,
                                            &sdvo_priv->save_input_dtd_2);
        }
 
@@ -1380,8 +1385,8 @@ static void intel_sdvo_save(struct drm_connector *connector)
                u16  this_output = (1 << o);
                if (sdvo_priv->caps.output_flags & this_output)
                {
-                       intel_sdvo_set_target_output(intel_output, this_output);
-                       intel_sdvo_get_output_timing(intel_output,
+                       intel_sdvo_set_target_output(intel_encoder, this_output);
+                       intel_sdvo_get_output_timing(intel_encoder,
                                                     &sdvo_priv->save_output_dtd[o]);
                }
        }
@@ -1389,66 +1394,66 @@ static void intel_sdvo_save(struct drm_connector *connector)
                /* XXX: Save TV format/enhancements. */
        }
 
-       sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
+       sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->sdvo_reg);
 }
 
 static void intel_sdvo_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int o;
        int i;
        bool input1, input2;
        u8 status;
 
-       intel_sdvo_set_active_outputs(intel_output, 0);
+       intel_sdvo_set_active_outputs(intel_encoder, 0);
 
        for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
        {
                u16  this_output = (1 << o);
                if (sdvo_priv->caps.output_flags & this_output) {
-                       intel_sdvo_set_target_output(intel_output, this_output);
-                       intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
+                       intel_sdvo_set_target_output(intel_encoder, this_output);
+                       intel_sdvo_set_output_timing(intel_encoder, &sdvo_priv->save_output_dtd[o]);
                }
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
-               intel_sdvo_set_target_input(intel_output, true, false);
-               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
+               intel_sdvo_set_target_input(intel_encoder, true, false);
+               intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_1);
        }
 
        if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
-               intel_sdvo_set_target_input(intel_output, false, true);
-               intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
+               intel_sdvo_set_target_input(intel_encoder, false, true);
+               intel_sdvo_set_input_timing(intel_encoder, &sdvo_priv->save_input_dtd_2);
        }
 
-       intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
+       intel_sdvo_set_clock_rate_mult(intel_encoder, sdvo_priv->save_sdvo_mult);
 
        if (sdvo_priv->is_tv) {
                /* XXX: Restore TV format/enhancements. */
        }
 
-       intel_sdvo_write_sdvox(intel_output, sdvo_priv->save_SDVOX);
+       intel_sdvo_write_sdvox(intel_encoder, sdvo_priv->save_SDVOX);
 
        if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
        {
                for (i = 0; i < 2; i++)
                        intel_wait_for_vblank(dev);
-               status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
+               status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, &input2);
                if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
                        DRM_DEBUG_KMS("First %s output reported failure to "
                                        "sync\n", SDVO_NAME(sdvo_priv));
        }
 
-       intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
+       intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->save_active_outputs);
 }
 
 static int intel_sdvo_mode_valid(struct drm_connector *connector,
                                 struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
                return MODE_NO_DBLESCAN;
@@ -1473,12 +1478,12 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector,
        return MODE_OK;
 }
 
-static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
+static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps)
 {
        u8 status;
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return false;
 
@@ -1488,22 +1493,22 @@ static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struc
 struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
 {
        struct drm_connector *connector = NULL;
-       struct intel_output *iout = NULL;
+       struct intel_encoder *iout = NULL;
        struct intel_sdvo_priv *sdvo;
 
        /* find the sdvo connector */
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               iout = to_intel_output(connector);
+               iout = to_intel_encoder(connector);
 
                if (iout->type != INTEL_OUTPUT_SDVO)
                        continue;
 
                sdvo = iout->dev_priv;
 
-               if (sdvo->output_device == SDVOB && sdvoB)
+               if (sdvo->sdvo_reg == SDVOB && sdvoB)
                        return connector;
 
-               if (sdvo->output_device == SDVOC && !sdvoB)
+               if (sdvo->sdvo_reg == SDVOC && !sdvoB)
                        return connector;
 
        }
@@ -1515,16 +1520,16 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector)
 {
        u8 response[2];
        u8 status;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        DRM_DEBUG_KMS("\n");
 
        if (!connector)
                return 0;
 
-       intel_output = to_intel_output(connector);
+       intel_encoder = to_intel_encoder(connector);
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+       status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
        if (response[0] !=0)
                return 1;
@@ -1536,30 +1541,30 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
 {
        u8 response[2];
        u8 status;
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-       intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+       intel_sdvo_read_response(intel_encoder, &response, 2);
 
        if (on) {
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
-               status = intel_sdvo_read_response(intel_output, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+               status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
        } else {
                response[0] = 0;
                response[1] = 0;
-               intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+               intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
        }
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
-       intel_sdvo_read_response(intel_output, &response, 2);
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+       intel_sdvo_read_response(intel_encoder, &response, 2);
 }
 
 static bool
-intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
+intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder)
 {
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int caps = 0;
 
        if (sdvo_priv->caps.output_flags &
@@ -1593,11 +1598,11 @@ static struct drm_connector *
 intel_find_analog_connector(struct drm_device *dev)
 {
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
 
        list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-               intel_output = to_intel_output(connector);
-               if (intel_output->type == INTEL_OUTPUT_ANALOG)
+               intel_encoder = to_intel_encoder(connector);
+               if (intel_encoder->type == INTEL_OUTPUT_ANALOG)
                        return connector;
        }
        return NULL;
@@ -1622,16 +1627,16 @@ intel_analog_is_connected(struct drm_device *dev)
 enum drm_connector_status
 intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        enum drm_connector_status status = connector_status_connected;
        struct edid *edid = NULL;
 
-       edid = drm_get_edid(&intel_output->base,
-                           intel_output->ddc_bus);
+       edid = drm_get_edid(&intel_encoder->base,
+                           intel_encoder->ddc_bus);
 
        /* This is only applied to SDVO cards with multiple outputs */
-       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_output)) {
+       if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) {
                uint8_t saved_ddc, temp_ddc;
                saved_ddc = sdvo_priv->ddc_bus;
                temp_ddc = sdvo_priv->ddc_bus >> 1;
@@ -1641,8 +1646,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
                 */
                while(temp_ddc > 1) {
                        sdvo_priv->ddc_bus = temp_ddc;
-                       edid = drm_get_edid(&intel_output->base,
-                               intel_output->ddc_bus);
+                       edid = drm_get_edid(&intel_encoder->base,
+                               intel_encoder->ddc_bus);
                        if (edid) {
                                /*
                                 * When we can get the EDID, maybe it is the
@@ -1661,8 +1666,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
         */
        if (edid == NULL &&
            sdvo_priv->analog_ddc_bus &&
-           !intel_analog_is_connected(intel_output->base.dev))
-               edid = drm_get_edid(&intel_output->base,
+           !intel_analog_is_connected(intel_encoder->base.dev))
+               edid = drm_get_edid(&intel_encoder->base,
                                    sdvo_priv->analog_ddc_bus);
        if (edid != NULL) {
                /* Don't report the output as connected if it's a DVI-I
@@ -1677,7 +1682,7 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
                }
 
                kfree(edid);
-               intel_output->base.display_info.raw_edid = NULL;
+               intel_encoder->base.display_info.raw_edid = NULL;
 
        } else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
                status = connector_status_disconnected;
@@ -1689,16 +1694,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 {
        uint16_t response;
        u8 status;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-       intel_sdvo_write_cmd(intel_output,
+       intel_sdvo_write_cmd(intel_encoder,
                             SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
        if (sdvo_priv->is_tv) {
                /* add 30ms delay when the output type is SDVO-TV */
                mdelay(30);
        }
-       status = intel_sdvo_read_response(intel_output, &response, 2);
+       status = intel_sdvo_read_response(intel_encoder, &response, 2);
 
        DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
 
@@ -1708,10 +1713,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
        if (response == 0)
                return connector_status_disconnected;
 
-       if (intel_sdvo_multifunc_encoder(intel_output) &&
+       if (intel_sdvo_multifunc_encoder(intel_encoder) &&
                sdvo_priv->attached_output != response) {
                if (sdvo_priv->controlled_output != response &&
-                       intel_sdvo_output_setup(intel_output, response) != true)
+                       intel_sdvo_output_setup(intel_encoder, response) != true)
                        return connector_status_unknown;
                sdvo_priv->attached_output = response;
        }
@@ -1720,12 +1725,12 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 
 static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        int num_modes;
 
        /* set the bus switch and get the modes */
-       num_modes = intel_ddc_get_modes(intel_output);
+       num_modes = intel_ddc_get_modes(intel_encoder);
 
        /*
         * Mac mini hack.  On this device, the DVI-I connector shares one DDC
@@ -1735,17 +1740,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
         */
        if (num_modes == 0 &&
            sdvo_priv->analog_ddc_bus &&
-           !intel_analog_is_connected(intel_output->base.dev)) {
+           !intel_analog_is_connected(intel_encoder->base.dev)) {
                struct i2c_adapter *digital_ddc_bus;
 
                /* Switch to the analog ddc bus and try that
                 */
-               digital_ddc_bus = intel_output->ddc_bus;
-               intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
+               digital_ddc_bus = intel_encoder->ddc_bus;
+               intel_encoder->ddc_bus = sdvo_priv->analog_ddc_bus;
 
-               (void) intel_ddc_get_modes(intel_output);
+               (void) intel_ddc_get_modes(intel_encoder);
 
-               intel_output->ddc_bus = digital_ddc_bus;
+               intel_encoder->ddc_bus = digital_ddc_bus;
        }
 }
 
@@ -1816,7 +1821,7 @@ struct drm_display_mode sdvo_tv_modes[] = {
 
 static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 {
-       struct intel_output *output = to_intel_output(connector);
+       struct intel_encoder *output = to_intel_encoder(connector);
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
        struct intel_sdvo_sdtv_resolution_request tv_res;
        uint32_t reply = 0, format_map = 0;
@@ -1858,9 +1863,9 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
 
 static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
        struct drm_i915_private *dev_priv = connector->dev->dev_private;
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct drm_display_mode *newmode;
 
        /*
@@ -1868,7 +1873,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
         * Assume that the preferred modes are
         * arranged in priority order.
         */
-       intel_ddc_get_modes(intel_output);
+       intel_ddc_get_modes(intel_encoder);
        if (list_empty(&connector->probed_modes) == false)
                goto end;
 
@@ -1897,7 +1902,7 @@ end:
 
 static int intel_sdvo_get_modes(struct drm_connector *connector)
 {
-       struct intel_output *output = to_intel_output(connector);
+       struct intel_encoder *output = to_intel_encoder(connector);
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
 
        if (sdvo_priv->is_tv)
@@ -1915,8 +1920,8 @@ static int intel_sdvo_get_modes(struct drm_connector *connector)
 static
 void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct drm_device *dev = connector->dev;
 
        if (sdvo_priv->is_tv) {
@@ -1953,13 +1958,13 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector)
 
 static void intel_sdvo_destroy(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
 
-       if (intel_output->i2c_bus)
-               intel_i2c_destroy(intel_output->i2c_bus);
-       if (intel_output->ddc_bus)
-               intel_i2c_destroy(intel_output->ddc_bus);
+       if (intel_encoder->i2c_bus)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
+       if (intel_encoder->ddc_bus)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
        if (sdvo_priv->analog_ddc_bus)
                intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
 
@@ -1977,7 +1982,7 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
 
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 static int
@@ -1985,9 +1990,9 @@ intel_sdvo_set_property(struct drm_connector *connector,
                        struct drm_property *property,
                        uint64_t val)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = encoder->crtc;
        int ret = 0;
        bool changed = false;
@@ -2095,8 +2100,8 @@ intel_sdvo_set_property(struct drm_connector *connector,
                        sdvo_priv->cur_brightness = temp_value;
                }
                if (cmd) {
-                       intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2);
-                       status = intel_sdvo_read_response(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2);
+                       status = intel_sdvo_read_response(intel_encoder,
                                                                NULL, 0);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO command \n");
@@ -2191,7 +2196,7 @@ intel_sdvo_select_ddc_bus(struct intel_sdvo_priv *dev_priv)
 }
 
 static bool
-intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
+intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output)
 {
        struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
        uint8_t status;
@@ -2205,42 +2210,42 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output)
        return true;
 }
 
-static struct intel_output *
-intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan)
+static struct intel_encoder *
+intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan)
 {
        struct drm_device *dev = chan->drm_dev;
        struct drm_connector *connector;
-       struct intel_output *intel_output = NULL;
+       struct intel_encoder *intel_encoder = NULL;
 
        list_for_each_entry(connector,
                        &dev->mode_config.connector_list, head) {
-               if (to_intel_output(connector)->ddc_bus == &chan->adapter) {
-                       intel_output = to_intel_output(connector);
+               if (to_intel_encoder(connector)->ddc_bus == &chan->adapter) {
+                       intel_encoder = to_intel_encoder(connector);
                        break;
                }
        }
-       return intel_output;
+       return intel_encoder;
 }
 
 static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap,
                                  struct i2c_msg msgs[], int num)
 {
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_sdvo_priv *sdvo_priv;
        struct i2c_algo_bit_data *algo_data;
        const struct i2c_algorithm *algo;
 
        algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data;
-       intel_output =
-               intel_sdvo_chan_to_intel_output(
+       intel_encoder =
+               intel_sdvo_chan_to_intel_encoder(
                                (struct intel_i2c_chan *)(algo_data->data));
-       if (intel_output == NULL)
+       if (intel_encoder == NULL)
                return -EINVAL;
 
-       sdvo_priv = intel_output->dev_priv;
-       algo = intel_output->i2c_bus->algo;
+       sdvo_priv = intel_encoder->dev_priv;
+       algo = intel_encoder->i2c_bus->algo;
 
-       intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus);
+       intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus);
        return algo->master_xfer(i2c_adap, msgs, num);
 }
 
@@ -2249,12 +2254,12 @@ static struct i2c_algorithm intel_sdvo_i2c_bit_algo = {
 };
 
 static u8
-intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
+intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct sdvo_device_mapping *my_mapping, *other_mapping;
 
-       if (output_device == SDVOB) {
+       if (sdvo_reg == SDVOB) {
                my_mapping = &dev_priv->sdvo_mappings[0];
                other_mapping = &dev_priv->sdvo_mappings[1];
        } else {
@@ -2279,7 +2284,7 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
        /* No SDVO device info is found for another DVO port,
         * so use mapping assumption we had before BIOS parsing.
         */
-       if (output_device == SDVOB)
+       if (sdvo_reg == SDVOB)
                return 0x70;
        else
                return 0x72;
@@ -2305,15 +2310,15 @@ static struct dmi_system_id intel_sdvo_bad_tv[] = {
 };
 
 static bool
-intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
+intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags)
 {
-       struct drm_connector *connector = &intel_output->base;
-       struct drm_encoder *encoder = &intel_output->enc;
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct drm_connector *connector = &intel_encoder->base;
+       struct drm_encoder *encoder = &intel_encoder->enc;
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        bool ret = true, registered = false;
 
        sdvo_priv->is_tv = false;
-       intel_output->needs_tv_clock = false;
+       intel_encoder->needs_tv_clock = false;
        sdvo_priv->is_lvds = false;
 
        if (device_is_registered(&connector->kdev)) {
@@ -2331,16 +2336,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
                connector->connector_type = DRM_MODE_CONNECTOR_DVID;
 
-               if (intel_sdvo_get_supp_encode(intel_output,
+               if (intel_sdvo_get_supp_encode(intel_encoder,
                                               &sdvo_priv->encode) &&
-                   intel_sdvo_get_digital_encoding_mode(intel_output) &&
+                   intel_sdvo_get_digital_encoding_mode(intel_encoder) &&
                    sdvo_priv->is_hdmi) {
                        /* enable hdmi encoding mode if supported */
-                       intel_sdvo_set_encode(intel_output, SDVO_ENCODE_HDMI);
-                       intel_sdvo_set_colorimetry(intel_output,
+                       intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI);
+                       intel_sdvo_set_colorimetry(intel_encoder,
                                                   SDVO_COLORIMETRY_RGB256);
                        connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
-                       intel_output->clone_mask =
+                       intel_encoder->clone_mask =
                                        (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
                }
@@ -2351,21 +2356,21 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
                connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
-               intel_output->needs_tv_clock = true;
-               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+               intel_encoder->needs_tv_clock = true;
+               intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
        } else if (flags & SDVO_OUTPUT_RGB0) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
                encoder->encoder_type = DRM_MODE_ENCODER_DAC;
                connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_RGB1) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
                encoder->encoder_type = DRM_MODE_ENCODER_DAC;
                connector->connector_type = DRM_MODE_CONNECTOR_VGA;
-               intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
                                        (1 << INTEL_ANALOG_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_CVBS0) {
 
@@ -2373,15 +2378,15 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
                connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
                sdvo_priv->is_tv = true;
-               intel_output->needs_tv_clock = true;
-               intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
+               intel_encoder->needs_tv_clock = true;
+               intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
        } else if (flags & SDVO_OUTPUT_LVDS0) {
 
                sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
-               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
                                        (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else if (flags & SDVO_OUTPUT_LVDS1) {
 
@@ -2389,7 +2394,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
                connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
                sdvo_priv->is_lvds = true;
-               intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
+               intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
                                        (1 << INTEL_SDVO_LVDS_CLONE_BIT);
        } else {
 
@@ -2402,7 +2407,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
                              bytes[0], bytes[1]);
                ret = false;
        }
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 
        if (ret && registered)
                ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
@@ -2414,18 +2419,18 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
 
 static void intel_sdvo_tv_create_property(struct drm_connector *connector)
 {
-      struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+      struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct intel_sdvo_tv_format format;
        uint32_t format_map, i;
        uint8_t status;
 
-       intel_sdvo_set_target_output(intel_output,
+       intel_sdvo_set_target_output(intel_encoder,
                                     sdvo_priv->controlled_output);
 
-       intel_sdvo_write_cmd(intel_output,
+       intel_sdvo_write_cmd(intel_encoder,
                             SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0);
-       status = intel_sdvo_read_response(intel_output,
+       status = intel_sdvo_read_response(intel_encoder,
                                          &format, sizeof(format));
        if (status != SDVO_CMD_STATUS_SUCCESS)
                return;
@@ -2463,16 +2468,16 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector)
 
 static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv;
        struct intel_sdvo_enhancements_reply sdvo_data;
        struct drm_device *dev = connector->dev;
        uint8_t status;
        uint16_t response, data_value[2];
 
-       intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
+       intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS,
                                                NULL, 0);
-       status = intel_sdvo_read_response(intel_output, &sdvo_data,
+       status = intel_sdvo_read_response(intel_encoder, &sdvo_data,
                                        sizeof(sdvo_data));
        if (status != SDVO_CMD_STATUS_SUCCESS) {
                DRM_DEBUG_KMS(" incorrect response is returned\n");
@@ -2488,18 +2493,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                 * property
                 */
                if (sdvo_data.overscan_h) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO max "
                                                "h_overscan\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_OVERSCAN_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n");
@@ -2529,18 +2534,18 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.overscan_v) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO max "
                                                "v_overscan\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_OVERSCAN_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n");
@@ -2570,17 +2575,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.position_h) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_POSITION_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_POSITION_H, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n");
@@ -2601,17 +2606,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.position_v) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_POSITION_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_POSITION_V, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n");
@@ -2634,17 +2639,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        }
        if (sdvo_priv->is_tv) {
                if (sdvo_data.saturation) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_SATURATION, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max sat\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_SATURATION, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get sat\n");
@@ -2666,17 +2671,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.contrast) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_CONTRAST, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_CONTRAST, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get contrast\n");
@@ -2697,17 +2702,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
                                        data_value[0], data_value[1], response);
                }
                if (sdvo_data.hue) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_HUE, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max hue\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_HUE, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get hue\n");
@@ -2730,17 +2735,17 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        }
        if (sdvo_priv->is_tv || sdvo_priv->is_lvds) {
                if (sdvo_data.brightness) {
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &data_value, 4);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO Max bright\n");
                                return;
                        }
-                       intel_sdvo_write_cmd(intel_output,
+                       intel_sdvo_write_cmd(intel_encoder,
                                SDVO_CMD_GET_BRIGHTNESS, NULL, 0);
-                       status = intel_sdvo_read_response(intel_output,
+                       status = intel_sdvo_read_response(intel_encoder,
                                &response, 2);
                        if (status != SDVO_CMD_STATUS_SUCCESS) {
                                DRM_DEBUG_KMS("Incorrect SDVO get brigh\n");
@@ -2765,81 +2770,81 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector)
        return;
 }
 
-bool intel_sdvo_init(struct drm_device *dev, int output_device)
+bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_sdvo_priv *sdvo_priv;
 
        u8 ch[0x40];
        int i;
 
-       intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
-       if (!intel_output) {
+       intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
+       if (!intel_encoder) {
                return false;
        }
 
-       sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
-       sdvo_priv->output_device = output_device;
+       sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1);
+       sdvo_priv->sdvo_reg = sdvo_reg;
 
-       intel_output->dev_priv = sdvo_priv;
-       intel_output->type = INTEL_OUTPUT_SDVO;
+       intel_encoder->dev_priv = sdvo_priv;
+       intel_encoder->type = INTEL_OUTPUT_SDVO;
 
        /* setup the DDC bus. */
-       if (output_device == SDVOB)
-               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
+       if (sdvo_reg == SDVOB)
+               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
        else
-               intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
+               intel_encoder->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
 
-       if (!intel_output->i2c_bus)
+       if (!intel_encoder->i2c_bus)
                goto err_inteloutput;
 
-       sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device);
+       sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg);
 
        /* Save the bit-banging i2c functionality for use by the DDC wrapper */
-       intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality;
+       intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality;
 
        /* Read the regs to test if we can talk to the device */
        for (i = 0; i < 0x40; i++) {
-               if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
+               if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) {
                        DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n",
-                                       output_device == SDVOB ? 'B' : 'C');
+                                       sdvo_reg == SDVOB ? 'B' : 'C');
                        goto err_i2c;
                }
        }
 
        /* setup the DDC bus. */
-       if (output_device == SDVOB) {
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
+       if (sdvo_reg == SDVOB) {
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
                sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
                                                "SDVOB/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
        } else {
-               intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+               intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
                sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA,
                                                "SDVOC/VGA DDC BUS");
                dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
        }
 
-       if (intel_output->ddc_bus == NULL)
+       if (intel_encoder->ddc_bus == NULL)
                goto err_i2c;
 
        /* Wrap with our custom algo which switches to DDC mode */
-       intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
+       intel_encoder->ddc_bus->algo = &intel_sdvo_i2c_bit_algo;
 
        /* In default case sdvo lvds is false */
-       intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
+       intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps);
 
-       if (intel_sdvo_output_setup(intel_output,
+       if (intel_sdvo_output_setup(intel_encoder,
                                    sdvo_priv->caps.output_flags) != true) {
                DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n",
-                         output_device == SDVOB ? 'B' : 'C');
+                         sdvo_reg == SDVOB ? 'B' : 'C');
                goto err_i2c;
        }
 
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
        drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
                           connector->connector_type);
 
@@ -2848,12 +2853,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        connector->doublescan_allowed = 0;
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 
-       drm_encoder_init(dev, &intel_output->enc,
-                       &intel_sdvo_enc_funcs, intel_output->enc.encoder_type);
+       drm_encoder_init(dev, &intel_encoder->enc,
+                       &intel_sdvo_enc_funcs, intel_encoder->enc.encoder_type);
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
        if (sdvo_priv->is_tv)
                intel_sdvo_tv_create_property(connector);
 
@@ -2865,9 +2870,9 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
        intel_sdvo_select_ddc_bus(sdvo_priv);
 
        /* Set the input timing to the screen. Assume always input 0. */
-       intel_sdvo_set_target_input(intel_output, true, false);
+       intel_sdvo_set_target_input(intel_encoder, true, false);
 
-       intel_sdvo_get_input_pixel_clock_range(intel_output,
+       intel_sdvo_get_input_pixel_clock_range(intel_encoder,
                                               &sdvo_priv->pixel_clock_min,
                                               &sdvo_priv->pixel_clock_max);
 
@@ -2894,12 +2899,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 err_i2c:
        if (sdvo_priv->analog_ddc_bus != NULL)
                intel_i2c_destroy(sdvo_priv->analog_ddc_bus);
-       if (intel_output->ddc_bus != NULL)
-               intel_i2c_destroy(intel_output->ddc_bus);
-       if (intel_output->i2c_bus != NULL)
-               intel_i2c_destroy(intel_output->i2c_bus);
+       if (intel_encoder->ddc_bus != NULL)
+               intel_i2c_destroy(intel_encoder->ddc_bus);
+       if (intel_encoder->i2c_bus != NULL)
+               intel_i2c_destroy(intel_encoder->i2c_bus);
 err_inteloutput:
-       kfree(intel_output);
+       kfree(intel_encoder);
 
        return false;
 }
index 552ec11..d7d39b2 100644 (file)
@@ -921,8 +921,8 @@ intel_tv_save(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
        int i;
 
        tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1);
@@ -971,8 +971,8 @@ intel_tv_restore(struct drm_connector *connector)
 {
        struct drm_device *dev = connector->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
        struct drm_crtc *crtc = connector->encoder->crtc;
        struct intel_crtc *intel_crtc;
        int i;
@@ -1068,9 +1068,9 @@ intel_tv_mode_lookup (char *tv_format)
 }
 
 static const struct tv_mode *
-intel_tv_mode_find (struct intel_output *intel_output)
+intel_tv_mode_find (struct intel_encoder *intel_encoder)
 {
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
 
        return intel_tv_mode_lookup(tv_priv->tv_format);
 }
@@ -1078,8 +1078,8 @@ intel_tv_mode_find (struct intel_output *intel_output)
 static enum drm_mode_status
 intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
        /* Ensure TV refresh is close to desired refresh */
        if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
@@ -1095,8 +1095,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
 {
        struct drm_device *dev = encoder->dev;
        struct drm_mode_config *drm_config = &dev->mode_config;
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder);
        struct drm_encoder *other_encoder;
 
        if (!tv_mode)
@@ -1121,9 +1121,9 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc = encoder->crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_output *intel_output = enc_to_intel_output(encoder);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        u32 tv_ctl;
        u32 hctl1, hctl2, hctl3;
        u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1360,9 +1360,9 @@ static const struct drm_display_mode reported_modes[] = {
  * \return false if TV is disconnected.
  */
 static int
-intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
+intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder)
 {
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_device *dev = encoder->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long irqflags;
@@ -1441,9 +1441,9 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
  */
 static void intel_tv_find_better_format(struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        int i;
 
        if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) ==
@@ -1475,9 +1475,9 @@ intel_tv_detect(struct drm_connector *connector)
 {
        struct drm_crtc *crtc;
        struct drm_display_mode mode;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        int dpms_mode;
        int type = tv_priv->type;
 
@@ -1485,12 +1485,12 @@ intel_tv_detect(struct drm_connector *connector)
        drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
 
        if (encoder->crtc && encoder->crtc->enabled) {
-               type = intel_tv_detect_type(encoder->crtc, intel_output);
+               type = intel_tv_detect_type(encoder->crtc, intel_encoder);
        } else {
-               crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
+               crtc = intel_get_load_detect_pipe(intel_encoder, &mode, &dpms_mode);
                if (crtc) {
-                       type = intel_tv_detect_type(crtc, intel_output);
-                       intel_release_load_detect_pipe(intel_output, dpms_mode);
+                       type = intel_tv_detect_type(crtc, intel_encoder);
+                       intel_release_load_detect_pipe(intel_encoder, dpms_mode);
                } else
                        type = -1;
        }
@@ -1525,8 +1525,8 @@ static void
 intel_tv_chose_preferred_modes(struct drm_connector *connector,
                               struct drm_display_mode *mode_ptr)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
 
        if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480)
                mode_ptr->type |= DRM_MODE_TYPE_PREFERRED;
@@ -1550,8 +1550,8 @@ static int
 intel_tv_get_modes(struct drm_connector *connector)
 {
        struct drm_display_mode *mode_ptr;
-       struct intel_output *intel_output = to_intel_output(connector);
-       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder);
        int j, count = 0;
        u64 tmp;
 
@@ -1604,11 +1604,11 @@ intel_tv_get_modes(struct drm_connector *connector)
 static void
 intel_tv_destroy (struct drm_connector *connector)
 {
-       struct intel_output *intel_output = to_intel_output(connector);
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
 
        drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
-       kfree(intel_output);
+       kfree(intel_encoder);
 }
 
 
@@ -1617,9 +1617,9 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
                      uint64_t val)
 {
        struct drm_device *dev = connector->dev;
-       struct intel_output *intel_output = to_intel_output(connector);
-       struct intel_tv_priv *tv_priv = intel_output->dev_priv;
-       struct drm_encoder *encoder = &intel_output->enc;
+       struct intel_encoder *intel_encoder = to_intel_encoder(connector);
+       struct intel_tv_priv *tv_priv = intel_encoder->dev_priv;
+       struct drm_encoder *encoder = &intel_encoder->enc;
        struct drm_crtc *crtc = encoder->crtc;
        int ret = 0;
        bool changed = false;
@@ -1740,7 +1740,7 @@ intel_tv_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_connector *connector;
-       struct intel_output *intel_output;
+       struct intel_encoder *intel_encoder;
        struct intel_tv_priv *tv_priv;
        u32 tv_dac_on, tv_dac_off, save_tv_dac;
        char **tv_format_names;
@@ -1780,28 +1780,28 @@ intel_tv_init(struct drm_device *dev)
            (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
                return;
 
-       intel_output = kzalloc(sizeof(struct intel_output) +
+       intel_encoder = kzalloc(sizeof(struct intel_encoder) +
                               sizeof(struct intel_tv_priv), GFP_KERNEL);
-       if (!intel_output) {
+       if (!intel_encoder) {
                return;
        }
 
-       connector = &intel_output->base;
+       connector = &intel_encoder->base;
 
        drm_connector_init(dev, connector, &intel_tv_connector_funcs,
                           DRM_MODE_CONNECTOR_SVIDEO);
 
-       drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
+       drm_encoder_init(dev, &intel_encoder->enc, &intel_tv_enc_funcs,
                         DRM_MODE_ENCODER_TVDAC);
 
-       drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
-       tv_priv = (struct intel_tv_priv *)(intel_output + 1);
-       intel_output->type = INTEL_OUTPUT_TVOUT;
-       intel_output->crtc_mask = (1 << 0) | (1 << 1);
-       intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
-       intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
-       intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
-       intel_output->dev_priv = tv_priv;
+       drm_mode_connector_attach_encoder(&intel_encoder->base, &intel_encoder->enc);
+       tv_priv = (struct intel_tv_priv *)(intel_encoder + 1);
+       intel_encoder->type = INTEL_OUTPUT_TVOUT;
+       intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
+       intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT);
+       intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1));
+       intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
+       intel_encoder->dev_priv = tv_priv;
        tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
 
        /* BIOS margin values */
@@ -1812,7 +1812,7 @@ intel_tv_init(struct drm_device *dev)
 
        tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
 
-       drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
+       drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs);
        drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
index 7f0d807..453df3f 100644 (file)
@@ -22,7 +22,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
              nv50_cursor.o nv50_display.o nv50_fbcon.o \
              nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \
              nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \
-             nv17_gpio.o
+             nv17_gpio.o nv50_gpio.o
 
 nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o
 nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
index b5a9336..abc382a 100644 (file)
@@ -2573,48 +2573,34 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
         * each GPIO according to various values listed in each entry
         */
 
-       const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+       struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
        const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
-       const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr];
-       const uint8_t *gpio_entry;
        int i;
 
-       if (!iexec->execute)
-               return 1;
-
-       if (bios->dcb.version != 0x40) {
-               NV_ERROR(bios->dev, "DCB table not version 4.0\n");
-               return 0;
-       }
-
-       if (!bios->dcb.gpio_table_ptr) {
-               NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n");
-               return 0;
+       if (dev_priv->card_type != NV_50) {
+               NV_ERROR(bios->dev, "INIT_GPIO on unsupported chipset\n");
+               return -ENODEV;
        }
 
-       gpio_entry = gpio_table + gpio_table[1];
-       for (i = 0; i < gpio_table[2]; i++, gpio_entry += gpio_table[3]) {
-               uint32_t entry = ROM32(gpio_entry[0]), r, s, v;
-               int line = (entry & 0x0000001f);
+       if (!iexec->execute)
+               return 1;
 
-               BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, entry);
+       for (i = 0; i < bios->dcb.gpio.entries; i++) {
+               struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i];
+               uint32_t r, s, v;
 
-               if ((entry & 0x0000ff00) == 0x0000ff00)
-                       continue;
+               BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
 
-               r = nv50_gpio_reg[line >> 3];
-               s = (line & 0x07) << 2;
-               v = bios_rd32(bios, r) & ~(0x00000003 << s);
-               if (entry & 0x01000000)
-                       v |= (((entry & 0x60000000) >> 29) ^ 2) << s;
-               else
-                       v |= (((entry & 0x18000000) >> 27) ^ 2) << s;
-               bios_wr32(bios, r, v);
+               nv50_gpio_set(bios->dev, gpio->tag, gpio->state_default);
 
-               r = nv50_gpio_ctl[line >> 4];
-               s = (line & 0x0f);
+               /* The NVIDIA binary driver doesn't appear to actually do
+                * any of this, my VBIOS does however.
+                */
+               /* Not a clue, needs de-magicing */
+               r = nv50_gpio_ctl[gpio->line >> 4];
+               s = (gpio->line & 0x0f);
                v = bios_rd32(bios, r) & ~(0x00010001 << s);
-               switch ((entry & 0x06000000) >> 25) {
+               switch ((gpio->entry & 0x06000000) >> 25) {
                case 1:
                        v |= (0x00000001 << s);
                        break;
@@ -3198,7 +3184,6 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
        struct nvbios *bios = &dev_priv->vbios;
        unsigned int outputset = (dcbent->or == 4) ? 1 : 0;
        uint16_t scriptptr = 0, clktable;
-       uint8_t clktableptr = 0;
 
        /*
         * For now we assume version 3.0 table - g80 support will need some
@@ -3217,26 +3202,29 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int
                scriptptr = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 11 + outputset * 2]);
                break;
        case LVDS_RESET:
+               clktable = bios->fp.lvdsmanufacturerpointer + 15;
+               if (dcbent->or == 4)
+                       clktable += 8;
+
                if (dcbent->lvdsconf.use_straps_for_mode) {
                        if (bios->fp.dual_link)
-                               clktableptr += 2;
-                       if (bios->fp.BITbit1)
-                               clktableptr++;
+                               clktable += 4;
+                       if (bios->fp.if_is_24bit)
+                               clktable += 2;
                } else {
                        /* using EDID */
-                       uint8_t fallback = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
-                       int fallbackcmpval = (dcbent->or == 4) ? 4 : 1;
+                       int cmpval_24bit = (dcbent->or == 4) ? 4 : 1;
 
                        if (bios->fp.dual_link) {
-                               clktableptr += 2;
-                               fallbackcmpval *= 2;
+                               clktable += 4;
+                               cmpval_24bit <<= 1;
                        }
-                       if (fallbackcmpval & fallback)
-                               clktableptr++;
+
+                       if (bios->fp.strapless_is_24bit & cmpval_24bit)
+                               clktable += 2;
                }
 
-               /* adding outputset * 8 may not be correct */
-               clktable = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 15 + clktableptr * 2 + outputset * 8]);
+               clktable = ROM16(bios->data[clktable]);
                if (!clktable) {
                        NV_ERROR(dev, "Pixel clock comparison table not found\n");
                        return -ENOENT;
@@ -3638,37 +3626,40 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
                *if_is_24bit = bios->data[lvdsofs] & 16;
                break;
        case 0x30:
-               /*
-                * My money would be on there being a 24 bit interface bit in
-                * this table, but I have no example of a laptop bios with a
-                * 24 bit panel to confirm that. Hence we shout loudly if any
-                * bit other than bit 0 is set (I've not even seen bit 1)
-                */
-               if (bios->data[lvdsofs] > 1)
-                       NV_ERROR(dev,
-                                "You have a very unusual laptop display; please report it\n");
+       case 0x40:
                /*
                 * No sign of the "power off for reset" or "reset for panel
                 * on" bits, but it's safer to assume we should
                 */
                bios->fp.power_off_for_reset = true;
                bios->fp.reset_after_pclk_change = true;
+
                /*
                 * It's ok lvdsofs is wrong for nv4x edid case; dual_link is
-                * over-written, and BITbit1 isn't used
+                * over-written, and if_is_24bit isn't used
                 */
                bios->fp.dual_link = bios->data[lvdsofs] & 1;
-               bios->fp.BITbit1 = bios->data[lvdsofs] & 2;
-               bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
-               break;
-       case 0x40:
-               bios->fp.dual_link = bios->data[lvdsofs] & 1;
                bios->fp.if_is_24bit = bios->data[lvdsofs] & 2;
                bios->fp.strapless_is_24bit = bios->data[bios->fp.lvdsmanufacturerpointer + 4];
                bios->fp.duallink_transition_clk = ROM16(bios->data[bios->fp.lvdsmanufacturerpointer + 5]) * 10;
                break;
        }
 
+       /* Dell Latitude D620 reports a too-high value for the dual-link
+        * transition freq, causing us to program the panel incorrectly.
+        *
+        * It doesn't appear the VBIOS actually uses its transition freq
+        * (90000kHz), instead it uses the "Number of LVDS channels" field
+        * out of the panel ID structure (http://www.spwg.org/).
+        *
+        * For the moment, a quirk will do :)
+        */
+       if ((dev->pdev->device == 0x01d7) &&
+           (dev->pdev->subsystem_vendor == 0x1028) &&
+           (dev->pdev->subsystem_device == 0x01c2)) {
+               bios->fp.duallink_transition_clk = 80000;
+       }
+
        /* set dual_link flag for EDID case */
        if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
                bios->fp.dual_link = (pxclk >= bios->fp.duallink_transition_clk);
@@ -5077,25 +5068,25 @@ parse_dcb30_gpio_entry(struct nvbios *bios, uint16_t offset)
        gpio->tag = tag;
        gpio->line = line;
        gpio->invert = flags != 4;
+       gpio->entry = ent;
 }
 
 static void
 parse_dcb40_gpio_entry(struct nvbios *bios, uint16_t offset)
 {
+       uint32_t entry = ROM32(bios->data[offset]);
        struct dcb_gpio_entry *gpio;
-       uint32_t ent = ROM32(bios->data[offset]);
-       uint8_t line = ent & 0x1f,
-               tag = ent >> 8 & 0xff;
 
-       if (tag == 0xff)
+       if ((entry & 0x0000ff00) == 0x0000ff00)
                return;
 
        gpio = new_gpio_entry(bios);
-
-       /* Currently unused, we may need more fields parsed at some
-        * point. */
-       gpio->tag = tag;
-       gpio->line = line;
+       gpio->tag = (entry & 0x0000ff00) >> 8;
+       gpio->line = (entry & 0x0000001f) >> 0;
+       gpio->state_default = (entry & 0x01000000) >> 24;
+       gpio->state[0] = (entry & 0x18000000) >> 27;
+       gpio->state[1] = (entry & 0x60000000) >> 29;
+       gpio->entry = entry;
 }
 
 static void
index 4f88e69..c0d7b0a 100644 (file)
@@ -49,6 +49,9 @@ struct dcb_gpio_entry {
        enum dcb_gpio_tag tag;
        int line;
        bool invert;
+       uint32_t entry;
+       uint8_t state_default;
+       uint8_t state[2];
 };
 
 struct dcb_gpio_table {
@@ -267,7 +270,6 @@ struct nvbios {
                bool reset_after_pclk_change;
                bool dual_link;
                bool link_c_increment;
-               bool BITbit1;
                bool if_is_24bit;
                int duallink_transition_clk;
                uint8_t strapless_is_24bit;
index 9042dd7..957d176 100644 (file)
@@ -72,7 +72,7 @@ nouveau_bo_fixup_align(struct drm_device *dev,
         * many small buffers.
         */
        if (dev_priv->card_type == NV_50) {
-               uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15;
+               uint32_t block_size = dev_priv->vram_size >> 15;
                int i;
 
                switch (tile_flags) {
@@ -154,7 +154,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
 
        nvbo->placement.fpfn = 0;
        nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0;
-       nouveau_bo_placement_set(nvbo, flags);
+       nouveau_bo_placement_set(nvbo, flags, 0);
 
        nvbo->channel = chan;
        ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
@@ -173,26 +173,33 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
        return 0;
 }
 
+static void
+set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
+{
+       *n = 0;
+
+       if (type & TTM_PL_FLAG_VRAM)
+               pl[(*n)++] = TTM_PL_FLAG_VRAM | flags;
+       if (type & TTM_PL_FLAG_TT)
+               pl[(*n)++] = TTM_PL_FLAG_TT | flags;
+       if (type & TTM_PL_FLAG_SYSTEM)
+               pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
+}
+
 void
-nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype)
+nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
 {
-       int n = 0;
-
-       if (memtype & TTM_PL_FLAG_VRAM)
-               nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING;
-       if (memtype & TTM_PL_FLAG_TT)
-               nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
-       if (memtype & TTM_PL_FLAG_SYSTEM)
-               nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING;
-       nvbo->placement.placement = nvbo->placements;
-       nvbo->placement.busy_placement = nvbo->placements;
-       nvbo->placement.num_placement = n;
-       nvbo->placement.num_busy_placement = n;
-
-       if (nvbo->pin_refcnt) {
-               while (n--)
-                       nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT;
-       }
+       struct ttm_placement *pl = &nvbo->placement;
+       uint32_t flags = TTM_PL_MASK_CACHING |
+               (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0);
+
+       pl->placement = nvbo->placements;
+       set_placement_list(nvbo->placements, &pl->num_placement,
+                          type, flags);
+
+       pl->busy_placement = nvbo->busy_placements;
+       set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
+                          type | busy, flags);
 }
 
 int
@@ -200,7 +207,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
 {
        struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_buffer_object *bo = &nvbo->bo;
-       int ret, i;
+       int ret;
 
        if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
                NV_ERROR(nouveau_bdev(bo->bdev)->dev,
@@ -216,9 +223,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
        if (ret)
                goto out;
 
-       nouveau_bo_placement_set(nvbo, memtype);
-       for (i = 0; i < nvbo->placement.num_placement; i++)
-               nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT;
+       nouveau_bo_placement_set(nvbo, memtype, 0);
 
        ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
        if (ret == 0) {
@@ -245,7 +250,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
 {
        struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
        struct ttm_buffer_object *bo = &nvbo->bo;
-       int ret, i;
+       int ret;
 
        if (--nvbo->pin_refcnt)
                return 0;
@@ -254,8 +259,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
        if (ret)
                return ret;
 
-       for (i = 0; i < nvbo->placement.num_placement; i++)
-               nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
+       nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
 
        ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
        if (ret == 0) {
@@ -396,8 +400,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
                man->io_addr = NULL;
                man->io_offset = drm_get_resource_start(dev, 1);
                man->io_size = drm_get_resource_len(dev, 1);
-               if (man->io_size > nouveau_mem_fb_amount(dev))
-                       man->io_size = nouveau_mem_fb_amount(dev);
+               if (man->io_size > dev_priv->vram_size)
+                       man->io_size = dev_priv->vram_size;
 
                man->gpu_offset = dev_priv->vm_vram_base;
                break;
@@ -440,10 +444,11 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
 
        switch (bo->mem.mem_type) {
        case TTM_PL_VRAM:
-               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT);
+               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT,
+                                        TTM_PL_FLAG_SYSTEM);
                break;
        default:
-               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
+               nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0);
                break;
        }
 
index 6dfb425..1fc57ef 100644 (file)
@@ -142,7 +142,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
                                           GFP_KERNEL);
        if (!dev_priv->fifos[channel])
                return -ENOMEM;
-       dev_priv->fifo_alloc_count++;
        chan = dev_priv->fifos[channel];
        INIT_LIST_HEAD(&chan->nvsw.vbl_wait);
        INIT_LIST_HEAD(&chan->fence.pending);
@@ -321,7 +320,6 @@ nouveau_channel_free(struct nouveau_channel *chan)
                iounmap(chan->user);
 
        dev_priv->fifos[chan->id] = NULL;
-       dev_priv->fifo_alloc_count--;
        kfree(chan);
 }
 
index 8ff9ef5..a251886 100644 (file)
@@ -137,10 +137,9 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data)
 {
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_minor *minor = node->minor;
-       struct drm_device *dev = minor->dev;
+       struct drm_nouveau_private *dev_priv = minor->dev->dev_private;
 
-       seq_printf(m, "VRAM total: %dKiB\n",
-                  (int)(nouveau_mem_fb_amount(dev) >> 10));
+       seq_printf(m, "VRAM total: %dKiB\n", (int)(dev_priv->vram_size >> 10));
        return 0;
 }
 
index f954ad9..deeb21c 100644 (file)
@@ -483,7 +483,7 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
        ctrl |= (cmd << NV50_AUXCH_CTRL_CMD_SHIFT);
        ctrl |= ((data_nr - 1) << NV50_AUXCH_CTRL_LEN_SHIFT);
 
-       for (;;) {
+       for (i = 0; i < 16; i++) {
                nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x80000000);
                nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl);
                nv_wr32(dev, NV50_AUXCH_CTRL(index), ctrl | 0x00010000);
@@ -502,6 +502,12 @@ nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
                        break;
        }
 
+       if (i == 16) {
+               NV_ERROR(dev, "auxch DEFER too many times, bailing\n");
+               ret = -EREMOTEIO;
+               goto out;
+       }
+
        if (cmd & 1) {
                if ((stat & NV50_AUXCH_STAT_COUNT) != data_nr) {
                        ret = -EREMOTEIO;
index d8b5590..ace630a 100644 (file)
@@ -76,6 +76,7 @@ struct nouveau_bo {
        struct ttm_buffer_object bo;
        struct ttm_placement placement;
        u32 placements[3];
+       u32 busy_placements[3];
        struct ttm_bo_kmap_obj kmap;
        struct list_head head;
 
@@ -519,6 +520,7 @@ struct drm_nouveau_private {
 
        struct workqueue_struct *wq;
        struct work_struct irq_work;
+       struct work_struct hpd_work;
 
        struct list_head vbl_waiting;
 
@@ -533,7 +535,6 @@ struct drm_nouveau_private {
 
        struct fb_info *fbdev_info;
 
-       int fifo_alloc_count;
        struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR];
 
        struct nouveau_engine engine;
@@ -553,12 +554,6 @@ struct drm_nouveau_private {
        uint32_t ramro_offset;
        uint32_t ramro_size;
 
-       /* base physical addresses */
-       uint64_t fb_phys;
-       uint64_t fb_available_size;
-       uint64_t fb_mappable_pages;
-       uint64_t fb_aper_free;
-
        struct {
                enum {
                        NOUVEAU_GART_NONE = 0,
@@ -572,10 +567,6 @@ struct drm_nouveau_private {
                struct nouveau_gpuobj *sg_ctxdma;
                struct page *sg_dummy_page;
                dma_addr_t sg_dummy_bus;
-
-               /* nottm hack */
-               struct drm_ttm_backend *sg_be;
-               unsigned long sg_handle;
        } gart_info;
 
        /* nv10-nv40 tiling regions */
@@ -584,6 +575,16 @@ struct drm_nouveau_private {
                spinlock_t lock;
        } tile;
 
+       /* VRAM/fb configuration */
+       uint64_t vram_size;
+       uint64_t vram_sys_base;
+
+       uint64_t fb_phys;
+       uint64_t fb_available_size;
+       uint64_t fb_mappable_pages;
+       uint64_t fb_aper_free;
+       int fb_mtrr;
+
        /* G8x/G9x virtual address space */
        uint64_t vm_gart_base;
        uint64_t vm_gart_size;
@@ -592,10 +593,6 @@ struct drm_nouveau_private {
        uint64_t vm_end;
        struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
        int vm_vram_pt_nr;
-       uint64_t vram_sys_base;
-
-       /* the mtrr covering the FB */
-       int fb_mtrr;
 
        struct mem_block *ramin_heap;
 
@@ -614,11 +611,7 @@ struct drm_nouveau_private {
        uint32_t dac_users[4];
 
        struct nouveau_suspend_resume {
-               uint32_t fifo_mode;
-               uint32_t graph_ctx_control;
-               uint32_t graph_state;
                uint32_t *ramin_copy;
-               uint64_t ramin_size;
        } susres;
 
        struct backlight_device *backlight;
@@ -717,7 +710,7 @@ extern struct mem_block *nouveau_mem_alloc_block(struct mem_block *,
                                                 struct drm_file *, int tail);
 extern void nouveau_mem_takedown(struct mem_block **heap);
 extern void nouveau_mem_free_block(struct mem_block *);
-extern uint64_t nouveau_mem_fb_amount(struct drm_device *);
+extern int  nouveau_mem_detect(struct drm_device *dev);
 extern void nouveau_mem_release(struct drm_file *, struct mem_block *heap);
 extern int  nouveau_mem_init(struct drm_device *);
 extern int  nouveau_mem_init_agp(struct drm_device *);
@@ -1124,7 +1117,8 @@ extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
 extern int nouveau_bo_unpin(struct nouveau_bo *);
 extern int nouveau_bo_map(struct nouveau_bo *);
 extern void nouveau_bo_unmap(struct nouveau_bo *);
-extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype);
+extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type,
+                                    uint32_t busy);
 extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
 extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
 extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
@@ -1168,6 +1162,10 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
 int nv17_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
 int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
 
+/* nv50_gpio.c */
+int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
+int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+
 #ifndef ioread32_native
 #ifdef __BIG_ENDIAN
 #define ioread16_native ioread16be
index bc4a240..9f28b94 100644 (file)
@@ -47,6 +47,7 @@ struct nouveau_encoder {
 
        union {
                struct {
+                       int mc_unknown;
                        int dpcd_version;
                        int link_nr;
                        int link_bw;
index 0d22f66..1bc0b38 100644 (file)
@@ -180,40 +180,35 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
 {
        struct nouveau_bo *nvbo = gem->driver_private;
        struct ttm_buffer_object *bo = &nvbo->bo;
-       uint64_t flags;
+       uint32_t domains = valid_domains &
+               (write_domains ? write_domains : read_domains);
+       uint32_t pref_flags = 0, valid_flags = 0;
 
-       if (!valid_domains || (!read_domains && !write_domains))
+       if (!domains)
                return -EINVAL;
 
-       if (write_domains) {
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   (write_domains & NOUVEAU_GEM_DOMAIN_VRAM))
-                       flags = TTM_PL_FLAG_VRAM;
-               else
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-                   (write_domains & NOUVEAU_GEM_DOMAIN_GART))
-                       flags = TTM_PL_FLAG_TT;
-               else
-                       return -EINVAL;
-       } else {
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   bo->mem.mem_type == TTM_PL_VRAM)
-                       flags = TTM_PL_FLAG_VRAM;
-               else
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-                   (read_domains & NOUVEAU_GEM_DOMAIN_GART) &&
-                   bo->mem.mem_type == TTM_PL_TT)
-                       flags = TTM_PL_FLAG_TT;
-               else
-               if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
-                   (read_domains & NOUVEAU_GEM_DOMAIN_VRAM))
-                       flags = TTM_PL_FLAG_VRAM;
-               else
-                       flags = TTM_PL_FLAG_TT;
-       }
+       if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
+               valid_flags |= TTM_PL_FLAG_VRAM;
+
+       if (valid_domains & NOUVEAU_GEM_DOMAIN_GART)
+               valid_flags |= TTM_PL_FLAG_TT;
+
+       if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
+           bo->mem.mem_type == TTM_PL_VRAM)
+               pref_flags |= TTM_PL_FLAG_VRAM;
+
+       else if ((domains & NOUVEAU_GEM_DOMAIN_GART) &&
+                bo->mem.mem_type == TTM_PL_TT)
+               pref_flags |= TTM_PL_FLAG_TT;
+
+       else if (domains & NOUVEAU_GEM_DOMAIN_VRAM)
+               pref_flags |= TTM_PL_FLAG_VRAM;
+
+       else
+               pref_flags |= TTM_PL_FLAG_TT;
+
+       nouveau_bo_placement_set(nvbo, pref_flags, valid_flags);
 
-       nouveau_bo_placement_set(nvbo, flags);
        return 0;
 }
 
index 2bd59a9..13e73ce 100644 (file)
@@ -51,6 +51,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
 
        if (dev_priv->card_type == NV_50) {
                INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
+               INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
                INIT_LIST_HEAD(&dev_priv->vbl_waiting);
        }
 }
index 2dc09db..775a701 100644 (file)
@@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
                return -EBUSY;
        }
 
+       nv_wr32(dev, 0x100c80, 0x00040001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return -EBUSY;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00060001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return -EBUSY;
+       }
+
        return 0;
 }
 
@@ -387,6 +401,20 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
        if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
                NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
                NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00040001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00060001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
        }
 }
 
@@ -449,9 +477,30 @@ void nouveau_mem_close(struct drm_device *dev)
        }
 }
 
-/*XXX won't work on BSD because of pci_read_config_dword */
 static uint32_t
-nouveau_mem_fb_amount_igp(struct drm_device *dev)
+nouveau_mem_detect_nv04(struct drm_device *dev)
+{
+       uint32_t boot0 = nv_rd32(dev, NV03_BOOT_0);
+
+       if (boot0 & 0x00000100)
+               return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
+
+       switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
+       case NV04_BOOT_0_RAM_AMOUNT_32MB:
+               return 32 * 1024 * 1024;
+       case NV04_BOOT_0_RAM_AMOUNT_16MB:
+               return 16 * 1024 * 1024;
+       case NV04_BOOT_0_RAM_AMOUNT_8MB:
+               return 8 * 1024 * 1024;
+       case NV04_BOOT_0_RAM_AMOUNT_4MB:
+               return 4 * 1024 * 1024;
+       }
+
+       return 0;
+}
+
+static uint32_t
+nouveau_mem_detect_nforce(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct pci_dev *bridge;
@@ -463,11 +512,11 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
                return 0;
        }
 
-       if (dev_priv->flags&NV_NFORCE) {
+       if (dev_priv->flags & NV_NFORCE) {
                pci_read_config_dword(bridge, 0x7C, &mem);
                return (uint64_t)(((mem >> 6) & 31) + 1)*1024*1024;
        } else
-       if (dev_priv->flags&NV_NFORCE2) {
+       if (dev_priv->flags & NV_NFORCE2) {
                pci_read_config_dword(bridge, 0x84, &mem);
                return (uint64_t)(((mem >> 4) & 127) + 1)*1024*1024;
        }
@@ -477,50 +526,32 @@ nouveau_mem_fb_amount_igp(struct drm_device *dev)
 }
 
 /* returns the amount of FB ram in bytes */
-uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
+int
+nouveau_mem_detect(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       uint32_t boot0;
-
-       switch (dev_priv->card_type) {
-       case NV_04:
-               boot0 = nv_rd32(dev, NV03_BOOT_0);
-               if (boot0 & 0x00000100)
-                       return (((boot0 >> 12) & 0xf) * 2 + 2) * 1024 * 1024;
-
-               switch (boot0 & NV03_BOOT_0_RAM_AMOUNT) {
-               case NV04_BOOT_0_RAM_AMOUNT_32MB:
-                       return 32 * 1024 * 1024;
-               case NV04_BOOT_0_RAM_AMOUNT_16MB:
-                       return 16 * 1024 * 1024;
-               case NV04_BOOT_0_RAM_AMOUNT_8MB:
-                       return 8 * 1024 * 1024;
-               case NV04_BOOT_0_RAM_AMOUNT_4MB:
-                       return 4 * 1024 * 1024;
-               }
-               break;
-       case NV_10:
-       case NV_20:
-       case NV_30:
-       case NV_40:
-       case NV_50:
-       default:
-               if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
-                       return nouveau_mem_fb_amount_igp(dev);
-               } else {
-                       uint64_t mem;
-                       mem = (nv_rd32(dev, NV04_FIFO_DATA) &
-                                       NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK) >>
-                                       NV10_FIFO_DATA_RAM_AMOUNT_MB_SHIFT;
-                       return mem * 1024 * 1024;
-               }
-               break;
+
+       if (dev_priv->card_type == NV_04) {
+               dev_priv->vram_size = nouveau_mem_detect_nv04(dev);
+       } else
+       if (dev_priv->flags & (NV_NFORCE | NV_NFORCE2)) {
+               dev_priv->vram_size = nouveau_mem_detect_nforce(dev);
+       } else {
+               dev_priv->vram_size  = nv_rd32(dev, NV04_FIFO_DATA);
+               dev_priv->vram_size &= NV10_FIFO_DATA_RAM_AMOUNT_MB_MASK;
+               if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
+                       dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
        }
 
-       NV_ERROR(dev,
-               "Unable to detect video ram size. Please report your setup to "
-                                                       DRIVER_EMAIL "\n");
-       return 0;
+       NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20));
+       if (dev_priv->vram_sys_base) {
+               NV_INFO(dev, "Stolen system memory at: 0x%010llx\n",
+                       dev_priv->vram_sys_base);
+       }
+
+       if (dev_priv->vram_size)
+               return 0;
+       return -ENOMEM;
 }
 
 #if __OS_HAS_AGP
@@ -631,15 +662,12 @@ nouveau_mem_init(struct drm_device *dev)
        spin_lock_init(&dev_priv->ttm.bo_list_lock);
        spin_lock_init(&dev_priv->tile.lock);
 
-       dev_priv->fb_available_size = nouveau_mem_fb_amount(dev);
-
+       dev_priv->fb_available_size = dev_priv->vram_size;
        dev_priv->fb_mappable_pages = dev_priv->fb_available_size;
        if (dev_priv->fb_mappable_pages > drm_get_resource_len(dev, 1))
                dev_priv->fb_mappable_pages = drm_get_resource_len(dev, 1);
        dev_priv->fb_mappable_pages >>= PAGE_SHIFT;
 
-       NV_INFO(dev, "%d MiB VRAM\n", (int)(dev_priv->fb_available_size >> 20));
-
        /* remove reserved space at end of vram from available amount */
        dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram;
        dev_priv->fb_aper_free = dev_priv->fb_available_size;
index 86785b8..1d6ee8b 100644 (file)
@@ -172,6 +172,24 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
        }
        dev_priv->engine.instmem.finish_access(nvbe->dev);
 
+       if (dev_priv->card_type == NV_50) {
+               nv_wr32(dev, 0x100c80, 0x00050001);
+               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+                                               nv_rd32(dev, 0x100c80));
+                       return -EBUSY;
+               }
+
+               nv_wr32(dev, 0x100c80, 0x00000001);
+               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+                                               nv_rd32(dev, 0x100c80));
+                       return -EBUSY;
+               }
+       }
+
        nvbe->bound = false;
        return 0;
 }
index 10656a6..e171064 100644 (file)
@@ -341,7 +341,7 @@ nouveau_card_init_channel(struct drm_device *dev)
 
        gpuobj = NULL;
        ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
-                                    0, nouveau_mem_fb_amount(dev),
+                                    0, dev_priv->vram_size,
                                     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
                                     &gpuobj);
        if (ret)
@@ -427,6 +427,10 @@ nouveau_card_init(struct drm_device *dev)
                        goto out;
        }
 
+       ret = nouveau_mem_detect(dev);
+       if (ret)
+               goto out_bios;
+
        ret = nouveau_gpuobj_early_init(dev);
        if (ret)
                goto out_bios;
@@ -502,7 +506,7 @@ nouveau_card_init(struct drm_device *dev)
                else
                        ret = nv04_display_create(dev);
                if (ret)
-                       goto out_irq;
+                       goto out_channel;
        }
 
        ret = nouveau_backlight_init(dev);
@@ -516,6 +520,11 @@ nouveau_card_init(struct drm_device *dev)
 
        return 0;
 
+out_channel:
+       if (dev_priv->channel) {
+               nouveau_channel_free(dev_priv->channel);
+               dev_priv->channel = NULL;
+       }
 out_irq:
        drm_irq_uninstall(dev);
 out_fifo:
@@ -533,6 +542,7 @@ out_mc:
 out_gpuobj:
        nouveau_gpuobj_takedown(dev);
 out_mem:
+       nouveau_sgdma_takedown(dev);
        nouveau_mem_close(dev);
 out_instmem:
        engine->instmem.takedown(dev);
index 6b2ef4a..500ccfd 100644 (file)
@@ -278,7 +278,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev)
        default:
                nv_wr32(dev, 0x2230, 0);
                nv_wr32(dev, NV40_PFIFO_RAMFC,
-                       ((nouveau_mem_fb_amount(dev) - 512 * 1024 +
+                       ((dev_priv->vram_size - 512 * 1024 +
                          dev_priv->ramfc_offset) >> 16) | (3 << 16));
                break;
        }
index 53e8afe..0616c96 100644 (file)
@@ -335,6 +335,27 @@ nv40_graph_init(struct drm_device *dev)
        nv_wr32(dev, 0x400b38, 0x2ffff800);
        nv_wr32(dev, 0x400b3c, 0x00006000);
 
+       /* Tiling related stuff. */
+       switch (dev_priv->chipset) {
+       case 0x44:
+       case 0x4a:
+               nv_wr32(dev, 0x400bc4, 0x1003d888);
+               nv_wr32(dev, 0x400bbc, 0xb7a7b500);
+               break;
+       case 0x46:
+               nv_wr32(dev, 0x400bc4, 0x0000e024);
+               nv_wr32(dev, 0x400bbc, 0xb7a7b520);
+               break;
+       case 0x4c:
+       case 0x4e:
+       case 0x67:
+               nv_wr32(dev, 0x400bc4, 0x1003d888);
+               nv_wr32(dev, 0x400bbc, 0xb7a7b540);
+               break;
+       default:
+               break;
+       }
+
        /* Turn all the tiling regions off. */
        for (i = 0; i < pfb->num_tiles; i++)
                nv40_graph_set_region_tiling(dev, i, 0, 0, 0);
index fac6c88..649db4c 100644 (file)
@@ -143,7 +143,7 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
        }
 
        ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19,
-                                 0, nouveau_mem_fb_amount(dev));
+                                 0, dev_priv->vram_size);
        if (ret) {
                nv50_evo_channel_del(pchan);
                return ret;
@@ -231,7 +231,7 @@ nv50_display_init(struct drm_device *dev)
        /* This used to be in crtc unblank, but seems out of place there. */
        nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0);
        /* RAM is clamped to 256 MiB. */
-       ram_amount = nouveau_mem_fb_amount(dev);
+       ram_amount = dev_priv->vram_size;
        NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount);
        if (ram_amount > 256*1024*1024)
                ram_amount = 256*1024*1024;
@@ -529,8 +529,10 @@ int nv50_display_create(struct drm_device *dev)
        }
 
        ret = nv50_display_init(dev);
-       if (ret)
+       if (ret) {
+               nv50_display_destroy(dev);
                return ret;
+       }
 
        return 0;
 }
@@ -885,10 +887,12 @@ nv50_display_error_handler(struct drm_device *dev)
        nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000);
 }
 
-static void
-nv50_display_irq_hotplug(struct drm_device *dev)
+void
+nv50_display_irq_hotplug_bh(struct work_struct *work)
 {
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct drm_nouveau_private *dev_priv =
+               container_of(work, struct drm_nouveau_private, hpd_work);
+       struct drm_device *dev = dev_priv->dev;
        struct drm_connector *connector;
        const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
        uint32_t unplug_mask, plug_mask, change_mask;
@@ -949,8 +953,10 @@ nv50_display_irq_handler(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        uint32_t delayed = 0;
 
-       while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG)
-               nv50_display_irq_hotplug(dev);
+       if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
+               if (!work_pending(&dev_priv->hpd_work))
+                       queue_work(dev_priv->wq, &dev_priv->hpd_work);
+       }
 
        while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {
                uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0);
index 3ae8d07..581d405 100644 (file)
@@ -37,6 +37,7 @@
 
 void nv50_display_irq_handler(struct drm_device *dev);
 void nv50_display_irq_handler_bh(struct work_struct *work);
+void nv50_display_irq_hotplug_bh(struct work_struct *work);
 int nv50_display_init(struct drm_device *dev);
 int nv50_display_create(struct drm_device *dev);
 int nv50_display_destroy(struct drm_device *dev);
index 25a3cd8..a8c70e7 100644 (file)
@@ -157,8 +157,11 @@ nv50_fbcon_accel_init(struct fb_info *info)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *chan = dev_priv->channel;
        struct nouveau_gpuobj *eng2d = NULL;
+       uint64_t fb;
        int ret, format;
 
+       fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base;
+
        switch (info->var.bits_per_pixel) {
        case 8:
                format = 0xf3;
@@ -248,9 +251,8 @@ nv50_fbcon_accel_init(struct fb_info *info)
        OUT_RING(chan, info->fix.line_length);
        OUT_RING(chan, info->var.xres_virtual);
        OUT_RING(chan, info->var.yres_virtual);
-       OUT_RING(chan, 0);
-       OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
-                        dev_priv->vm_vram_base);
+       OUT_RING(chan, upper_32_bits(fb));
+       OUT_RING(chan, lower_32_bits(fb));
        BEGIN_RING(chan, NvSub2D, 0x0230, 2);
        OUT_RING(chan, format);
        OUT_RING(chan, 1);
@@ -258,9 +260,8 @@ nv50_fbcon_accel_init(struct fb_info *info)
        OUT_RING(chan, info->fix.line_length);
        OUT_RING(chan, info->var.xres_virtual);
        OUT_RING(chan, info->var.yres_virtual);
-       OUT_RING(chan, 0);
-       OUT_RING(chan, info->fix.smem_start - dev_priv->fb_phys +
-                        dev_priv->vm_vram_base);
+       OUT_RING(chan, upper_32_bits(fb));
+       OUT_RING(chan, lower_32_bits(fb));
 
        return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
new file mode 100644 (file)
index 0000000..c61782b
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_hw.h"
+
+static int
+nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift)
+{
+       const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
+
+       if (gpio->line > 32)
+               return -EINVAL;
+
+       *reg = nv50_gpio_reg[gpio->line >> 3];
+       *shift = (gpio->line & 7) << 2;
+       return 0;
+}
+
+int
+nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag)
+{
+       struct dcb_gpio_entry *gpio;
+       uint32_t r, s, v;
+
+       gpio = nouveau_bios_gpio_entry(dev, tag);
+       if (!gpio)
+               return -ENOENT;
+
+       if (nv50_gpio_location(gpio, &r, &s))
+               return -EINVAL;
+
+       v = nv_rd32(dev, r) >> (s + 2);
+       return ((v & 1) == (gpio->state[1] & 1));
+}
+
+int
+nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
+{
+       struct dcb_gpio_entry *gpio;
+       uint32_t r, s, v;
+
+       gpio = nouveau_bios_gpio_entry(dev, tag);
+       if (!gpio)
+               return -ENOENT;
+
+       if (nv50_gpio_location(gpio, &r, &s))
+               return -EINVAL;
+
+       v  = nv_rd32(dev, r) & ~(0x3 << s);
+       v |= (gpio->state[state] ^ 2) << s;
+       nv_wr32(dev, r, v);
+       return 0;
+}
index c62b33a..b203d06 100644 (file)
@@ -410,9 +410,10 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = {
        { 0x5039, false, NULL }, /* m2mf */
        { 0x502d, false, NULL }, /* 2d */
        { 0x50c0, false, NULL }, /* compute */
+       { 0x85c0, false, NULL }, /* compute (nva3, nva5, nva8) */
        { 0x5097, false, NULL }, /* tesla (nv50) */
-       { 0x8297, false, NULL }, /* tesla (nv80/nv90) */
-       { 0x8397, false, NULL }, /* tesla (nva0) */
-       { 0x8597, false, NULL }, /* tesla (nva8) */
+       { 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */
+       { 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */
+       { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */
        {}
 };
index 546b319..42a8fb2 100644 (file)
 #define CP_FLAG_AUTO_LOAD             ((2 * 32) + 5)
 #define CP_FLAG_AUTO_LOAD_NOT_PENDING 0
 #define CP_FLAG_AUTO_LOAD_PENDING     1
+#define CP_FLAG_NEWCTX                ((2 * 32) + 10)
+#define CP_FLAG_NEWCTX_BUSY           0
+#define CP_FLAG_NEWCTX_DONE           1
 #define CP_FLAG_XFER                  ((2 * 32) + 11)
 #define CP_FLAG_XFER_IDLE             0
 #define CP_FLAG_XFER_BUSY             1
-#define CP_FLAG_NEWCTX                ((2 * 32) + 12)
-#define CP_FLAG_NEWCTX_BUSY           0
-#define CP_FLAG_NEWCTX_DONE           1
 #define CP_FLAG_ALWAYS                ((2 * 32) + 13)
 #define CP_FLAG_ALWAYS_FALSE          0
 #define CP_FLAG_ALWAYS_TRUE           1
@@ -177,6 +177,7 @@ nv50_grctx_init(struct nouveau_grctx *ctx)
        case 0x96:
        case 0x98:
        case 0xa0:
+       case 0xa3:
        case 0xa5:
        case 0xa8:
        case 0xaa:
@@ -364,6 +365,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
        case 0xac:
                gr_def(ctx, 0x401c00, 0x042500df);
                break;
+       case 0xa3:
        case 0xa5:
        case 0xa8:
                gr_def(ctx, 0x401c00, 0x142500df);
@@ -418,6 +420,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                break;
        case 0x84:
        case 0xa0:
+       case 0xa3:
        case 0xa5:
        case 0xa8:
        case 0xaa:
@@ -792,6 +795,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                                case 0xa5:
                                        gr_def(ctx, offset + 0x1c, 0x310c0000);
                                        break;
+                               case 0xa3:
                                case 0xa8:
                                case 0xaa:
                                case 0xac:
@@ -859,6 +863,8 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
                        else
                                gr_def(ctx, offset + 0x8, 0x05010202);
                        gr_def(ctx, offset + 0xc, 0x00030201);
+                       if (dev_priv->chipset == 0xa3)
+                               cp_ctx(ctx, base + 0x36c, 1);
 
                        cp_ctx(ctx, base + 0x400, 2);
                        gr_def(ctx, base + 0x404, 0x00000040);
@@ -1159,7 +1165,9 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
                nv50_graph_construct_gene_unk8(ctx);
                if (dev_priv->chipset == 0xa0)
                        xf_emit(ctx, 0x189, 0);
-               else if (dev_priv->chipset < 0xa8)
+               else if (dev_priv->chipset == 0xa3)
+                       xf_emit(ctx, 0xd5, 0);
+               else if (dev_priv->chipset == 0xa5)
                        xf_emit(ctx, 0x99, 0);
                else if (dev_priv->chipset == 0xaa)
                        xf_emit(ctx, 0x65, 0);
@@ -1197,6 +1205,8 @@ nv50_graph_construct_xfer1(struct nouveau_grctx *ctx)
                ctx->ctxvals_pos = offset + 4;
                if (dev_priv->chipset == 0xa0)
                        xf_emit(ctx, 0xa80, 0);
+               else if (dev_priv->chipset == 0xa3)
+                       xf_emit(ctx, 0xa7c, 0);
                else
                        xf_emit(ctx, 0xa7a, 0);
                xf_emit(ctx, 1, 0x3fffff);
@@ -1341,6 +1351,7 @@ nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx)
                xf_emit(ctx, 0x942, 0);
                break;
        case 0xa0:
+       case 0xa3:
                xf_emit(ctx, 0x2042, 0);
                break;
        case 0xa5:
index de1f5b0..5f21df3 100644 (file)
@@ -63,9 +63,10 @@ nv50_instmem_init(struct drm_device *dev)
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_channel *chan;
        uint32_t c_offset, c_size, c_ramfc, c_vmpd, c_base, pt_size;
+       uint32_t save_nv001700;
+       uint64_t v;
        struct nv50_instmem_priv *priv;
        int ret, i;
-       uint32_t v, save_nv001700;
 
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -76,17 +77,12 @@ nv50_instmem_init(struct drm_device *dev)
        for (i = 0x1700; i <= 0x1710; i += 4)
                priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
 
-       if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
-               dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
-       else
-               dev_priv->vram_sys_base = 0;
-
        /* Reserve the last MiB of VRAM, we should probably try to avoid
         * setting up the below tables over the top of the VBIOS image at
         * some point.
         */
        dev_priv->ramin_rsvd_vram = 1 << 20;
-       c_offset = nouveau_mem_fb_amount(dev) - dev_priv->ramin_rsvd_vram;
+       c_offset = dev_priv->vram_size - dev_priv->ramin_rsvd_vram;
        c_size   = 128 << 10;
        c_vmpd   = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x1400 : 0x200;
        c_ramfc  = ((dev_priv->chipset & 0xf0) == 0x50) ? 0x0 : 0x20;
@@ -106,7 +102,7 @@ nv50_instmem_init(struct drm_device *dev)
        dev_priv->vm_gart_size = NV50_VM_BLOCK;
 
        dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size;
-       dev_priv->vm_vram_size = nouveau_mem_fb_amount(dev);
+       dev_priv->vm_vram_size = dev_priv->vram_size;
        if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM)
                dev_priv->vm_vram_size = NV50_VM_MAX_VRAM;
        dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK);
@@ -189,8 +185,8 @@ nv50_instmem_init(struct drm_device *dev)
 
        i = 0;
        while (v < dev_priv->vram_sys_base + c_offset + c_size) {
-               BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v);
-               BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
+               BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, lower_32_bits(v));
+               BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, upper_32_bits(v));
                v += 0x1000;
                i += 8;
        }
index c2fff54..0c68698 100644 (file)
@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                        mode_ctl = 0x0200;
                break;
        case OUTPUT_DP:
-               mode_ctl |= 0x00050000;
+               mode_ctl |= (nv_encoder->dp.mc_unknown << 16);
                if (nv_encoder->dcb->sorconf.link & 1)
                        mode_ctl |= 0x00000800;
                else
@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
 int
 nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
 {
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_encoder *nv_encoder = NULL;
        struct drm_encoder *encoder;
        bool dum;
@@ -319,5 +320,27 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       if (nv_encoder->dcb->type == OUTPUT_DP) {
+               uint32_t mc, or = nv_encoder->or;
+
+               if (dev_priv->chipset < 0x90 ||
+                   dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
+                       mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
+               else
+                       mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
+
+               switch ((mc & 0x00000f00) >> 8) {
+               case 8:
+               case 9:
+                       nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16;
+                       break;
+               default:
+                       break;
+               }
+
+               if (!nv_encoder->dp.mc_unknown)
+                       nv_encoder->dp.mc_unknown = 5;
+       }
+
        return 0;
 }
index 07b7ebf..1d56983 100644 (file)
@@ -908,11 +908,16 @@ static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++), shift;
        uint32_t saved, dst;
        int dptr = *ptr;
+       uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
        SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
        SDEBUG("   shift: %d\n", shift);
        dst <<= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
        SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
@@ -922,11 +927,16 @@ static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
        uint8_t attr = U8((*ptr)++), shift;
        uint32_t saved, dst;
        int dptr = *ptr;
+       uint32_t dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
        SDEBUG("   dst: ");
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
        shift = atom_get_src(ctx, attr, ptr);
        SDEBUG("   shift: %d\n", shift);
        dst >>= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
        SDEBUG("   dst: ");
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
@@ -1137,6 +1147,7 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32
        int len, ws, ps, ptr;
        unsigned char op;
        atom_exec_context ectx;
+       int ret = 0;
 
        if (!base)
                return -EINVAL;
@@ -1169,7 +1180,8 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32
                if (ectx.abort) {
                        DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n",
                                base, len, ws, ps, ptr - 1);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto free;
                }
 
                if (op < ATOM_OP_CNT && op > 0)
@@ -1184,9 +1196,10 @@ static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32
        debug_depth--;
        SDEBUG("<<\n");
 
+free:
        if (ws)
                kfree(ectx.ws);
-       return 0;
+       return ret;
 }
 
 int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
index fd4ef6d..a87990b 100644 (file)
@@ -521,6 +521,10 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
                                if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
                                        adjusted_clock = mode->clock * 2;
+                               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+                                       pll->algo = PLL_ALGO_LEGACY;
+                                       pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+                               }
                        } else {
                                if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
                                        pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
index c958049..d7388fd 100644 (file)
@@ -2891,7 +2891,7 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
 {
        struct radeon_bo *robj;
        unsigned long size;
-       unsigned u, i, w, h;
+       unsigned u, i, w, h, d;
        int ret;
 
        for (u = 0; u < track->num_texture; u++) {
@@ -2923,20 +2923,25 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
                        h = h / (1 << i);
                        if (track->textures[u].roundup_h)
                                h = roundup_pow_of_two(h);
+                       if (track->textures[u].tex_coord_type == 1) {
+                               d = (1 << track->textures[u].txdepth) / (1 << i);
+                               if (!d)
+                                       d = 1;
+                       } else {
+                               d = 1;
+                       }
                        if (track->textures[u].compress_format) {
 
-                               size += r100_track_compress_size(track->textures[u].compress_format, w, h);
+                               size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d;
                                /* compressed textures are block based */
                        } else
-                               size += w * h;
+                               size += w * h * d;
                }
                size *= track->textures[u].cpp;
 
                switch (track->textures[u].tex_coord_type) {
                case 0:
-                       break;
                case 1:
-                       size *= (1 << track->textures[u].txdepth);
                        break;
                case 2:
                        if (track->separate_cube) {
@@ -3007,7 +3012,11 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
                }
        }
        prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
-       nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+       if (track->vap_vf_cntl & (1 << 14)) {
+               nverts = track->vap_alt_nverts;
+       } else {
+               nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
+       }
        switch (prim_walk) {
        case 1:
                for (i = 0; i < track->num_arrays; i++) {
index b27a699..fadfe68 100644 (file)
@@ -64,6 +64,7 @@ struct r100_cs_track {
        unsigned                        maxy;
        unsigned                        vtx_size;
        unsigned                        vap_vf_cntl;
+       unsigned                        vap_alt_nverts;
        unsigned                        immd_dwords;
        unsigned                        num_arrays;
        unsigned                        max_indx;
index 561048a..bd75f99 100644 (file)
@@ -325,11 +325,12 @@ void r300_gpu_init(struct radeon_device *rdev)
 
        r100_hdp_reset(rdev);
        /* FIXME: rv380 one pipes ? */
-       if ((rdev->family == CHIP_R300) || (rdev->family == CHIP_R350)) {
+       if ((rdev->family == CHIP_R300 && rdev->pdev->device != 0x4144) ||
+           (rdev->family == CHIP_R350)) {
                /* r300,r350 */
                rdev->num_gb_pipes = 2;
        } else {
-               /* rv350,rv370,rv380 */
+               /* rv350,rv370,rv380,r300 AD */
                rdev->num_gb_pipes = 1;
        }
        rdev->num_z_pipes = 1;
@@ -729,6 +730,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                /* VAP_VF_MAX_VTX_INDX */
                track->max_indx = idx_value & 0x00FFFFFFUL;
                break;
+       case 0x2088:
+               /* VAP_ALT_NUM_VERTICES - only valid on r500 */
+               if (p->rdev->family < CHIP_RV515)
+                       goto fail;
+               track->vap_alt_nverts = idx_value & 0xFFFFFF;
+               break;
        case 0x43E4:
                /* SC_SCISSOR1 */
                track->maxy = ((idx_value >> 13) & 0x1FFF) + 1;
@@ -766,7 +773,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                tmp = idx_value & ~(0x7 << 16);
                tmp |= tile_flags;
                ib[idx] = tmp;
-
                i = (reg - 0x4E38) >> 2;
                track->cb[i].pitch = idx_value & 0x3FFE;
                switch (((idx_value >> 21) & 0xF)) {
@@ -1051,11 +1057,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                        break;
                /* fallthrough do not move */
        default:
-               printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
-                      reg, idx);
-               return -EINVAL;
+               goto fail;
        }
        return 0;
+fail:
+       printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
+              reg, idx);
+       return -EINVAL;
 }
 
 static int r300_packet3_check(struct radeon_cs_parser *p,
index dac7042..1d89805 100644 (file)
@@ -35,7 +35,7 @@
  */
 static int r600_audio_chipset_supported(struct radeon_device *rdev)
 {
-       return rdev->family >= CHIP_R600
+       return (rdev->family >= CHIP_R600 && rdev->family < CHIP_CEDAR)
                || rdev->family == CHIP_RS600
                || rdev->family == CHIP_RS690
                || rdev->family == CHIP_RS740;
index 029fa14..2616b82 100644 (file)
@@ -314,6 +314,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
        struct radeon_device *rdev = dev->dev_private;
        uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (!offset)
                return;
 
@@ -484,6 +487,9 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (!radeon_encoder->hdmi_offset) {
                r600_hdmi_assign_block(encoder);
                if (!radeon_encoder->hdmi_offset) {
@@ -525,6 +531,9 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 
+       if (ASIC_IS_DCE4(rdev))
+               return;
+
        if (!radeon_encoder->hdmi_offset) {
                dev_err(rdev->dev, "Disabling not enabled HDMI\n");
                return;
index 1fff955..5673665 100644 (file)
@@ -69,16 +69,19 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
        struct radeon_i2c_bus_rec i2c;
        int index = GetIndexIntoMasterTable(DATA, GPIO_I2C_Info);
        struct _ATOM_GPIO_I2C_INFO *i2c_info;
-       uint16_t data_offset;
-       int i;
+       uint16_t data_offset, size;
+       int i, num_indices;
 
        memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec));
        i2c.valid = false;
 
-       if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
+       if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) {
                i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset);
 
-               for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+               num_indices = (size - sizeof(ATOM_COMMON_TABLE_HEADER)) /
+                       sizeof(ATOM_GPIO_I2C_ASSIGMENT);
+
+               for (i = 0; i < num_indices; i++) {
                        gpio = &i2c_info->asGPIO_Info[i];
 
                        if (gpio->sucI2cId.ucAccess == id) {
index 2becded..37db8ad 100644 (file)
@@ -760,7 +760,9 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct
                        dac = RBIOS8(dac_info + 0x3) & 0xf;
                        p_dac->ps2_pdac_adj = (bg << 8) | (dac);
                }
-               found = 1;
+               /* if the values are all zeros, use the table */
+               if (p_dac->ps2_pdac_adj)
+                       found = 1;
        }
 
        if (!found) /* fallback to defaults */
@@ -895,7 +897,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                        bg = RBIOS8(dac_info + 0x10) & 0xf;
                        dac = RBIOS8(dac_info + 0x11) & 0xf;
                        tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
-                       found = 1;
+                       /* if the values are all zeros, use the table */
+                       if (tv_dac->ps2_tvdac_adj)
+                               found = 1;
                } else if (rev > 1) {
                        bg = RBIOS8(dac_info + 0xc) & 0xf;
                        dac = (RBIOS8(dac_info + 0xc) >> 4) & 0xf;
@@ -908,7 +912,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                        bg = RBIOS8(dac_info + 0xe) & 0xf;
                        dac = (RBIOS8(dac_info + 0xe) >> 4) & 0xf;
                        tv_dac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
-                       found = 1;
+                       /* if the values are all zeros, use the table */
+                       if (tv_dac->ps2_tvdac_adj)
+                               found = 1;
                }
                tv_dac->tv_std = radeon_combios_get_tv_info(rdev);
        }
@@ -925,7 +931,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                                    (bg << 16) | (dac << 20);
                                tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
                                tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
-                               found = 1;
+                               /* if the values are all zeros, use the table */
+                               if (tv_dac->ps2_tvdac_adj)
+                                       found = 1;
                        } else {
                                bg = RBIOS8(dac_info + 0x4) & 0xf;
                                dac = RBIOS8(dac_info + 0x5) & 0xf;
@@ -933,7 +941,9 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct
                                    (bg << 16) | (dac << 20);
                                tv_dac->pal_tvdac_adj = tv_dac->ps2_tvdac_adj;
                                tv_dac->ntsc_tvdac_adj = tv_dac->ps2_tvdac_adj;
-                               found = 1;
+                               /* if the values are all zeros, use the table */
+                               if (tv_dac->ps2_tvdac_adj)
+                                       found = 1;
                        }
                } else {
                        DRM_INFO("No TV DAC info found in BIOS\n");
index 60d5981..1331351 100644 (file)
@@ -162,12 +162,14 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
 {
        struct drm_device *dev = connector->dev;
        struct drm_connector *conflict;
+       struct radeon_connector *radeon_conflict;
        int i;
 
        list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
                if (conflict == connector)
                        continue;
 
+               radeon_conflict = to_radeon_connector(conflict);
                for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
                        if (conflict->encoder_ids[i] == 0)
                                break;
@@ -177,6 +179,9 @@ radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
                                if (conflict->status != connector_status_connected)
                                        continue;
 
+                               if (radeon_conflict->use_digital)
+                                       continue;
+
                                if (priority == true) {
                                        DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
                                        DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
@@ -287,6 +292,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
 
        if (property == rdev->mode_info.coherent_mode_property) {
                struct radeon_encoder_atom_dig *dig;
+               bool new_coherent_mode;
 
                /* need to find digital encoder on connector */
                encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
@@ -299,8 +305,11 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
                        return 0;
 
                dig = radeon_encoder->enc_priv;
-               dig->coherent_mode = val ? true : false;
-               radeon_property_change_mode(&radeon_encoder->base);
+               new_coherent_mode = val ? true : false;
+               if (dig->coherent_mode != new_coherent_mode) {
+                       dig->coherent_mode = new_coherent_mode;
+                       radeon_property_change_mode(&radeon_encoder->base);
+               }
        }
 
        if (property == rdev->mode_info.tv_std_property) {
@@ -315,7 +324,7 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
                radeon_encoder = to_radeon_encoder(encoder);
                if (!radeon_encoder->enc_priv)
                        return 0;
-               if (rdev->is_atom_bios) {
+               if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) {
                        struct radeon_encoder_atom_dac *dac_int;
                        dac_int = radeon_encoder->enc_priv;
                        dac_int->tv_std = val;
index dc6eba6..419630d 100644 (file)
@@ -417,8 +417,9 @@ static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
        return -EBUSY;
 }
 
-static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
+static void radeon_init_pipes(struct drm_device *dev)
 {
+       drm_radeon_private_t *dev_priv = dev->dev_private;
        uint32_t gb_tile_config, gb_pipe_sel = 0;
 
        if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) {
@@ -436,11 +437,12 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
                dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
        } else {
                /* R3xx */
-               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
+               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300 &&
+                    dev->pdev->device != 0x4144) ||
                    ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
                        dev_priv->num_gb_pipes = 2;
                } else {
-                       /* R3Vxx */
+                       /* RV3xx/R300 AD */
                        dev_priv->num_gb_pipes = 1;
                }
        }
@@ -736,7 +738,7 @@ static int radeon_do_engine_reset(struct drm_device * dev)
 
        /* setup the raster pipes */
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
-           radeon_init_pipes(dev_priv);
+           radeon_init_pipes(dev);
 
        /* Reset the CP ring */
        radeon_do_cp_reset(dev_priv);
index bddf17f..7b629e3 100644 (file)
 #include "radeon.h"
 #include "atom.h"
 
+static const char radeon_family_name[][16] = {
+       "R100",
+       "RV100",
+       "RS100",
+       "RV200",
+       "RS200",
+       "R200",
+       "RV250",
+       "RS300",
+       "RV280",
+       "R300",
+       "R350",
+       "RV350",
+       "RV380",
+       "R420",
+       "R423",
+       "RV410",
+       "RS400",
+       "RS480",
+       "RS600",
+       "RS690",
+       "RS740",
+       "RV515",
+       "R520",
+       "RV530",
+       "RV560",
+       "RV570",
+       "R580",
+       "R600",
+       "RV610",
+       "RV630",
+       "RV670",
+       "RV620",
+       "RV635",
+       "RS780",
+       "RS880",
+       "RV770",
+       "RV730",
+       "RV710",
+       "RV740",
+       "CEDAR",
+       "REDWOOD",
+       "JUNIPER",
+       "CYPRESS",
+       "HEMLOCK",
+       "LAST",
+};
+
 /*
  * Clear GPU surface registers.
  */
@@ -526,7 +574,6 @@ int radeon_device_init(struct radeon_device *rdev,
        int r;
        int dma_bits;
 
-       DRM_INFO("radeon: Initializing kernel modesetting.\n");
        rdev->shutdown = false;
        rdev->dev = &pdev->dev;
        rdev->ddev = ddev;
@@ -538,6 +585,10 @@ int radeon_device_init(struct radeon_device *rdev,
        rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
        rdev->gpu_lockup = false;
        rdev->accel_working = false;
+
+       DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
+               radeon_family_name[rdev->family], pdev->vendor, pdev->device);
+
        /* mutex initialization are all done here so we
         * can recall function without having locking issues */
        mutex_init(&rdev->cs_mutex);
index 055a517..4b05563 100644 (file)
  * - 2.0.0 - initial interface
  * - 2.1.0 - add square tiling interface
  * - 2.2.0 - add r6xx/r7xx const buffer support
+ * - 2.3.0 - add MSPOS + 3D texture + r500 VAP regs
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       2
+#define KMS_DRIVER_MINOR       3
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
index 52d6f96..30293be 100644 (file)
@@ -317,12 +317,8 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
        DAC_ENCODER_CONTROL_PS_ALLOCATION args;
-       int index = 0, num = 0;
+       int index = 0;
        struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-       enum radeon_tv_std tv_std = TV_STD_NTSC;
-
-       if (dac_info->tv_std)
-               tv_std = dac_info->tv_std;
 
        memset(&args, 0, sizeof(args));
 
@@ -330,12 +326,10 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
                index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
-               num = 1;
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
                index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
-               num = 2;
                break;
        }
 
@@ -346,7 +340,7 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
        else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
                args.ucDacStandard = ATOM_DAC1_CV;
        else {
-               switch (tv_std) {
+               switch (dac_info->tv_std) {
                case TV_STD_PAL:
                case TV_STD_PAL_M:
                case TV_STD_SCART_PAL:
@@ -377,10 +371,6 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
        TV_ENCODER_CONTROL_PS_ALLOCATION args;
        int index = 0;
        struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
-       enum radeon_tv_std tv_std = TV_STD_NTSC;
-
-       if (dac_info->tv_std)
-               tv_std = dac_info->tv_std;
 
        memset(&args, 0, sizeof(args));
 
@@ -391,7 +381,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
        if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT))
                args.sTVEncoder.ucTvStandard = ATOM_TV_CV;
        else {
-               switch (tv_std) {
+               switch (dac_info->tv_std) {
                case TV_STD_NTSC:
                        args.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
                        break;
@@ -875,6 +865,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                        if (dig->coherent_mode)
                                args.v3.acConfig.fCoherentMode = 1;
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.v3.acConfig.fDualLinkConnector = 1;
                }
        } else if (ASIC_IS_DCE32(rdev)) {
                args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
@@ -898,6 +890,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                        if (dig->coherent_mode)
                                args.v2.acConfig.fCoherentMode = 1;
+                       if (radeon_encoder->pixel_clock > 165000)
+                               args.v2.acConfig.fDualLinkConnector = 1;
                }
        } else {
                args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
@@ -1383,8 +1377,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
                atombios_dac_setup(encoder, ATOM_ENABLE);
-               if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
-                       atombios_tv_setup(encoder, ATOM_ENABLE);
+               if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) {
+                       if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+                               atombios_tv_setup(encoder, ATOM_ENABLE);
+                       else
+                               atombios_tv_setup(encoder, ATOM_DISABLE);
+               }
                break;
        }
        atombios_apply_encoder_quirks(encoder, adjusted_mode);
@@ -1558,12 +1556,14 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = {
 struct radeon_encoder_atom_dac *
 radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder)
 {
+       struct drm_device *dev = radeon_encoder->base.dev;
+       struct radeon_device *rdev = dev->dev_private;
        struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL);
 
        if (!dac)
                return NULL;
 
-       dac->tv_std = TV_STD_NTSC;
+       dac->tv_std = radeon_atombios_get_tv_info(rdev);
        return dac;
 }
 
@@ -1641,6 +1641,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC1:
                drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_DAC);
+               radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder);
                drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_DAC2:
index 93c7d5d..e329066 100644 (file)
@@ -36,7 +36,7 @@
  * Radeon chip families
  */
 enum radeon_family {
-       CHIP_R100,
+       CHIP_R100 = 0,
        CHIP_RV100,
        CHIP_RS100,
        CHIP_RV200,
@@ -99,4 +99,5 @@ enum radeon_chip_flags {
        RADEON_IS_PCI = 0x00800000UL,
        RADEON_IS_IGPGART = 0x01000000UL,
 };
+
 #endif
index cf389ce..2441cca 100644 (file)
@@ -830,8 +830,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
                                crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
 
                        if (rdev->family == CHIP_R420 ||
-                                       rdev->family == CHIP_R423 ||
-                                       rdev->family == CHIP_RV410)
+                           rdev->family == CHIP_R423 ||
+                           rdev->family == CHIP_RV410)
                                tv_dac_cntl |= (R420_TV_DAC_RDACPD |
                                                R420_TV_DAC_GDACPD |
                                                R420_TV_DAC_BDACPD |
@@ -907,35 +907,43 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
        if (rdev->family != CHIP_R200) {
                tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
                if (rdev->family == CHIP_R420 ||
-                               rdev->family == CHIP_R423 ||
-                               rdev->family == CHIP_RV410) {
+                   rdev->family == CHIP_R423 ||
+                   rdev->family == CHIP_RV410) {
                        tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
-                                       RADEON_TV_DAC_BGADJ_MASK |
-                                       R420_TV_DAC_DACADJ_MASK |
-                                       R420_TV_DAC_RDACPD |
-                                       R420_TV_DAC_GDACPD |
-                                       R420_TV_DAC_BDACPD |
-                                       R420_TV_DAC_TVENABLE);
+                                        RADEON_TV_DAC_BGADJ_MASK |
+                                        R420_TV_DAC_DACADJ_MASK |
+                                        R420_TV_DAC_RDACPD |
+                                        R420_TV_DAC_GDACPD |
+                                        R420_TV_DAC_BDACPD |
+                                        R420_TV_DAC_TVENABLE);
                } else {
                        tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
-                                       RADEON_TV_DAC_BGADJ_MASK |
-                                       RADEON_TV_DAC_DACADJ_MASK |
-                                       RADEON_TV_DAC_RDACPD |
-                                       RADEON_TV_DAC_GDACPD |
-                                       RADEON_TV_DAC_BDACPD);
+                                        RADEON_TV_DAC_BGADJ_MASK |
+                                        RADEON_TV_DAC_DACADJ_MASK |
+                                        RADEON_TV_DAC_RDACPD |
+                                        RADEON_TV_DAC_GDACPD |
+                                        RADEON_TV_DAC_BDACPD);
                }
 
-               /*  FIXME TV */
-               if (tv_dac) {
-                       struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
-                       tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-                                       RADEON_TV_DAC_NHOLD |
-                                       RADEON_TV_DAC_STD_PS2 |
-                                       tv_dac->ps2_tvdac_adj);
+               tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD;
+
+               if (is_tv) {
+                       if (tv_dac->tv_std == TV_STD_NTSC ||
+                           tv_dac->tv_std == TV_STD_NTSC_J ||
+                           tv_dac->tv_std == TV_STD_PAL_M ||
+                           tv_dac->tv_std == TV_STD_PAL_60)
+                               tv_dac_cntl |= tv_dac->ntsc_tvdac_adj;
+                       else
+                               tv_dac_cntl |= tv_dac->pal_tvdac_adj;
+
+                       if (tv_dac->tv_std == TV_STD_NTSC ||
+                           tv_dac->tv_std == TV_STD_NTSC_J)
+                               tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+                       else
+                               tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
                } else
-                       tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-                                       RADEON_TV_DAC_NHOLD |
-                                       RADEON_TV_DAC_STD_PS2);
+                       tv_dac_cntl |= (RADEON_TV_DAC_STD_PS2 |
+                                       tv_dac->ps2_tvdac_adj);
 
                WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
        }
index 19c4663..1e97b2d 100644 (file)
@@ -125,6 +125,8 @@ r300 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 989f7a0..e958980 100644 (file)
@@ -125,6 +125,8 @@ r420 0x4f60
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 6801b86..83e8bc0 100644 (file)
@@ -125,6 +125,8 @@ rs600 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index 38abf63..1e46233 100644 (file)
@@ -35,6 +35,7 @@ rv515 0x6d40
 0x1DA8 VAP_VPORT_ZSCALE
 0x1DAC VAP_VPORT_ZOFFSET
 0x2080 VAP_CNTL
+0x208C VAP_INDEX_OFFSET
 0x2090 VAP_OUT_VTX_FMT_0
 0x2094 VAP_OUT_VTX_FMT_1
 0x20B0 VAP_VTE_CNTL
@@ -158,6 +159,8 @@ rv515 0x6d40
 0x4000 GB_VAP_RASTER_VTX_FMT_0
 0x4004 GB_VAP_RASTER_VTX_FMT_1
 0x4008 GB_ENABLE
+0x4010 GB_MSPOS0
+0x4014 GB_MSPOS1
 0x401C GB_SELECT
 0x4020 GB_AA_CONFIG
 0x4024 GB_FIFO_SIZE
index abf824c..a81bc7a 100644 (file)
@@ -159,7 +159,7 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
        WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
        tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
-       tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1);
+       tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) | S_000100_INVALIDATE_L2_CACHE(1);
        WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
 
        tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
index c1605b5..0f28d91 100644 (file)
@@ -142,6 +142,12 @@ static const char *temperature_sensors_sets[][41] = {
          "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
          "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
          NULL },
+/* Set 17: iMac 9,1 */
+       { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
+         "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
+/* Set 18: MacBook Pro 2,2 */
+       { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
+         "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
 };
 
 /* List of keys used to read/write fan speeds */
@@ -1350,6 +1356,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
        { .accelerometer = 1, .light = 1, .temperature_set = 15 },
 /* MacPro3,1: temperature set 16 */
        { .accelerometer = 0, .light = 0, .temperature_set = 16 },
+/* iMac 9,1: light sensor only, temperature set 17 */
+       { .accelerometer = 0, .light = 0, .temperature_set = 17 },
+/* MacBook Pro 2,2: accelerometer, backlight and temperature set 18 */
+       { .accelerometer = 1, .light = 1, .temperature_set = 18 },
 };
 
 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
@@ -1375,6 +1385,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
                &applesmc_dmi_data[9]},
+       { applesmc_dmi_match, "Apple MacBook Pro 2,2", {
+         DMI_MATCH(DMI_BOARD_VENDOR, "Apple Computer, Inc."),
+         DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2") },
+               &applesmc_dmi_data[18]},
        { applesmc_dmi_match, "Apple MacBook Pro", {
          DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
@@ -1415,6 +1429,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "MacPro") },
                &applesmc_dmi_data[4]},
+       { applesmc_dmi_match, "Apple iMac 9,1", {
+         DMI_MATCH(DMI_BOARD_VENDOR, "Apple Inc."),
+         DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1") },
+               &applesmc_dmi_data[17]},
        { applesmc_dmi_match, "Apple iMac 8", {
          DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
          DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") },
index 1002bef..5be09c0 100644 (file)
@@ -539,14 +539,14 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
 
        struct it87_data *data = dev_get_drvdata(dev);
        long val;
+       u8 reg;
 
        if (strict_strtol(buf, 10, &val) < 0)
                return -EINVAL;
 
-       mutex_lock(&data->update_lock);
-
-       data->sensor &= ~(1 << nr);
-       data->sensor &= ~(8 << nr);
+       reg = it87_read_value(data, IT87_REG_TEMP_ENABLE);
+       reg &= ~(1 << nr);
+       reg &= ~(8 << nr);
        if (val == 2) { /* backwards compatibility */
                dev_warn(dev, "Sensor type 2 is deprecated, please use 4 "
                         "instead\n");
@@ -554,14 +554,16 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
        }
        /* 3 = thermal diode; 4 = thermistor; 0 = disabled */
        if (val == 3)
-               data->sensor |= 1 << nr;
+               reg |= 1 << nr;
        else if (val == 4)
-               data->sensor |= 8 << nr;
-       else if (val != 0) {
-               mutex_unlock(&data->update_lock);
+               reg |= 8 << nr;
+       else if (val != 0)
                return -EINVAL;
-       }
+
+       mutex_lock(&data->update_lock);
+       data->sensor = reg;
        it87_write_value(data, IT87_REG_TEMP_ENABLE, data->sensor);
+       data->valid = 0;        /* Force cache refresh */
        mutex_unlock(&data->update_lock);
        return count;
 }
@@ -1841,14 +1843,10 @@ static void __devinit it87_init_device(struct platform_device *pdev)
                        it87_write_value(data, IT87_REG_TEMP_HIGH(i), 127);
        }
 
-       /* Check if temperature channels are reset manually or by some reason */
-       tmp = it87_read_value(data, IT87_REG_TEMP_ENABLE);
-       if ((tmp & 0x3f) == 0) {
-               /* Temp1,Temp3=thermistor; Temp2=thermal diode */
-               tmp = (tmp & 0xc0) | 0x2a;
-               it87_write_value(data, IT87_REG_TEMP_ENABLE, tmp);
-       }
-       data->sensor = tmp;
+       /* Temperature channels are not forcibly enabled, as they can be
+        * set to two different sensor types and we can't guess which one
+        * is correct for a given system. These channels can be enabled at
+        * run-time through the temp{1-3}_type sysfs accessors if needed. */
 
        /* Check if voltage monitors are reset manually or by some reason */
        tmp = it87_read_value(data, IT87_REG_VIN_ENABLE);
index 6b2d8ae..a610e78 100644 (file)
@@ -303,13 +303,13 @@ error_ret:
  **/
 static inline int sht15_calc_temp(struct sht15_data *data)
 {
-       int d1 = 0;
+       int d1 = temppoints[0].d1;
        int i;
 
-       for (i = 1; i < ARRAY_SIZE(temppoints); i++)
+       for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--)
                /* Find pointer to interpolate */
                if (data->supply_uV > temppoints[i - 1].vdd) {
-                       d1 = (data->supply_uV/1000 - temppoints[i - 1].vdd)
+                       d1 = (data->supply_uV - temppoints[i - 1].vdd)
                                * (temppoints[i].d1 - temppoints[i - 1].d1)
                                / (temppoints[i].vdd - temppoints[i - 1].vdd)
                                + temppoints[i - 1].d1;
@@ -542,7 +542,12 @@ static int __devinit sht15_probe(struct platform_device *pdev)
 /* If a regulator is available, query what the supply voltage actually is!*/
        data->reg = regulator_get(data->dev, "vcc");
        if (!IS_ERR(data->reg)) {
-               data->supply_uV = regulator_get_voltage(data->reg);
+               int voltage;
+
+               voltage = regulator_get_voltage(data->reg);
+               if (voltage)
+                       data->supply_uV = voltage;
+
                regulator_enable(data->reg);
                /* setup a notifier block to update this if another device
                 *  causes the voltage to change */
index f7e27b7..d1ff940 100644 (file)
@@ -146,10 +146,10 @@ static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy)
                                "<%s> I2C Interrupted\n", __func__);
                        return -EINTR;
                }
-               if (time_after(jiffies, orig_jiffies + HZ / 1000)) {
+               if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
                        dev_dbg(&i2c_imx->adapter.dev,
                                "<%s> I2C bus is busy\n", __func__);
-                       return -EIO;
+                       return -ETIMEDOUT;
                }
                schedule();
        }
@@ -444,6 +444,8 @@ static int i2c_imx_xfer(struct i2c_adapter *adapter,
                        result = i2c_imx_read(i2c_imx, &msgs[i]);
                else
                        result = i2c_imx_write(i2c_imx, &msgs[i]);
+               if (result)
+                       goto fail0;
        }
 
 fail0:
index 6bd0f19..389ac60 100644 (file)
@@ -903,6 +903,11 @@ omap_i2c_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dev);
 
+       if (cpu_is_omap7xx())
+               dev->reg_shift = 1;
+       else
+               dev->reg_shift = 2;
+
        if ((r = omap_i2c_get_clocks(dev)) != 0)
                goto err_iounmap;
 
@@ -926,11 +931,6 @@ omap_i2c_probe(struct platform_device *pdev)
                dev->b_hw = 1; /* Enable hardware fixes */
        }
 
-       if (cpu_is_omap7xx())
-               dev->reg_shift = 1;
-       else
-               dev->reg_shift = 2;
-
        /* reset ASAP, clearing any IRQs */
        omap_i2c_init(dev);
 
index 2471033..a97e3fe 100644 (file)
@@ -173,6 +173,9 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
                /* We still have something to talk about... */
                val = *alg_data->mif.buf++;
 
+               if (alg_data->mif.len == 1)
+                       val |= stop_bit;
+
                alg_data->mif.len--;
                iowrite32(val, I2C_REG_TX(alg_data));
 
@@ -246,6 +249,9 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
                        __func__);
 
                if (alg_data->mif.len == 1) {
+                       /* Last byte, do not acknowledge next rcv. */
+                       val |= stop_bit;
+
                        /*
                         * Enable interrupt RFDAIE (data in Rx fifo),
                         * and disable DRMIE (need data for Tx)
@@ -633,6 +639,8 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
         */
 
        tmp = ((freq / 1000) / I2C_PNX_SPEED_KHZ) / 2 - 2;
+       if (tmp > 0x3FF)
+               tmp = 0x3FF;
        iowrite32(tmp, I2C_REG_CKH(alg_data));
        iowrite32(tmp, I2C_REG_CKL(alg_data));
 
index 1f5b38b..495be45 100644 (file)
@@ -498,7 +498,7 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)
        int i = 0;
 
        /* Locate the apropriate clock setting */
-       while (i < ARRAY_SIZE(stu300_clktable) &&
+       while (i < ARRAY_SIZE(stu300_clktable) - 1 &&
               stu300_clktable[i].rate < clkrate)
                i++;
 
index fc73d6a..ad63b79 100644 (file)
@@ -3694,7 +3694,7 @@ static void cm_add_one(struct ib_device *ib_device)
        cm_dev->device = device_create(&cm_class, &ib_device->dev,
                                       MKDEV(0, 0), NULL,
                                       "%s", ib_device->name);
-       if (!cm_dev->device) {
+       if (IS_ERR(cm_dev->device)) {
                kfree(cm_dev);
                return;
        }
index 7794249..6d77706 100644 (file)
@@ -1684,6 +1684,7 @@ int rdma_set_ib_paths(struct rdma_cm_id *id,
        }
 
        memcpy(id->route.path_rec, path_rec, sizeof *path_rec * num_paths);
+       id->route.num_paths = num_paths;
        return 0;
 err:
        cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED);
index 56147b2..1d27b9a 100644 (file)
@@ -240,7 +240,7 @@ struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device
        mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
                                                     size, &mfrpl->map,
                                                     GFP_KERNEL);
-       if (!mfrpl->ibfrpl.page_list)
+       if (!mfrpl->mapped_page_list)
                goto err_free;
 
        WARN_ON(mfrpl->map & 0x3f);
index 5a076e8..e54f312 100644 (file)
@@ -2821,11 +2821,10 @@ static int nes_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        attr->cap.max_send_wr = nesqp->hwqp.sq_size;
        attr->cap.max_recv_wr = nesqp->hwqp.rq_size;
        attr->cap.max_recv_sge = 1;
-       if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA) {
-               init_attr->cap.max_inline_data = 0;
-       } else {
-               init_attr->cap.max_inline_data = 64;
-       }
+       if (nes_drv_opt & NES_DRV_OPT_NO_INLINE_DATA)
+               attr->cap.max_inline_data = 0;
+       else
+               attr->cap.max_inline_data = 64;
 
        init_attr->event_handler = nesqp->ibqp.event_handler;
        init_attr->qp_context = nesqp->ibqp.qp_context;
index afd4e2b..9c79bd5 100644 (file)
@@ -660,7 +660,14 @@ static int input_default_setkeycode(struct input_dev *dev,
 int input_get_keycode(struct input_dev *dev,
                      unsigned int scancode, unsigned int *keycode)
 {
-       return dev->getkeycode(dev, scancode, keycode);
+       unsigned long flags;
+       int retval;
+
+       spin_lock_irqsave(&dev->event_lock, flags);
+       retval = dev->getkeycode(dev, scancode, keycode);
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+
+       return retval;
 }
 EXPORT_SYMBOL(input_get_keycode);
 
index ffc25cf..b443e08 100644 (file)
@@ -374,7 +374,9 @@ static int __devinit matrix_keypad_probe(struct platform_device *pdev)
        input_dev->name         = pdev->name;
        input_dev->id.bustype   = BUS_HOST;
        input_dev->dev.parent   = &pdev->dev;
-       input_dev->evbit[0]     = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+       input_dev->evbit[0]     = BIT_MASK(EV_KEY);
+       if (!pdata->no_autorepeat)
+               input_dev->evbit[0] |= BIT_MASK(EV_REP);
        input_dev->open         = matrix_keypad_start;
        input_dev->close        = matrix_keypad_stop;
 
index 99d5876..0d22cb9 100644 (file)
@@ -64,6 +64,7 @@ static const struct alps_model_info alps_model_data[] = {
        { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },
        { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FOUR_BUTTONS },          /* Dell Vostro 1400 */
+       { { 0x73, 0x02, 0x64 }, 0xf8, 0xf8, 0 },                          /* HP Pavilion dm3 */
        { { 0x52, 0x01, 0x14 }, 0xff, 0xff,
                ALPS_PASS | ALPS_DUALPOINT | ALPS_PS2_INTERLEAVED },      /* Toshiba Tecra A11-11L */
 };
index 4f8fe08..b89879b 100644 (file)
@@ -803,7 +803,6 @@ static struct usb_driver bcm5974_driver = {
        .disconnect             = bcm5974_disconnect,
        .suspend                = bcm5974_suspend,
        .resume                 = bcm5974_resume,
-       .reset_resume           = bcm5974_resume,
        .id_table               = bcm5974_table,
        .supports_autosuspend   = 1,
 };
index 577688b..6440a8f 100644 (file)
@@ -39,7 +39,7 @@ MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
 
 static bool i8042_nomux;
 module_param_named(nomux, i8042_nomux, bool, 0);
-MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing conrtoller is present.");
+MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present.");
 
 static bool i8042_unlock;
 module_param_named(unlock, i8042_unlock, bool, 0);
index 82ae18d..0142483 100644 (file)
@@ -68,12 +68,14 @@ static int sparse_keymap_getkeycode(struct input_dev *dev,
                                    unsigned int scancode,
                                    unsigned int *keycode)
 {
-       const struct key_entry *key =
-                       sparse_keymap_entry_from_scancode(dev, scancode);
+       const struct key_entry *key;
 
-       if (key && key->type == KE_KEY) {
-               *keycode = key->keycode;
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       *keycode = key->keycode;
+                       return 0;
+               }
        }
 
        return -EINVAL;
@@ -86,17 +88,16 @@ static int sparse_keymap_setkeycode(struct input_dev *dev,
        struct key_entry *key;
        int old_keycode;
 
-       if (keycode < 0 || keycode > KEY_MAX)
-               return -EINVAL;
-
-       key = sparse_keymap_entry_from_scancode(dev, scancode);
-       if (key && key->type == KE_KEY) {
-               old_keycode = key->keycode;
-               key->keycode = keycode;
-               set_bit(keycode, dev->keybit);
-               if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
-                       clear_bit(old_keycode, dev->keybit);
-               return 0;
+       if (dev->keycode) {
+               key = sparse_keymap_entry_from_scancode(dev, scancode);
+               if (key && key->type == KE_KEY) {
+                       old_keycode = key->keycode;
+                       key->keycode = keycode;
+                       set_bit(keycode, dev->keybit);
+                       if (!sparse_keymap_entry_from_keycode(dev, old_keycode))
+                               clear_bit(old_keycode, dev->keybit);
+                       return 0;
+               }
        }
 
        return -EINVAL;
@@ -164,7 +165,7 @@ int sparse_keymap_setup(struct input_dev *dev,
        return 0;
 
  err_out:
-       kfree(keymap);
+       kfree(map);
        return error;
 
 }
@@ -176,14 +177,27 @@ EXPORT_SYMBOL(sparse_keymap_setup);
  *
  * This function is used to free memory allocated by sparse keymap
  * in an input device that was set up by sparse_keymap_setup().
+ * NOTE: It is safe to cal this function while input device is
+ * still registered (however the drivers should care not to try to
+ * use freed keymap and thus have to shut off interrups/polling
+ * before freeing the keymap).
  */
 void sparse_keymap_free(struct input_dev *dev)
 {
+       unsigned long flags;
+
+       /*
+        * Take event lock to prevent racing with input_get_keycode()
+        * and input_set_keycode() if we are called while input device
+        * is still registered.
+        */
+       spin_lock_irqsave(&dev->event_lock, flags);
+
        kfree(dev->keycode);
        dev->keycode = NULL;
        dev->keycodemax = 0;
-       dev->getkeycode = NULL;
-       dev->setkeycode = NULL;
+
+       spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 EXPORT_SYMBOL(sparse_keymap_free);
 
index 8b5d287..f465025 100644 (file)
@@ -673,13 +673,15 @@ static int wacom_resume(struct usb_interface *intf)
        int rv;
 
        mutex_lock(&wacom->lock);
-       if (wacom->open) {
+
+       /* switch to wacom mode first */
+       wacom_query_tablet_data(intf, features);
+
+       if (wacom->open)
                rv = usb_submit_urb(wacom->irq, GFP_NOIO);
-               /* switch to wacom mode if needed */
-               if (!wacom_retrieve_hid_descriptor(intf, features))
-                       wacom_query_tablet_data(intf, features);
-       } else
+       else
                rv = 0;
+
        mutex_unlock(&wacom->lock);
 
        return rv;
index b3ba343..4a852d8 100644 (file)
@@ -155,19 +155,19 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 {
        struct wacom_features *features = &wacom->features;
        unsigned char *data = wacom->data;
-       int x, y, prox;
-       int rw = 0;
-       int retval = 0;
+       int x, y, rw;
+       static int penData = 0;
 
        if (data[0] != WACOM_REPORT_PENABLED) {
                dbg("wacom_graphire_irq: received unknown report #%d", data[0]);
-               goto exit;
+               return 0;
        }
 
-       prox = data[1] & 0x80;
-       if (prox || wacom->id[0]) {
-               if (prox) {
-                       switch ((data[1] >> 5) & 3) {
+       if (data[1] & 0x80) {
+               /* in prox and not a pad data */
+               penData = 1;
+
+               switch ((data[1] >> 5) & 3) {
 
                        case 0: /* Pen */
                                wacom->tool[0] = BTN_TOOL_PEN;
@@ -181,13 +181,23 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
 
                        case 2: /* Mouse with wheel */
                                wacom_report_key(wcombo, BTN_MIDDLE, data[1] & 0x04);
+                               if (features->type == WACOM_G4 || features->type == WACOM_MO) {
+                                       rw = data[7] & 0x04 ? (data[7] & 0x03)-4 : (data[7] & 0x03);
+                                       wacom_report_rel(wcombo, REL_WHEEL, -rw);
+                               } else
+                                       wacom_report_rel(wcombo, REL_WHEEL, -(signed char) data[6]);
                                /* fall through */
 
                        case 3: /* Mouse without wheel */
                                wacom->tool[0] = BTN_TOOL_MOUSE;
                                wacom->id[0] = CURSOR_DEVICE_ID;
+                               wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
+                               wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
+                               if (features->type == WACOM_G4 || features->type == WACOM_MO)
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
+                               else
+                                       wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
                                break;
-                       }
                }
                x = wacom_le16_to_cpu(&data[2]);
                y = wacom_le16_to_cpu(&data[4]);
@@ -198,32 +208,36 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x01);
                        wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
                        wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04);
-               } else {
-                       wacom_report_key(wcombo, BTN_LEFT, data[1] & 0x01);
-                       wacom_report_key(wcombo, BTN_RIGHT, data[1] & 0x02);
-                       if (features->type == WACOM_G4 ||
-                                       features->type == WACOM_MO) {
-                               wacom_report_abs(wcombo, ABS_DISTANCE, data[6] & 0x3f);
-                               rw = (signed)(data[7] & 0x04) - (data[7] & 0x03);
-                       } else {
-                               wacom_report_abs(wcombo, ABS_DISTANCE, data[7] & 0x3f);
-                               rw = -(signed)data[6];
-                       }
-                       wacom_report_rel(wcombo, REL_WHEEL, rw);
                }
-
-               if (!prox)
-                       wacom->id[0] = 0;
                wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); /* report tool id */
-               wacom_report_key(wcombo, wacom->tool[0], prox);
-               wacom_input_sync(wcombo); /* sync last event */
+               wacom_report_key(wcombo, wacom->tool[0], 1);
+       } else if (wacom->id[0]) {
+               wacom_report_abs(wcombo, ABS_X, 0);
+               wacom_report_abs(wcombo, ABS_Y, 0);
+               if (wacom->tool[0] == BTN_TOOL_MOUSE) {
+                       wacom_report_key(wcombo, BTN_LEFT, 0);
+                       wacom_report_key(wcombo, BTN_RIGHT, 0);
+                       wacom_report_abs(wcombo, ABS_DISTANCE, 0);
+               } else {
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+               }
+               wacom->id[0] = 0;
+               wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */
+               wacom_report_key(wcombo, wacom->tool[0], 0);
        }
 
        /* send pad data */
        switch (features->type) {
            case WACOM_G4:
-               prox = data[7] & 0xf8;
-               if (prox || wacom->id[1]) {
+               if (data[7] & 0xf8) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
                        wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
@@ -231,16 +245,29 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_rel(wcombo, REL_WHEEL, rw);
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
-                       if (!prox)
-                               wacom->id[1] = 0;
-                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               } else if (wacom->id[1]) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
+                       wacom->id[1] = 0;
+                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x40));
+                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x80));
+                       wacom_report_rel(wcombo, REL_WHEEL, 0);
+                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
-               retval = 1;
                break;
            case WACOM_MO:
-               prox = (data[7] & 0xf8) || data[8];
-               if (prox || wacom->id[1]) {
+               if ((data[7] & 0xf8) || (data[8] & 0xff)) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
                        wacom->id[1] = PAD_DEVICE_ID;
                        wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
                        wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
@@ -248,16 +275,27 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo)
                        wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
                        wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
                        wacom_report_key(wcombo, BTN_TOOL_FINGER, 0xf0);
-                       if (!prox)
-                               wacom->id[1] = 0;
                        wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]);
                        wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
+               } else if (wacom->id[1]) {
+                       if (penData) {
+                               wacom_input_sync(wcombo); /* sync last event */
+                               if (!wacom->id[0])
+                                       penData = 0;
+                       }
+                       wacom->id[1] = 0;
+                       wacom_report_key(wcombo, BTN_0, (data[7] & 0x08));
+                       wacom_report_key(wcombo, BTN_1, (data[7] & 0x20));
+                       wacom_report_key(wcombo, BTN_4, (data[7] & 0x10));
+                       wacom_report_key(wcombo, BTN_5, (data[7] & 0x40));
+                       wacom_report_abs(wcombo, ABS_WHEEL, (data[8] & 0x7f));
+                       wacom_report_key(wcombo, BTN_TOOL_FINGER, 0);
+                       wacom_report_abs(wcombo, ABS_MISC, 0);
+                       wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0);
                }
-               retval = 1;
                break;
        }
-exit:
-       return retval;
+       return 1;
 }
 
 static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo)
@@ -598,9 +636,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
 static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx)
 {
        wacom_report_abs(wcombo, ABS_X,
-               data[2 + idx * 2] | ((data[3 + idx * 2] & 0x7f) << 8));
+               (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_Y,
-               data[6 + idx * 2] | ((data[7 + idx * 2] & 0x7f) << 8));
+               (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8));
        wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
        wacom_report_key(wcombo, wacom->tool[idx], 1);
        if (idx)
@@ -744,24 +782,31 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
 
                touchInProx = 0;
 
-               if (!wacom->id[0]) { /* first in prox */
-                       /* Going into proximity select tool */
-                       wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
-                       if (wacom->tool[0] == BTN_TOOL_PEN)
-                               wacom->id[0] = STYLUS_DEVICE_ID;
-                       else
-                               wacom->id[0] = ERASER_DEVICE_ID;
-               }
-               wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
-               wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
-               wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
-               wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
-               pressure = ((data[7] & 0x01) << 8) | data[6];
-               if (pressure < 0)
-                       pressure = features->pressure_max + pressure + 1;
-               wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
-               wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
-               if (!prox) { /* out-prox */
+               if (prox) { /* in prox */
+                       if (!wacom->id[0]) {
+                               /* Going into proximity select tool */
+                               wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+                               if (wacom->tool[0] == BTN_TOOL_PEN)
+                                       wacom->id[0] = STYLUS_DEVICE_ID;
+                               else
+                                       wacom->id[0] = ERASER_DEVICE_ID;
+                       }
+                       wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
+                       wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
+                       wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+                       wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+                       pressure = ((data[7] & 0x01) << 8) | data[6];
+                       if (pressure < 0)
+                               pressure = features->pressure_max + pressure + 1;
+                       wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
+                       wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05);
+               } else {
+                       wacom_report_abs(wcombo, ABS_X, 0);
+                       wacom_report_abs(wcombo, ABS_Y, 0);
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
                        wacom->id[0] = 0;
                        /* pen is out so touch can be enabled now */
                        touchInProx = 1;
index 0be15c7..47a5ffe 100644 (file)
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/timer.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index eb7e271..964a55f 100644 (file)
@@ -12,8 +12,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/slab.h>
-#include <linux/ctype.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/isdn/capilli.h>
index 0b39b38..f6f45f2 100644 (file)
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/slab.h>
 
 /* Version Information */
 #define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
index 9ef5b04..05947f9 100644 (file)
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <linux/ctype.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include <linux/usb.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/ppp_defs.h>
index c99fb97..c22e5ac 100644 (file)
@@ -15,7 +15,6 @@
 
 #include "gigaset.h"
 #include <linux/isdnif.h>
-#include <linux/slab.h>
 
 #define HW_HDR_LEN     2       /* Header size used to store ack info */
 
index f0dc6c9..c9f28dd 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "gigaset.h"
 #include <linux/gigaset_dev.h>
-#include <linux/tty.h>
 #include <linux/tty_flip.h>
 
 /*** our ioctls ***/
index b69f73a..b943efb 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include "gigaset.h"
-#include <linux/ctype.h>
 
 static ssize_t show_cidmode(struct device *dev,
                            struct device_attribute *attr, char *buf)
index 8b0afd2..e96c058 100644 (file)
  */
 
 #include "gigaset.h"
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
-#include <linux/tty.h>
 #include <linux/completion.h>
-#include <linux/slab.h>
 
 /* Version Information */
 #define DRIVER_AUTHOR "Tilman Schmidt"
index 9430a2b..76dbb20 100644 (file)
  */
 
 #include "gigaset.h"
-
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
index 07090f3..69c84a1 100644 (file)
@@ -178,7 +178,7 @@ static void set_status(struct virtio_device *vdev, u8 status)
 
        /* We set the status. */
        to_lgdev(vdev)->desc->status = status;
-       kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
+       hcall(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset, 0, 0, 0);
 }
 
 static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -229,7 +229,7 @@ static void lg_notify(struct virtqueue *vq)
         */
        struct lguest_vq_info *lvq = vq->priv;
 
-       kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
+       hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0, 0);
 }
 
 /* An extern declaration inside a C file is bad form.  Don't do it. */
index fb2b7ef..b4eb675 100644 (file)
@@ -288,6 +288,18 @@ static int emulate_insn(struct lg_cpu *cpu)
        insn = lgread(cpu, physaddr, u8);
 
        /*
+        * Around 2.6.33, the kernel started using an emulation for the
+        * cmpxchg8b instruction in early boot on many configurations.  This
+        * code isn't paravirtualized, and it tries to disable interrupts.
+        * Ignore it, which will Mostly Work.
+        */
+       if (insn == 0xfa) {
+               /* "cli", or Clear Interrupt Enable instruction.  Skip it. */
+               cpu->regs->eip++;
+               return 1;
+       }
+
+       /*
         * 0x66 is an "operand prefix".  It means it's using the upper 16 bits
         * of the eax register.
         */
index e3e9a36..20e4840 100644 (file)
@@ -1650,8 +1650,8 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
                                     int previous, int *dd_idx,
                                     struct stripe_head *sh)
 {
-       long stripe;
-       unsigned long chunk_number;
+       sector_t stripe;
+       sector_t chunk_number;
        unsigned int chunk_offset;
        int pd_idx, qd_idx;
        int ddf_layout = 0;
@@ -1671,17 +1671,12 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
         */
        chunk_offset = sector_div(r_sector, sectors_per_chunk);
        chunk_number = r_sector;
-       BUG_ON(r_sector != chunk_number);
 
        /*
         * Compute the stripe number
         */
-       stripe = chunk_number / data_disks;
-
-       /*
-        * Compute the data disk and parity disk indexes inside the stripe
-        */
-       *dd_idx = chunk_number % data_disks;
+       stripe = chunk_number;
+       *dd_idx = sector_div(stripe, data_disks);
 
        /*
         * Select the parity disk based on the user selected algorithm.
@@ -1870,14 +1865,14 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
                                 : conf->algorithm;
        sector_t stripe;
        int chunk_offset;
-       int chunk_number, dummy1, dd_idx = i;
+       sector_t chunk_number;
+       int dummy1, dd_idx = i;
        sector_t r_sector;
        struct stripe_head sh2;
 
 
        chunk_offset = sector_div(new_sector, sectors_per_chunk);
        stripe = new_sector;
-       BUG_ON(new_sector != stripe);
 
        if (i == sh->pd_idx)
                return 0;
@@ -1970,7 +1965,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
        }
 
        chunk_number = stripe * data_disks + i;
-       r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
+       r_sector = chunk_number * sectors_per_chunk + chunk_offset;
 
        check = raid5_compute_sector(conf, r_sector,
                                     previous, &dummy1, &sh2);
index 9781942..4b451a7 100644 (file)
@@ -2334,13 +2334,13 @@ static int cnic_service_bnx2x(void *data, void *status_blk)
        struct cnic_local *cp = dev->cnic_priv;
        u16 prod = cp->kcq_prod_idx & MAX_KCQ_IDX;
 
-       prefetch(cp->status_blk.bnx2x);
-       prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
+       if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags))) {
+               prefetch(cp->status_blk.bnx2x);
+               prefetch(&cp->kcq[KCQ_PG(prod)][KCQ_IDX(prod)]);
 
-       if (likely(test_bit(CNIC_F_CNIC_UP, &dev->flags)))
                tasklet_schedule(&cp->cnic_irq_task);
-
-       cnic_chk_pkt_rings(cp);
+               cnic_chk_pkt_rings(cp);
+       }
 
        return 0;
 }
index cfd09ce..73d43c5 100644 (file)
@@ -661,6 +661,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
                                i = 0;
                }
 
+               if (i == tx_ring->next_to_use)
+                       break;
                eop = tx_ring->buffer_info[i].next_to_watch;
                eop_desc = E1000_TX_DESC(*tx_ring, eop);
        }
index 73b260c..5c98f7c 100644 (file)
@@ -5899,7 +5899,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        /* Limit the number of tx's outstanding for hw bug */
        if (id->driver_data & DEV_NEED_TX_LIMIT) {
                np->tx_limit = 1;
-               if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
+               if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) &&
                    pci_dev->revision >= 0xA2)
                        np->tx_limit = 0;
        }
index d313fae..7430384 100644 (file)
@@ -1814,6 +1814,7 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
                retval = 0;
                break;
        case E1000_DEV_ID_82576_QUAD_COPPER:
+       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
                /* quad port adapters only support WoL on port A */
                if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
                        wol->supported = 0;
index 9b3c51a..c9baa2a 100644 (file)
@@ -1612,6 +1612,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
                        adapter->eeprom_wol = 0;
                break;
        case E1000_DEV_ID_82576_QUAD_COPPER:
+       case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
                /* if quad port adapter, disable WoL on all but port A */
                if (global_quad_port_a != 0)
                        adapter->eeprom_wol = 0;
index 4718877..ecde087 100644 (file)
@@ -1690,7 +1690,7 @@ myri10ge_set_pauseparam(struct net_device *netdev,
        if (pause->tx_pause != mgp->pause)
                return myri10ge_change_pause(mgp, pause->tx_pause);
        if (pause->rx_pause != mgp->pause)
-               return myri10ge_change_pause(mgp, pause->tx_pause);
+               return myri10ge_change_pause(mgp, pause->rx_pause);
        if (pause->autoneg != 0)
                return -EINVAL;
        return 0;
index ff7eb91..fd9d6e3 100644 (file)
@@ -1608,9 +1608,12 @@ static void set_rx_mode(struct net_device *dev)
 {
     unsigned int ioaddr = dev->base_addr;
     struct smc_private *smc = netdev_priv(dev);
-    u_int multicast_table[ 2 ] = { 0, };
+    unsigned char multicast_table[8];
     unsigned long flags;
     u_short rx_cfg_setting;
+    int i;
+
+    memset(multicast_table, 0, sizeof(multicast_table));
 
     if (dev->flags & IFF_PROMISC) {
        rx_cfg_setting = RxStripCRC | RxEnable | RxPromisc | RxAllMulti;
@@ -1622,10 +1625,6 @@ static void set_rx_mode(struct net_device *dev)
 
            netdev_for_each_mc_addr(mc_addr, dev) {
                u_int position = ether_crc(6, mc_addr->dmi_addr);
-#ifndef final_version          /* Verify multicast address. */
-               if ((mc_addr->dmi_addr[0] & 1) == 0)
-                   continue;
-#endif
                multicast_table[position >> 29] |= 1 << ((position >> 26) & 7);
            }
        }
@@ -1635,8 +1634,8 @@ static void set_rx_mode(struct net_device *dev)
     /* Load MC table and Rx setting into the chip without interrupts. */
     spin_lock_irqsave(&smc->lock, flags);
     SMC_SELECT_BANK(3);
-    outl(multicast_table[0], ioaddr + MULTICAST0);
-    outl(multicast_table[1], ioaddr + MULTICAST4);
+    for (i = 0; i < 8; i++)
+       outb(multicast_table[i], ioaddr + MULTICAST0 + i);
     SMC_SELECT_BANK(0);
     outw(rx_cfg_setting, ioaddr + RCR);
     SMC_SELECT_BANK(2);
index a6ef266..e73ba45 100644 (file)
@@ -431,6 +431,9 @@ void qlcnic_set_multi(struct net_device *netdev)
        u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        u32 mode = VPORT_MISS_MODE_DROP;
 
+       if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
+               return;
+
        qlcnic_nic_add_mac(adapter, adapter->mac_addr);
        qlcnic_nic_add_mac(adapter, bcast_addr);
 
index 43afdb6..0298d8c 100644 (file)
 #define RX_DESC_SIZE   (RX_DCNT * sizeof(struct r6040_descriptor))
 #define TX_DESC_SIZE   (TX_DCNT * sizeof(struct r6040_descriptor))
 #define MBCR_DEFAULT   0x012A  /* MAC Bus Control Register */
-#define MCAST_MAX      4       /* Max number multicast addresses to filter */
+#define MCAST_MAX      3       /* Max number multicast addresses to filter */
 
 /* Descriptor status */
 #define DSC_OWNER_MAC  0x8000  /* MAC is the owner of this descriptor */
@@ -982,9 +982,6 @@ static void r6040_multicast_list(struct net_device *dev)
                        crc >>= 26;
                        hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
                }
-               /* Write the index of the hash table */
-               for (i = 0; i < 4; i++)
-                       iowrite16(hash_table[i] << 14, ioaddr + MCR1);
                /* Fill the MAC hash tables with their values */
                iowrite16(hash_table[0], ioaddr + MAR0);
                iowrite16(hash_table[1], ioaddr + MAR1);
@@ -1000,9 +997,9 @@ static void r6040_multicast_list(struct net_device *dev)
                        iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
                        iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
                } else {
-                       iowrite16(0xffff, ioaddr + MID_0L + 8 * i);
-                       iowrite16(0xffff, ioaddr + MID_0M + 8 * i);
-                       iowrite16(0xffff, ioaddr + MID_0H + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
+                       iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
                }
                i++;
        }
index a214a16..4111a85 100644 (file)
@@ -1686,7 +1686,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
        }
        pr_info("done!\n");
 
-       if (!request_mem_region(res->start, (res->end - res->start),
+       if (!request_mem_region(res->start, resource_size(res),
                                pdev->name)) {
                pr_err("%s: ERROR: memory allocation failed"
                       "cannot get the I/O addr 0x%x\n",
@@ -1695,9 +1695,9 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
                goto out;
        }
 
-       addr = ioremap(res->start, (res->end - res->start));
+       addr = ioremap(res->start, resource_size(res));
        if (!addr) {
-               pr_err("%s: ERROR: memory mapping failed \n", __func__);
+               pr_err("%s: ERROR: memory mapping failed\n", __func__);
                ret = -ENOMEM;
                goto out;
        }
@@ -1775,7 +1775,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev)
 out:
        if (ret < 0) {
                platform_set_drvdata(pdev, NULL);
-               release_mem_region(res->start, (res->end - res->start));
+               release_mem_region(res->start, resource_size(res));
                if (addr != NULL)
                        iounmap(addr);
        }
@@ -1813,7 +1813,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev)
 
        iounmap((void *)ndev->base_addr);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, (res->end - res->start));
+       release_mem_region(res->start, resource_size(res));
 
        free_netdev(ndev);
 
index 96c39bd..4326520 100644 (file)
@@ -387,6 +387,10 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
+       /* Orphan the skb - required as we might hang on to it
+        * for indefinite time. */
+       skb_orphan(skb);
+
        /* Enqueue packet */
        skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
        dev->trans_start = jiffies;
index 6fb783c..b0577dd 100644 (file)
@@ -327,6 +327,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
        struct scatterlist sg[2];
        int err;
 
+       sg_init_table(sg, 2);
        skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
        if (unlikely(!skb))
                return -ENOMEM;
@@ -352,6 +353,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
        char *p;
        int i, err, offset;
 
+       sg_init_table(sg, MAX_SKB_FRAGS + 2);
        /* page in sg[MAX_SKB_FRAGS + 1] is list tail */
        for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
                first = get_a_page(vi, gfp);
index b9b9d6b..941f053 100644 (file)
@@ -628,9 +628,15 @@ static void ppp_stop(struct net_device *dev)
        ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL);
 }
 
+static void ppp_close(struct net_device *dev)
+{
+       ppp_tx_flush();
+}
+
 static struct hdlc_proto proto = {
        .start          = ppp_start,
        .stop           = ppp_stop,
+       .close          = ppp_close,
        .type_trans     = ppp_type_trans,
        .ioctl          = ppp_ioctl,
        .netif_rx       = ppp_rx,
index 67ca4e5..115e1ae 100644 (file)
@@ -1532,8 +1532,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
                all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
                ath9k_set_wiphy_idle(aphy, idle);
 
-               if (!idle && all_wiphys_idle)
-                       enable_radio = true;
+               enable_radio = (!idle && all_wiphys_idle);
 
                /*
                 * After we unlock here its possible another wiphy
index 83c52a6..8972166 100644 (file)
@@ -2015,7 +2015,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                        IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
                                           "%d index %d\n", scd_ssn , index);
                        freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+                       if (qc)
+                               iwl_free_tfds_in_queue(priv, sta_id,
+                                                      tid, freed);
 
                        if (priv->mac80211_registered &&
                            (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -2041,14 +2043,17 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
                                   tx_resp->failure_frame);
 
                freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-               iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+               if (qc && likely(sta_id != IWL_INVALID_STATION))
+                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
+               else if (sta_id == IWL_INVALID_STATION)
+                       IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
 
                if (priv->mac80211_registered &&
                    (iwl_queue_space(&txq->q) > txq->q.low_mark))
                        iwl_wake_queue(priv, txq_id);
        }
-
-       iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+       if (qc && likely(sta_id != IWL_INVALID_STATION))
+               iwl_txq_check_empty(priv, sta_id, tid, txq_id);
 
        if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
                IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
index 35f819a..1460116 100644 (file)
@@ -346,6 +346,17 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
               !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
 }
 
+/*
+ * Static function to get the expected throughput from an iwl_scale_tbl_info
+ * that wraps a NULL pointer check
+ */
+static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
+{
+       if (tbl->expected_tpt)
+               return tbl->expected_tpt[rs_index];
+       return 0;
+}
+
 /**
  * rs_collect_tx_data - Update the success/failure sliding window
  *
@@ -353,19 +364,21 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
  * at this rate.  window->data contains the bitmask of successful
  * packets.
  */
-static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
-                             int scale_index, s32 tpt, int attempts,
-                             int successes)
+static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
+                             int scale_index, int attempts, int successes)
 {
        struct iwl_rate_scale_data *window = NULL;
        static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
-       s32 fail_count;
+       s32 fail_count, tpt;
 
        if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
                return -EINVAL;
 
        /* Select window for current tx bit rate */
-       window = &(windows[scale_index]);
+       window = &(tbl->win[scale_index]);
+
+       /* Get expected throughput */
+       tpt = get_expected_tpt(tbl, scale_index);
 
        /*
         * Keep track of only the latest 62 tx frame attempts in this rate's
@@ -739,16 +752,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a,
        return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
                (a->is_SGI == b->is_SGI);
 }
-/*
- * Static function to get the expected throughput from an iwl_scale_tbl_info
- * that wraps a NULL pointer check
- */
-static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
-{
-       if (tbl->expected_tpt)
-               return tbl->expected_tpt[rs_index];
-       return 0;
-}
 
 /*
  * mac80211 sends us Tx status
@@ -765,12 +768,10 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct iwl_rate_scale_data *window = NULL;
        enum mac80211_rate_control_flags mac_flags;
        u32 tx_rate;
        struct iwl_scale_tbl_info tbl_type;
-       struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
-       s32 tpt = 0;
+       struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
 
        IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
 
@@ -853,7 +854,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
                return;
        }
-       window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
 
        /*
         * Updating the frame history depends on whether packets were
@@ -866,8 +866,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
                rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
                                &rs_index);
-               tpt = get_expected_tpt(curr_tbl, rs_index);
-               rs_collect_tx_data(window, rs_index, tpt,
+               rs_collect_tx_data(curr_tbl, rs_index,
                                   info->status.ampdu_ack_len,
                                   info->status.ampdu_ack_map);
 
@@ -897,19 +896,13 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
                         * table as active/search.
                         */
                        if (table_type_matches(&tbl_type, curr_tbl))
-                               tpt = get_expected_tpt(curr_tbl, rs_index);
+                               tmp_tbl = curr_tbl;
                        else if (table_type_matches(&tbl_type, other_tbl))
-                               tpt = get_expected_tpt(other_tbl, rs_index);
+                               tmp_tbl = other_tbl;
                        else
                                continue;
-
-                       /* Constants mean 1 transmission, 0 successes */
-                       if (i < retries)
-                               rs_collect_tx_data(window, rs_index, tpt, 1,
-                                               0);
-                       else
-                               rs_collect_tx_data(window, rs_index, tpt, 1,
-                                               legacy_success);
+                       rs_collect_tx_data(tmp_tbl, rs_index, 1,
+                                          i < retries ? 0 : legacy_success);
                }
 
                /* Update success/fail counts if not searching for new mode */
index de3b3f4..8b516c5 100644 (file)
@@ -808,6 +808,18 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
                }
        }
 
+       /*
+        * The above algorithm sometimes fails when the ucode
+        * reports 0 for all chains. It's not clear why that
+        * happens to start with, but it is then causing trouble
+        * because this can make us enable more chains than the
+        * hardware really has.
+        *
+        * To be safe, simply mask out any chains that we know
+        * are not on the device.
+        */
+       active_chains &= priv->hw_params.valid_rx_ant;
+
        num_tx_chains = 0;
        for (i = 0; i < NUM_RX_CHAINS; i++) {
                /* loops on all the bits of
index db050b8..3352f70 100644 (file)
@@ -308,10 +308,13 @@ int iwl_hw_nic_init(struct iwl_priv *priv)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       /* Allocate and init all Tx and Command queues */
-       ret = iwl_txq_ctx_reset(priv);
-       if (ret)
-               return ret;
+       /* Allocate or reset and init all Tx and Command queues */
+       if (!priv->txq) {
+               ret = iwl_txq_ctx_alloc(priv);
+               if (ret)
+                       return ret;
+       } else
+               iwl_txq_ctx_reset(priv);
 
        set_bit(STATUS_INIT, &priv->status);
 
index 4ef7739..732590f 100644 (file)
@@ -442,7 +442,8 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 /*****************************************************
 * TX
 ******************************************************/
-int iwl_txq_ctx_reset(struct iwl_priv *priv);
+int iwl_txq_ctx_alloc(struct iwl_priv *priv);
+void iwl_txq_ctx_reset(struct iwl_priv *priv);
 void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
                                 struct iwl_tx_queue *txq,
@@ -456,6 +457,8 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
 void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                      int slots_num, u32 txq_id);
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+                       int slots_num, u32 txq_id);
 void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
 int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
 int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
index f0b7e6c..8dd0c03 100644 (file)
@@ -194,10 +194,34 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
        struct iwl_queue *q = &txq->q;
        struct device *dev = &priv->pci_dev->dev;
        int i;
+       bool huge = false;
 
        if (q->n_bd == 0)
                return;
 
+       for (; q->read_ptr != q->write_ptr;
+            q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+               /* we have no way to tell if it is a huge cmd ATM */
+               i = get_cmd_index(q, q->read_ptr, 0);
+
+               if (txq->meta[i].flags & CMD_SIZE_HUGE) {
+                       huge = true;
+                       continue;
+               }
+
+               pci_unmap_single(priv->pci_dev,
+                                pci_unmap_addr(&txq->meta[i], mapping),
+                                pci_unmap_len(&txq->meta[i], len),
+                                PCI_DMA_BIDIRECTIONAL);
+       }
+       if (huge) {
+               i = q->n_window;
+               pci_unmap_single(priv->pci_dev,
+                                pci_unmap_addr(&txq->meta[i], mapping),
+                                pci_unmap_len(&txq->meta[i], len),
+                                PCI_DMA_BIDIRECTIONAL);
+       }
+
        /* De-alloc array of command/tx buffers */
        for (i = 0; i <= TFD_CMD_SLOTS; i++)
                kfree(txq->cmd[i]);
@@ -410,6 +434,26 @@ out_free_arrays:
 }
 EXPORT_SYMBOL(iwl_tx_queue_init);
 
+void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+                       int slots_num, u32 txq_id)
+{
+       int actual_slots = slots_num;
+
+       if (txq_id == IWL_CMD_QUEUE_NUM)
+               actual_slots++;
+
+       memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+
+       txq->need_update = 0;
+
+       /* Initialize queue's high/low-water marks, and head/tail indexes */
+       iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+
+       /* Tell device where to find queue */
+       priv->cfg->ops->lib->txq_init(priv, txq);
+}
+EXPORT_SYMBOL(iwl_tx_queue_reset);
+
 /**
  * iwl_hw_txq_ctx_free - Free TXQ Context
  *
@@ -421,8 +465,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 
        /* Tx queues */
        if (priv->txq) {
-               for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
-                    txq_id++)
+               for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
                        if (txq_id == IWL_CMD_QUEUE_NUM)
                                iwl_cmd_queue_free(priv);
                        else
@@ -438,15 +481,15 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
 EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
 
 /**
- * iwl_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialize them again
+ * iwl_txq_ctx_alloc - allocate TX queue context
+ * Allocate all Tx DMA structures and initialize them
  *
  * @param priv
  * @return error code
  */
-int iwl_txq_ctx_reset(struct iwl_priv *priv)
+int iwl_txq_ctx_alloc(struct iwl_priv *priv)
 {
-       int ret = 0;
+       int ret;
        int txq_id, slots_num;
        unsigned long flags;
 
@@ -504,8 +547,31 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
        return ret;
 }
 
+void iwl_txq_ctx_reset(struct iwl_priv *priv)
+{
+       int txq_id, slots_num;
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Turn off all Tx DMA fifos */
+       priv->cfg->ops->lib->txq_set_sched(priv, 0);
+
+       /* Tell NIC where to find the "keep warm" buffer */
+       iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       /* Alloc and init all Tx queues, including the command queue (#4) */
+       for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
+               slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
+                           TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
+               iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
+       }
+}
+
 /**
- * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
+ * iwl_txq_ctx_stop - Stop all Tx DMA channels
  */
 void iwl_txq_ctx_stop(struct iwl_priv *priv)
 {
@@ -525,9 +591,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
                                    1000);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
-
-       /* Deallocate memory for all Tx queues */
-       iwl_hw_txq_ctx_free(priv);
 }
 EXPORT_SYMBOL(iwl_txq_ctx_stop);
 
@@ -1050,6 +1113,14 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
        spin_lock_irqsave(&priv->hcmd_lock, flags);
 
+       /* If this is a huge cmd, mark the huge flag also on the meta.flags
+        * of the _original_ cmd. This is used for DMA mapping clean up.
+        */
+       if (cmd->flags & CMD_SIZE_HUGE) {
+               idx = get_cmd_index(q, q->write_ptr, 0);
+               txq->meta[idx].flags = CMD_SIZE_HUGE;
+       }
+
        idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
        out_cmd = txq->cmd[idx];
        out_meta = &txq->meta[idx];
@@ -1227,6 +1298,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
        struct iwl_device_cmd *cmd;
        struct iwl_cmd_meta *meta;
+       struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
 
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
@@ -1240,9 +1312,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                return;
        }
 
-       cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
-       cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
-       meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
+       /* If this is a huge cmd, clear the huge flag on the meta.flags
+        * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
+        * the DMA buffer for the scan (huge) command.
+        */
+       if (huge) {
+               cmd_index = get_cmd_index(&txq->q, index, 0);
+               txq->meta[cmd_index].flags = 0;
+       }
+       cmd_index = get_cmd_index(&txq->q, index, huge);
+       cmd = txq->cmd[cmd_index];
+       meta = &txq->meta[cmd_index];
 
        pci_unmap_single(priv->pci_dev,
                         pci_unmap_addr(meta, mapping),
@@ -1264,6 +1344,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                               get_cmd_string(cmd->hdr.cmd));
                wake_up_interruptible(&priv->wait_command_queue);
        }
+       meta->flags = 0;
 }
 EXPORT_SYMBOL(iwl_tx_cmd_complete);
 
index f230f65..854959c 100644 (file)
@@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
        if (!s)
                return -EINVAL;
 
+       if (s->functions) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
        /* We do not want to validate the CIS cache... */
        mutex_lock(&s->ops_mutex);
        destroy_cis_cache(s);
@@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
                count = 0;
        else {
                struct pcmcia_socket *s;
-               unsigned int chains;
+               unsigned int chains = 1;
 
                if (off + count > size)
                        count = size - off;
@@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
 
                if (!(s->state & SOCKET_PRESENT))
                        return -ENODEV;
-               if (pccard_validate_cis(s, &chains))
+               if (!s->functions && pccard_validate_cis(s, &chains))
                        return -EIO;
                if (!chains)
                        return -ENODATA;
index 6206408..2d48196 100644 (file)
@@ -166,8 +166,10 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
 
                ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
                                  IRQF_DISABLED, "pcmcia_insert", sock);
-               if (ret)
+               if (ret) {
+                       local_irq_restore(flags);
                        goto out1;
+               }
 
                ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq,
                                  IRQF_DISABLED, "pcmcia_eject", sock);
index cb6036d..4014cf8 100644 (file)
@@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)
                        new_funcs = mfc.nfn;
                else
                        new_funcs = 1;
-               if (old_funcs > new_funcs) {
+               if (old_funcs != new_funcs) {
+                       /* we need to re-start */
                        pcmcia_card_remove(s, NULL);
                        pcmcia_card_add(s);
-               } else if (new_funcs > old_funcs) {
-                       s->functions = new_funcs;
-                       pcmcia_device_add(s, 1);
                }
        }
 
@@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
        struct pcmcia_socket *s = dev->socket;
        const struct firmware *fw;
        int ret = -ENOMEM;
+       cistpl_longlink_mfc_t mfc;
+       int old_funcs, new_funcs = 1;
 
        if (!filename)
                return -EINVAL;
@@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
                        goto release;
                }
 
+               /* we need to re-start if the number of functions changed */
+               old_funcs = s->functions;
+               if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
+                                       &mfc))
+                       new_funcs = mfc.nfn;
+
+               if (old_funcs != new_funcs)
+                       ret = -EBUSY;
 
                /* update information */
                pcmcia_device_query(dev);
@@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
                dev_dbg(&dev->dev, "device needs a fake CIS\n");
                if (!dev->socket->fake_cis)
-                       pcmcia_load_firmware(dev, did->cisfile);
-
-               if (!dev->socket->fake_cis)
-                       return 0;
+                       if (pcmcia_load_firmware(dev, did->cisfile))
+                               return 0;
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
index caec1de..7c3d03b 100644 (file)
@@ -755,12 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
        else
                printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
 
-#ifdef CONFIG_PCMCIA_PROBE
-
-       if (s->irq.AssignedIRQ != 0) {
-               /* If the interrupt is already assigned, it must be the same */
+       /* If the interrupt is already assigned, it must be the same */
+       if (s->irq.AssignedIRQ != 0)
                irq = s->irq.AssignedIRQ;
-       } else {
+
+#ifdef CONFIG_PCMCIA_PROBE
+       if (!irq) {
                int try;
                u32 mask = s->irq_mask;
                void *data = p_dev; /* something unique to this device */
index 559069a..a6eb7b5 100644 (file)
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
                return;
        }
        for (i = base, most = 0; i < base+num; i += 8) {
-               res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+               res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
                if (!res)
                        continue;
                hole = inb(i);
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
 
        bad = any = 0;
        for (i = base; i < base+num; i += 8) {
-               res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
-               if (!res)
+               res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
+               if (!res) {
+                       if (!any)
+                               printk(" excluding");
+                       if (!bad)
+                               bad = any = i;
                        continue;
+               }
                for (j = 0; j < 8; j++)
                        if (inb(i+j) != most)
                                break;
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
        }
        if (bad) {
                if ((num > 16) && (bad == base) && (i == base+num)) {
+                       sub_interval(&s_data->io_db, bad, i-bad);
                        printk(" nothing: probe failed.\n");
                        return;
                } else {
@@ -804,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
 static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
 {
        struct socket_data *data = s->resource_data;
-       unsigned long size = end - start + 1;
+       unsigned long size;
        int ret = 0;
 
 #if defined(CONFIG_X86)
@@ -814,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
                start = 0x100;
 #endif
 
+       size = end - start + 1;
+
        if (end < start)
                return -EINVAL;
 
index a681f5e..ad036dd 100644 (file)
@@ -618,9 +618,12 @@ static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
                dev_get_platdata(&pdev->dev);
        int i;
 
+       platform_set_drvdata(pdev, NULL);
+
        for (i = 0; i < pdata->num_regulators; i++)
                regulator_unregister(priv->regulators[i]);
 
+       kfree(priv);
        return 0;
 }
 
index 2aecf7f..7ad30e7 100644 (file)
@@ -85,7 +85,7 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write,
                rc = copy_from_user(buf, buffer, sizeof(buf));
                if (rc != 0)
                        return -EFAULT;
-               buf[len - 1] = '\0';
+               buf[sizeof(buf) - 1] = '\0';
                if (strict_strtoul(buf, 0, &val) != 0)
                        return -EINVAL;
                if (val != 0 && val != 1)
index 58c62ff..8b827f3 100644 (file)
@@ -2186,7 +2186,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
        blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
 
        gd->driverfs_dev = &sdp->sdev_gendev;
-       gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
+       gd->flags = GENHD_FL_EXT_DEVT;
        if (sdp->removable)
                gd->flags |= GENHD_FL_REMOVABLE;
 
index 7bb5fee..b5aaef9 100644 (file)
@@ -263,6 +263,7 @@ static void mcf_set_termios(struct uart_port *port, struct ktermios *termios,
        }
 
        spin_lock_irqsave(&port->lock, flags);
+       uart_update_timeout(port, termios->c_cflag, baud);
        writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
        writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
        writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR);
@@ -379,6 +380,7 @@ static irqreturn_t mcf_interrupt(int irq, void *data)
 static void mcf_config_port(struct uart_port *port, int flags)
 {
        port->type = PORT_MCF;
+       port->fifosize = MCFUART_TXFIFOSIZE;
 
        /* Clear mask, so no surprise interrupts. */
        writeb(0, port->membase + MCFUART_UIMR);
@@ -424,7 +426,7 @@ static int mcf_verify_port(struct uart_port *port, struct serial_struct *ser)
 /*
  *     Define the basic serial functions we support.
  */
-static struct uart_ops mcf_uart_ops = {
+static const struct uart_ops mcf_uart_ops = {
        .tx_empty       = mcf_tx_empty,
        .get_mctrl      = mcf_get_mctrl,
        .set_mctrl      = mcf_set_mctrl,
@@ -443,7 +445,7 @@ static struct uart_ops mcf_uart_ops = {
        .verify_port    = mcf_verify_port,
 };
 
-static struct mcf_uart mcf_ports[3];
+static struct mcf_uart mcf_ports[4];
 
 #define        MCF_MAXPORTS    ARRAY_SIZE(mcf_ports)
 
index 175d202..8cfa5b1 100644 (file)
@@ -105,6 +105,10 @@ struct serial_cfg_mem {
  * manfid 0x0160, 0x0104
  * This card appears to have a 14.7456MHz clock.
  */
+/* Generic Modem: MD55x (GPRS/EDGE) have
+ * Elan VPU16551 UART with 14.7456MHz oscillator
+ * manfid 0x015D, 0x4C45
+ */
 static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
 {
        port->uartclk = 14745600;
@@ -196,6 +200,11 @@ static const struct serial_quirk quirks[] = {
                .multi  = -1,
                .setup  = quirk_setup_brainboxes_0104,
        }, {
+               .manfid = 0x015D,
+               .prodid = 0x4C45,
+               .multi  = -1,
+               .setup  = quirk_setup_brainboxes_0104,
+       }, {
                .manfid = MANFID_IBM,
                .prodid = ~0,
                .multi  = -1,
index f1dcd79..0e8d352 100644 (file)
@@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore_controller = {
        .pci_ops        = &ssb_pcicore_pciops,
        .io_resource    = &ssb_pcicore_io_resource,
        .mem_resource   = &ssb_pcicore_mem_resource,
-       .mem_offset     = 0x24000000,
 };
 
-static u32 ssb_pcicore_pcibus_iobase = 0x100;
-static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
-
 /* This function is called when doing a pci_enable_device().
  * We must first check if the device is a device on the PCI-core bridge. */
 int ssb_pcicore_plat_dev_init(struct pci_dev *d)
 {
-       struct resource *res;
-       int pos, size;
-       u32 *base;
-
        if (d->bus->ops != &ssb_pcicore_pciops) {
                /* This is not a device on the PCI-core bridge. */
                return -ENODEV;
@@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci_dev *d)
        ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
                   pci_name(d));
 
-       /* Fix up resource bases */
-       for (pos = 0; pos < 6; pos++) {
-               res = &d->resource[pos];
-               if (res->flags & IORESOURCE_IO)
-                       base = &ssb_pcicore_pcibus_iobase;
-               else
-                       base = &ssb_pcicore_pcibus_membase;
-               res->flags |= IORESOURCE_PCI_FIXED;
-               if (res->end) {
-                       size = res->end - res->start + 1;
-                       if (*base & (size - 1))
-                               *base = (*base + size) & ~(size - 1);
-                       res->start = *base;
-                       res->end = res->start + size - 1;
-                       *base += size;
-                       pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
-               }
-               /* Fix up PCI bridge BAR0 only */
-               if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
-                       break;
-       }
        /* Fix up interrupt lines */
        d->irq = ssb_mips_irq(extpci_core->dev) + 2;
        pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
index a67c622..e2c44ec 100644 (file)
@@ -57,19 +57,8 @@ MA 02111-1307 USA
 
 extern void printques(int);
 
-#ifdef MODULE
 #include <linux/module.h>
 #include <linux/interrupt.h>
-
-
-MODULE_LICENSE("GPL");
-
-#endif
-
-#ifndef CONFIG_PCI
-#error  "DT3155 :  Kernel PCI support not enabled (DT3155 drive requires PCI)"
-#endif
-
 #include <linux/pci.h>
 #include <linux/types.h>
 #include <linux/poll.h>
@@ -84,6 +73,9 @@ MODULE_LICENSE("GPL");
 #include "dt3155_io.h"
 #include "allocator.h"
 
+
+MODULE_LICENSE("GPL");
+
 /* Error variable.  Zero means no error. */
 int dt3155_errno = 0;
 
index 5be11c9..e69d238 100644 (file)
@@ -236,6 +236,10 @@ static int vq_memory_access_ok(void __user *log_base, struct vhost_memory *mem,
                               int log_all)
 {
        int i;
+
+        if (!mem)
+                return 0;
+
        for (i = 0; i < mem->nregions; ++i) {
                struct vhost_memory_region *m = mem->regions + i;
                unsigned long a = m->userspace_addr;
index 3aed388..bfec7c2 100644 (file)
@@ -103,7 +103,8 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num)
        num = min(num, ARRAY_SIZE(vb->pfns));
 
        for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) {
-               struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY);
+               struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY |
+                                       __GFP_NOMEMALLOC | __GFP_NOWARN);
                if (!page) {
                        if (printk_ratelimit())
                                dev_printk(KERN_INFO, &vb->vdev->dev,
index 0e8468f..0bf5020 100644 (file)
@@ -194,10 +194,10 @@ config EP93XX_WATCHDOG
 
 config OMAP_WATCHDOG
        tristate "OMAP Watchdog"
-       depends on ARCH_OMAP16XX || ARCH_OMAP2 || ARCH_OMAP3
+       depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
        help
-         Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog.  Say 'Y'
-         here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430 watchdog timer.
+         Support for TI OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog.  Say 'Y'
+         here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer.
 
 config PNX4008_WATCHDOG
        tristate "PNX4008 Watchdog"
@@ -302,7 +302,7 @@ config TS72XX_WATCHDOG
 
 config MAX63XX_WATCHDOG
        tristate "Max63xx watchdog"
-       depends on ARM
+       depends on ARM && HAS_IOMEM
        help
          Support for memory mapped max63{69,70,71,72,73,74} watchdog timer.
 
index 8b724aa..500d383 100644 (file)
@@ -44,7 +44,7 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
 
 #ifdef CONFIG_FSL_BOOKE
 #define WDTP(x)                ((((x)&0x3)<<30)|(((x)&0x3c)<<15))
-#define WDTP_MASK      (WDTP(0))
+#define WDTP_MASK      (WDTP(0x3f))
 #else
 #define WDTP(x)                (TCR_WP(x))
 #define WDTP_MASK      (TCR_WP_MASK)
index 75f3a83..3053ff0 100644 (file)
@@ -154,9 +154,14 @@ static void max63xx_wdt_enable(struct max63xx_timeout *entry)
 
 static void max63xx_wdt_disable(void)
 {
+       u8 val;
+
        spin_lock(&io_lock);
 
-       __raw_writeb(3, wdt_base);
+       val = __raw_readb(wdt_base);
+       val &= ~MAX6369_WDSET;
+       val |= 3;
+       __raw_writeb(val, wdt_base);
 
        spin_unlock(&io_lock);
 
index 5e813a8..b3feddc 100644 (file)
@@ -138,9 +138,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
 {
        struct afs_super_info *super;
        struct vfsmount *mnt;
-       struct page *page = NULL;
+       struct page *page;
        size_t size;
-       char *buf, *devname = NULL, *options = NULL;
+       char *buf, *devname, *options;
        int ret;
 
        _enter("{%s}", mntpt->d_name.name);
@@ -150,22 +150,22 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
        ret = -EINVAL;
        size = mntpt->d_inode->i_size;
        if (size > PAGE_SIZE - 1)
-               goto error;
+               goto error_no_devname;
 
        ret = -ENOMEM;
        devname = (char *) get_zeroed_page(GFP_KERNEL);
        if (!devname)
-               goto error;
+               goto error_no_devname;
 
        options = (char *) get_zeroed_page(GFP_KERNEL);
        if (!options)
-               goto error;
+               goto error_no_options;
 
        /* read the contents of the AFS special symlink */
        page = read_mapping_page(mntpt->d_inode->i_mapping, 0, NULL);
        if (IS_ERR(page)) {
                ret = PTR_ERR(page);
-               goto error;
+               goto error_no_page;
        }
 
        ret = -EIO;
@@ -196,12 +196,12 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
        return mnt;
 
 error:
-       if (page)
-               page_cache_release(page);
-       if (devname)
-               free_page((unsigned long) devname);
-       if (options)
-               free_page((unsigned long) options);
+       page_cache_release(page);
+error_no_page:
+       free_page((unsigned long) options);
+error_no_options:
+       free_page((unsigned long) devname);
+error_no_devname:
        _leave(" = %d", ret);
        return ERR_PTR(ret);
 }
index e0e769b..49566c1 100644 (file)
@@ -355,7 +355,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp)
 
        if (!flat_reloc_valid(r, start_brk - start_data + text_len)) {
                printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)",
-                      (int) r,(int)(start_brk-start_code),(int)text_len);
+                      (int) r,(int)(start_brk-start_data+text_len),(int)text_len);
                goto failed;
        }
 
index e1f9221..e7bf6ca 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -554,7 +554,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
                                        .bi_rw = bio->bi_rw,
                                };
 
-                               if (q->merge_bvec_fn(q, &bvm, prev) < len) {
+                               if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) {
                                        prev->bv_len -= len;
                                        return 0;
                                }
@@ -607,7 +607,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
                 * merge_bvec_fn() returns number of bytes it can accept
                 * at this offset
                 */
-               if (q->merge_bvec_fn(q, &bvm, bvec) < len) {
+               if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) {
                        bvec->bv_page = NULL;
                        bvec->bv_len = 0;
                        bvec->bv_offset = 0;
index 9e23ffe..b34d32f 100644 (file)
@@ -3235,7 +3235,8 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
                                u64 bytes)
 {
        struct btrfs_space_info *data_sinfo;
-       int ret = 0, committed = 0;
+       u64 used;
+       int ret = 0, committed = 0, flushed = 0;
 
        /* make sure bytes are sectorsize aligned */
        bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
@@ -3247,12 +3248,21 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
 again:
        /* make sure we have enough space to handle the data first */
        spin_lock(&data_sinfo->lock);
-       if (data_sinfo->total_bytes - data_sinfo->bytes_used -
-           data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved -
-           data_sinfo->bytes_pinned - data_sinfo->bytes_readonly -
-           data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) {
+       used = data_sinfo->bytes_used + data_sinfo->bytes_delalloc +
+               data_sinfo->bytes_reserved + data_sinfo->bytes_pinned +
+               data_sinfo->bytes_readonly + data_sinfo->bytes_may_use +
+               data_sinfo->bytes_super;
+
+       if (used + bytes > data_sinfo->total_bytes) {
                struct btrfs_trans_handle *trans;
 
+               if (!flushed) {
+                       spin_unlock(&data_sinfo->lock);
+                       flush_delalloc(root, data_sinfo);
+                       flushed = 1;
+                       goto again;
+               }
+
                /*
                 * if we don't have enough free bytes in this space then we need
                 * to alloc a new chunk.
index aa7dc36..8db7b14 100644 (file)
@@ -2250,6 +2250,12 @@ again:
        if (!looped)
                calc_size = max_t(u64, min_stripe_size, calc_size);
 
+       /*
+        * we're about to do_div by the stripe_len so lets make sure
+        * we end up with something bigger than a stripe
+        */
+       calc_size = max_t(u64, calc_size, stripe_len * 4);
+
        do_div(calc_size, stripe_len);
        calc_size *= stripe_len;
 
index aa3cd7c..4125937 100644 (file)
@@ -337,16 +337,15 @@ out:
 /*
  * Get ref for the oldest snapc for an inode with dirty data... that is, the
  * only snap context we are allowed to write back.
- *
- * Caller holds i_lock.
  */
-static struct ceph_snap_context *__get_oldest_context(struct inode *inode,
-                                                     u64 *snap_size)
+static struct ceph_snap_context *get_oldest_context(struct inode *inode,
+                                                   u64 *snap_size)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_snap_context *snapc = NULL;
        struct ceph_cap_snap *capsnap = NULL;
 
+       spin_lock(&inode->i_lock);
        list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
                dout(" cap_snap %p snapc %p has %d dirty pages\n", capsnap,
                     capsnap->context, capsnap->dirty_pages);
@@ -357,21 +356,11 @@ static struct ceph_snap_context *__get_oldest_context(struct inode *inode,
                        break;
                }
        }
-       if (!snapc && ci->i_snap_realm) {
-               snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context);
+       if (!snapc && ci->i_head_snapc) {
+               snapc = ceph_get_snap_context(ci->i_head_snapc);
                dout(" head snapc %p has %d dirty pages\n",
                     snapc, ci->i_wrbuffer_ref_head);
        }
-       return snapc;
-}
-
-static struct ceph_snap_context *get_oldest_context(struct inode *inode,
-                                                   u64 *snap_size)
-{
-       struct ceph_snap_context *snapc = NULL;
-
-       spin_lock(&inode->i_lock);
-       snapc = __get_oldest_context(inode, snap_size);
        spin_unlock(&inode->i_lock);
        return snapc;
 }
@@ -392,7 +381,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
        int len = PAGE_CACHE_SIZE;
        loff_t i_size;
        int err = 0;
-       struct ceph_snap_context *snapc;
+       struct ceph_snap_context *snapc, *oldest;
        u64 snap_size = 0;
        long writeback_stat;
 
@@ -413,13 +402,16 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
                dout("writepage %p page %p not dirty?\n", inode, page);
                goto out;
        }
-       if (snapc != get_oldest_context(inode, &snap_size)) {
+       oldest = get_oldest_context(inode, &snap_size);
+       if (snapc->seq > oldest->seq) {
                dout("writepage %p page %p snapc %p not writeable - noop\n",
                     inode, page, (void *)page->private);
                /* we should only noop if called by kswapd */
                WARN_ON((current->flags & PF_MEMALLOC) == 0);
+               ceph_put_snap_context(oldest);
                goto out;
        }
+       ceph_put_snap_context(oldest);
 
        /* is this a partial page at end of file? */
        if (snap_size)
@@ -458,7 +450,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
        ClearPagePrivate(page);
        end_page_writeback(page);
        ceph_put_wrbuffer_cap_refs(ci, 1, snapc);
-       ceph_put_snap_context(snapc);
+       ceph_put_snap_context(snapc);  /* page's reference */
 out:
        return err;
 }
@@ -558,9 +550,9 @@ static void writepages_finish(struct ceph_osd_request *req,
                        dout("inode %p skipping page %p\n", inode, page);
                        wbc->pages_skipped++;
                }
+               ceph_put_snap_context((void *)page->private);
                page->private = 0;
                ClearPagePrivate(page);
-               ceph_put_snap_context(snapc);
                dout("unlocking %d %p\n", i, page);
                end_page_writeback(page);
 
@@ -618,7 +610,7 @@ static int ceph_writepages_start(struct address_space *mapping,
        int range_whole = 0;
        int should_loop = 1;
        pgoff_t max_pages = 0, max_pages_ever = 0;
-       struct ceph_snap_context *snapc = NULL, *last_snapc = NULL;
+       struct ceph_snap_context *snapc = NULL, *last_snapc = NULL, *pgsnapc;
        struct pagevec pvec;
        int done = 0;
        int rc = 0;
@@ -770,9 +762,10 @@ get_more_pages:
                        }
 
                        /* only if matching snap context */
-                       if (snapc != (void *)page->private) {
-                               dout("page snapc %p != oldest %p\n",
-                                    (void *)page->private, snapc);
+                       pgsnapc = (void *)page->private;
+                       if (pgsnapc->seq > snapc->seq) {
+                               dout("page snapc %p %lld > oldest %p %lld\n",
+                                    pgsnapc, pgsnapc->seq, snapc, snapc->seq);
                                unlock_page(page);
                                if (!locked_pages)
                                        continue; /* keep looking for snap */
@@ -914,7 +907,10 @@ static int context_is_writeable_or_written(struct inode *inode,
                                           struct ceph_snap_context *snapc)
 {
        struct ceph_snap_context *oldest = get_oldest_context(inode, NULL);
-       return !oldest || snapc->seq <= oldest->seq;
+       int ret = !oldest || snapc->seq <= oldest->seq;
+
+       ceph_put_snap_context(oldest);
+       return ret;
 }
 
 /*
@@ -936,8 +932,8 @@ static int ceph_update_writeable_page(struct file *file,
        int pos_in_page = pos & ~PAGE_CACHE_MASK;
        int end_in_page = pos_in_page + len;
        loff_t i_size;
-       struct ceph_snap_context *snapc;
        int r;
+       struct ceph_snap_context *snapc, *oldest;
 
 retry_locked:
        /* writepages currently holds page lock, but if we change that later, */
@@ -947,23 +943,24 @@ retry_locked:
        BUG_ON(!ci->i_snap_realm);
        down_read(&mdsc->snap_rwsem);
        BUG_ON(!ci->i_snap_realm->cached_context);
-       if (page->private &&
-           (void *)page->private != ci->i_snap_realm->cached_context) {
+       snapc = (void *)page->private;
+       if (snapc && snapc != ci->i_head_snapc) {
                /*
                 * this page is already dirty in another (older) snap
                 * context!  is it writeable now?
                 */
-               snapc = get_oldest_context(inode, NULL);
+               oldest = get_oldest_context(inode, NULL);
                up_read(&mdsc->snap_rwsem);
 
-               if (snapc != (void *)page->private) {
+               if (snapc->seq > oldest->seq) {
+                       ceph_put_snap_context(oldest);
                        dout(" page %p snapc %p not current or oldest\n",
-                            page, (void *)page->private);
+                            page, snapc);
                        /*
                         * queue for writeback, and wait for snapc to
                         * be writeable or written
                         */
-                       snapc = ceph_get_snap_context((void *)page->private);
+                       snapc = ceph_get_snap_context(snapc);
                        unlock_page(page);
                        ceph_queue_writeback(inode);
                        r = wait_event_interruptible(ci->i_cap_wq,
@@ -973,6 +970,7 @@ retry_locked:
                                return r;
                        return -EAGAIN;
                }
+               ceph_put_snap_context(oldest);
 
                /* yay, writeable, do it now (without dropping page lock) */
                dout(" page %p snapc %p not current, but oldest\n",
index 3710e07..aa2239f 100644 (file)
@@ -1205,6 +1205,12 @@ retry:
                if (capsnap->dirty_pages || capsnap->writing)
                        continue;
 
+               /*
+                * if cap writeback already occurred, we should have dropped
+                * the capsnap in ceph_put_wrbuffer_cap_refs.
+                */
+               BUG_ON(capsnap->dirty == 0);
+
                /* pick mds, take s_mutex */
                mds = __ceph_get_cap_mds(ci, &mseq);
                if (session && session->s_mds != mds) {
@@ -2118,8 +2124,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
                }
        spin_unlock(&inode->i_lock);
 
-       dout("put_cap_refs %p had %s %s\n", inode, ceph_cap_string(had),
-            last ? "last" : "");
+       dout("put_cap_refs %p had %s%s%s\n", inode, ceph_cap_string(had),
+            last ? " last" : "", put ? " put" : "");
 
        if (last && !flushsnaps)
                ceph_check_caps(ci, 0, NULL);
@@ -2143,7 +2149,8 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
 {
        struct inode *inode = &ci->vfs_inode;
        int last = 0;
-       int last_snap = 0;
+       int complete_capsnap = 0;
+       int drop_capsnap = 0;
        int found = 0;
        struct ceph_cap_snap *capsnap = NULL;
 
@@ -2166,19 +2173,32 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
                list_for_each_entry(capsnap, &ci->i_cap_snaps, ci_item) {
                        if (capsnap->context == snapc) {
                                found = 1;
-                               capsnap->dirty_pages -= nr;
-                               last_snap = !capsnap->dirty_pages;
                                break;
                        }
                }
                BUG_ON(!found);
+               capsnap->dirty_pages -= nr;
+               if (capsnap->dirty_pages == 0) {
+                       complete_capsnap = 1;
+                       if (capsnap->dirty == 0)
+                               /* cap writeback completed before we created
+                                * the cap_snap; no FLUSHSNAP is needed */
+                               drop_capsnap = 1;
+               }
                dout("put_wrbuffer_cap_refs on %p cap_snap %p "
-                    " snap %lld %d/%d -> %d/%d %s%s\n",
+                    " snap %lld %d/%d -> %d/%d %s%s%s\n",
                     inode, capsnap, capsnap->context->seq,
                     ci->i_wrbuffer_ref+nr, capsnap->dirty_pages + nr,
                     ci->i_wrbuffer_ref, capsnap->dirty_pages,
                     last ? " (wrbuffer last)" : "",
-                    last_snap ? " (capsnap last)" : "");
+                    complete_capsnap ? " (complete capsnap)" : "",
+                    drop_capsnap ? " (drop capsnap)" : "");
+               if (drop_capsnap) {
+                       ceph_put_snap_context(capsnap->context);
+                       list_del(&capsnap->ci_item);
+                       list_del(&capsnap->flushing_item);
+                       ceph_put_cap_snap(capsnap);
+               }
        }
 
        spin_unlock(&inode->i_lock);
@@ -2186,10 +2206,12 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
        if (last) {
                ceph_check_caps(ci, CHECK_CAPS_AUTHONLY, NULL);
                iput(inode);
-       } else if (last_snap) {
+       } else if (complete_capsnap) {
                ceph_flush_snaps(ci);
                wake_up(&ci->i_cap_wq);
        }
+       if (drop_capsnap)
+               iput(inode);
 }
 
 /*
@@ -2465,8 +2487,8 @@ static void handle_cap_flushsnap_ack(struct inode *inode, u64 flush_tid,
                                break;
                        }
                        WARN_ON(capsnap->dirty_pages || capsnap->writing);
-                       dout(" removing cap_snap %p follows %lld\n",
-                            capsnap, follows);
+                       dout(" removing %p cap_snap %p follows %lld\n",
+                            inode, capsnap, follows);
                        ceph_put_snap_context(capsnap->context);
                        list_del(&capsnap->ci_item);
                        list_del(&capsnap->flushing_item);
index 7261dc6..ea8ee2e 100644 (file)
@@ -171,11 +171,11 @@ more:
        spin_lock(&inode->i_lock);
        spin_lock(&dcache_lock);
 
+       last = dentry;
+
        if (err < 0)
                goto out_unlock;
 
-       last = dentry;
-
        p = p->prev;
        filp->f_pos++;
 
@@ -312,7 +312,7 @@ more:
                req->r_readdir_offset = fi->next_offset;
                req->r_args.readdir.frag = cpu_to_le32(frag);
                req->r_args.readdir.max_entries = cpu_to_le32(max_entries);
-               req->r_num_caps = max_entries;
+               req->r_num_caps = max_entries + 1;
                err = ceph_mdsc_do_request(mdsc, NULL, req);
                if (err < 0) {
                        ceph_mdsc_put_request(req);
@@ -489,6 +489,7 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req,
                struct inode *inode = ceph_get_snapdir(parent);
                dout("ENOENT on snapdir %p '%.*s', linking to snapdir %p\n",
                     dentry, dentry->d_name.len, dentry->d_name.name, inode);
+               BUG_ON(!d_unhashed(dentry));
                d_add(dentry, inode);
                err = 0;
        }
index aca82d5..26f883c 100644 (file)
@@ -886,6 +886,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
        struct inode *in = NULL;
        struct ceph_mds_reply_inode *ininfo;
        struct ceph_vino vino;
+       struct ceph_client *client = ceph_sb_to_client(sb);
        int i = 0;
        int err = 0;
 
@@ -949,7 +950,14 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                        return err;
        }
 
-       if (rinfo->head->is_dentry && !req->r_aborted) {
+       /*
+        * ignore null lease/binding on snapdir ENOENT, or else we
+        * will have trouble splicing in the virtual snapdir later
+        */
+       if (rinfo->head->is_dentry && !req->r_aborted &&
+           (rinfo->head->is_target || strncmp(req->r_dentry->d_name.name,
+                                              client->mount_args->snapdir_name,
+                                              req->r_dentry->d_name.len))) {
                /*
                 * lookup link rename   : null -> possibly existing inode
                 * mknod symlink mkdir  : null -> new inode
index 8f1715f..cdaaa13 100644 (file)
@@ -30,6 +30,10 @@ static char tag_msg = CEPH_MSGR_TAG_MSG;
 static char tag_ack = CEPH_MSGR_TAG_ACK;
 static char tag_keepalive = CEPH_MSGR_TAG_KEEPALIVE;
 
+#ifdef CONFIG_LOCKDEP
+static struct lock_class_key socket_class;
+#endif
+
 
 static void queue_con(struct ceph_connection *con);
 static void con_work(struct work_struct *);
@@ -228,6 +232,10 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con)
        con->sock = sock;
        sock->sk->sk_allocation = GFP_NOFS;
 
+#ifdef CONFIG_LOCKDEP
+       lockdep_set_class(&sock->sk->sk_lock, &socket_class);
+#endif
+
        set_sock_callbacks(sock, con);
 
        dout("connect %s\n", pr_addr(&con->peer_addr.in_addr));
@@ -333,6 +341,7 @@ static void reset_connection(struct ceph_connection *con)
                con->out_msg = NULL;
        }
        con->in_seq = 0;
+       con->in_seq_acked = 0;
 }
 
 /*
index 21c6623..2e2c15e 100644 (file)
@@ -314,71 +314,6 @@ bad:
        return ERR_PTR(err);
 }
 
-
-/*
- * osd map
- */
-void ceph_osdmap_destroy(struct ceph_osdmap *map)
-{
-       dout("osdmap_destroy %p\n", map);
-       if (map->crush)
-               crush_destroy(map->crush);
-       while (!RB_EMPTY_ROOT(&map->pg_temp)) {
-               struct ceph_pg_mapping *pg =
-                       rb_entry(rb_first(&map->pg_temp),
-                                struct ceph_pg_mapping, node);
-               rb_erase(&pg->node, &map->pg_temp);
-               kfree(pg);
-       }
-       while (!RB_EMPTY_ROOT(&map->pg_pools)) {
-               struct ceph_pg_pool_info *pi =
-                       rb_entry(rb_first(&map->pg_pools),
-                                struct ceph_pg_pool_info, node);
-               rb_erase(&pi->node, &map->pg_pools);
-               kfree(pi);
-       }
-       kfree(map->osd_state);
-       kfree(map->osd_weight);
-       kfree(map->osd_addr);
-       kfree(map);
-}
-
-/*
- * adjust max osd value.  reallocate arrays.
- */
-static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
-{
-       u8 *state;
-       struct ceph_entity_addr *addr;
-       u32 *weight;
-
-       state = kcalloc(max, sizeof(*state), GFP_NOFS);
-       addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
-       weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
-       if (state == NULL || addr == NULL || weight == NULL) {
-               kfree(state);
-               kfree(addr);
-               kfree(weight);
-               return -ENOMEM;
-       }
-
-       /* copy old? */
-       if (map->osd_state) {
-               memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
-               memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
-               memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
-               kfree(map->osd_state);
-               kfree(map->osd_addr);
-               kfree(map->osd_weight);
-       }
-
-       map->osd_state = state;
-       map->osd_weight = weight;
-       map->osd_addr = addr;
-       map->max_osd = max;
-       return 0;
-}
-
 /*
  * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
  * to a set of osds)
@@ -482,6 +417,13 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id)
        return NULL;
 }
 
+static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
+{
+       rb_erase(&pi->node, root);
+       kfree(pi->name);
+       kfree(pi);
+}
+
 void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
 {
        ceph_decode_copy(p, &pi->v, sizeof(pi->v));
@@ -490,6 +432,98 @@ void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
        *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2;
 }
 
+static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
+{
+       struct ceph_pg_pool_info *pi;
+       u32 num, len, pool;
+
+       ceph_decode_32_safe(p, end, num, bad);
+       dout(" %d pool names\n", num);
+       while (num--) {
+               ceph_decode_32_safe(p, end, pool, bad);
+               ceph_decode_32_safe(p, end, len, bad);
+               dout("  pool %d len %d\n", pool, len);
+               pi = __lookup_pg_pool(&map->pg_pools, pool);
+               if (pi) {
+                       kfree(pi->name);
+                       pi->name = kmalloc(len + 1, GFP_NOFS);
+                       if (pi->name) {
+                               memcpy(pi->name, *p, len);
+                               pi->name[len] = '\0';
+                               dout("  name is %s\n", pi->name);
+                       }
+               }
+               *p += len;
+       }
+       return 0;
+
+bad:
+       return -EINVAL;
+}
+
+/*
+ * osd map
+ */
+void ceph_osdmap_destroy(struct ceph_osdmap *map)
+{
+       dout("osdmap_destroy %p\n", map);
+       if (map->crush)
+               crush_destroy(map->crush);
+       while (!RB_EMPTY_ROOT(&map->pg_temp)) {
+               struct ceph_pg_mapping *pg =
+                       rb_entry(rb_first(&map->pg_temp),
+                                struct ceph_pg_mapping, node);
+               rb_erase(&pg->node, &map->pg_temp);
+               kfree(pg);
+       }
+       while (!RB_EMPTY_ROOT(&map->pg_pools)) {
+               struct ceph_pg_pool_info *pi =
+                       rb_entry(rb_first(&map->pg_pools),
+                                struct ceph_pg_pool_info, node);
+               __remove_pg_pool(&map->pg_pools, pi);
+       }
+       kfree(map->osd_state);
+       kfree(map->osd_weight);
+       kfree(map->osd_addr);
+       kfree(map);
+}
+
+/*
+ * adjust max osd value.  reallocate arrays.
+ */
+static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
+{
+       u8 *state;
+       struct ceph_entity_addr *addr;
+       u32 *weight;
+
+       state = kcalloc(max, sizeof(*state), GFP_NOFS);
+       addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
+       weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
+       if (state == NULL || addr == NULL || weight == NULL) {
+               kfree(state);
+               kfree(addr);
+               kfree(weight);
+               return -ENOMEM;
+       }
+
+       /* copy old? */
+       if (map->osd_state) {
+               memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
+               memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
+               memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
+               kfree(map->osd_state);
+               kfree(map->osd_addr);
+               kfree(map->osd_weight);
+       }
+
+       map->osd_state = state;
+       map->osd_weight = weight;
+       map->osd_addr = addr;
+       map->max_osd = max;
+       return 0;
+}
+
 /*
  * decode a full map.
  */
@@ -526,7 +560,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
        ceph_decode_32_safe(p, end, max, bad);
        while (max--) {
                ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
-               pi = kmalloc(sizeof(*pi), GFP_NOFS);
+               pi = kzalloc(sizeof(*pi), GFP_NOFS);
                if (!pi)
                        goto bad;
                pi->id = ceph_decode_32(p);
@@ -539,6 +573,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
                __decode_pool(p, pi);
                __insert_pg_pool(&map->pg_pools, pi);
        }
+
+       if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+               goto bad;
+
        ceph_decode_32_safe(p, end, map->pool_max, bad);
 
        ceph_decode_32_safe(p, end, map->flags, bad);
@@ -712,7 +750,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
                }
                pi = __lookup_pg_pool(&map->pg_pools, pool);
                if (!pi) {
-                       pi = kmalloc(sizeof(*pi), GFP_NOFS);
+                       pi = kzalloc(sizeof(*pi), GFP_NOFS);
                        if (!pi) {
                                err = -ENOMEM;
                                goto bad;
@@ -722,6 +760,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
                }
                __decode_pool(p, pi);
        }
+       if (version >= 5 && __decode_pool_names(p, end, map) < 0)
+               goto bad;
 
        /* old_pool */
        ceph_decode_32_safe(p, end, len, bad);
@@ -730,10 +770,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
 
                ceph_decode_32_safe(p, end, pool, bad);
                pi = __lookup_pg_pool(&map->pg_pools, pool);
-               if (pi) {
-                       rb_erase(&pi->node, &map->pg_pools);
-                       kfree(pi);
-               }
+               if (pi)
+                       __remove_pg_pool(&map->pg_pools, pi);
        }
 
        /* new_up */
index 1fb55af..8bc9f1e 100644 (file)
@@ -23,6 +23,7 @@ struct ceph_pg_pool_info {
        int id;
        struct ceph_pg_pool v;
        int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask;
+       char *name;
 };
 
 struct ceph_pg_mapping {
index 26ac8b8..a1fc1d0 100644 (file)
 /*
  * osdmap encoding versions
  */
-#define CEPH_OSDMAP_INC_VERSION 4
-#define CEPH_OSDMAP_VERSION     4
+#define CEPH_OSDMAP_INC_VERSION     5
+#define CEPH_OSDMAP_INC_VERSION_EXT 5
+#define CEPH_OSDMAP_VERSION         5
+#define CEPH_OSDMAP_VERSION_EXT     5
 
 /*
  * fs id
index e6f9bc5..2b88126 100644 (file)
@@ -431,8 +431,7 @@ static int dup_array(u64 **dst, __le64 *src, int num)
  * Caller must hold snap_rwsem for read (i.e., the realm topology won't
  * change).
  */
-void ceph_queue_cap_snap(struct ceph_inode_info *ci,
-                        struct ceph_snap_context *snapc)
+void ceph_queue_cap_snap(struct ceph_inode_info *ci)
 {
        struct inode *inode = &ci->vfs_inode;
        struct ceph_cap_snap *capsnap;
@@ -451,10 +450,11 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                   as no new writes are allowed to start when pending, so any
                   writes in progress now were started before the previous
                   cap_snap.  lucky us. */
-               dout("queue_cap_snap %p snapc %p seq %llu used %d"
-                    " already pending\n", inode, snapc, snapc->seq, used);
+               dout("queue_cap_snap %p already pending\n", inode);
                kfree(capsnap);
        } else if (ci->i_wrbuffer_ref_head || (used & CEPH_CAP_FILE_WR)) {
+               struct ceph_snap_context *snapc = ci->i_head_snapc;
+
                igrab(inode);
 
                atomic_set(&capsnap->nref, 1);
@@ -463,7 +463,6 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                INIT_LIST_HEAD(&capsnap->flushing_item);
 
                capsnap->follows = snapc->seq - 1;
-               capsnap->context = ceph_get_snap_context(snapc);
                capsnap->issued = __ceph_caps_issued(ci, NULL);
                capsnap->dirty = __ceph_caps_dirty(ci);
 
@@ -480,7 +479,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                   snapshot. */
                capsnap->dirty_pages = ci->i_wrbuffer_ref_head;
                ci->i_wrbuffer_ref_head = 0;
-               ceph_put_snap_context(ci->i_head_snapc);
+               capsnap->context = snapc;
                ci->i_head_snapc = NULL;
                list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps);
 
@@ -522,15 +521,17 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
        capsnap->ctime = inode->i_ctime;
        capsnap->time_warp_seq = ci->i_time_warp_seq;
        if (capsnap->dirty_pages) {
-               dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu "
+               dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu "
                     "still has %d dirty pages\n", inode, capsnap,
                     capsnap->context, capsnap->context->seq,
-                    capsnap->size, capsnap->dirty_pages);
+                    ceph_cap_string(capsnap->dirty), capsnap->size,
+                    capsnap->dirty_pages);
                return 0;
        }
-       dout("finish_cap_snap %p cap_snap %p snapc %p %llu s=%llu clean\n",
+       dout("finish_cap_snap %p cap_snap %p snapc %p %llu %s s=%llu\n",
             inode, capsnap, capsnap->context,
-            capsnap->context->seq, capsnap->size);
+            capsnap->context->seq, ceph_cap_string(capsnap->dirty),
+            capsnap->size);
 
        spin_lock(&mdsc->snap_flush_lock);
        list_add_tail(&ci->i_snap_flush_item, &mdsc->snap_flush_list);
@@ -602,7 +603,7 @@ more:
                                if (lastinode)
                                        iput(lastinode);
                                lastinode = inode;
-                               ceph_queue_cap_snap(ci, realm->cached_context);
+                               ceph_queue_cap_snap(ci);
                                spin_lock(&realm->inodes_with_caps_lock);
                        }
                        spin_unlock(&realm->inodes_with_caps_lock);
@@ -824,8 +825,7 @@ void ceph_handle_snap(struct ceph_mds_client *mdsc,
                        spin_unlock(&realm->inodes_with_caps_lock);
                        spin_unlock(&inode->i_lock);
 
-                       ceph_queue_cap_snap(ci,
-                                           ci->i_snap_realm->cached_context);
+                       ceph_queue_cap_snap(ci);
 
                        iput(inode);
                        continue;
index ca702c6..e30dfbb 100644 (file)
@@ -715,8 +715,7 @@ extern int ceph_update_snap_trace(struct ceph_mds_client *m,
 extern void ceph_handle_snap(struct ceph_mds_client *mdsc,
                             struct ceph_mds_session *session,
                             struct ceph_msg *msg);
-extern void ceph_queue_cap_snap(struct ceph_inode_info *ci,
-                               struct ceph_snap_context *snapc);
+extern void ceph_queue_cap_snap(struct ceph_inode_info *ci);
 extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
                                  struct ceph_cap_snap *capsnap);
 extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc);
index 5183bc2..ded66be 100644 (file)
@@ -808,6 +808,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
        .release = cifs_close,
        .fsync = cifs_fsync,
        .flush = cifs_flush,
+       .mmap = cifs_file_mmap,
        .splice_read = generic_file_splice_read,
 #ifdef CONFIG_CIFS_POSIX
        .unlocked_ioctl  = cifs_ioctl,
index 3f4fbd6..5d3f29f 100644 (file)
@@ -1431,6 +1431,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        __u32 bytes_sent;
        __u16 byte_count;
 
+       *nbytes = 0;
+
        /* cFYI(1, ("write at %lld %d bytes", offset, count));*/
        if (tcon->ses == NULL)
                return -ECONNABORTED;
@@ -1513,11 +1515,18 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
        cifs_stats_inc(&tcon->num_writes);
        if (rc) {
                cFYI(1, ("Send error in write = %d", rc));
-               *nbytes = 0;
        } else {
                *nbytes = le16_to_cpu(pSMBr->CountHigh);
                *nbytes = (*nbytes) << 16;
                *nbytes += le16_to_cpu(pSMBr->Count);
+
+               /*
+                * Mask off high 16 bits when bytes written as returned by the
+                * server is greater than bytes requested by the client. Some
+                * OS/2 servers are known to set incorrect CountHigh values.
+                */
+               if (*nbytes > count)
+                       *nbytes &= 0xFFFF;
        }
 
        cifs_buf_release(pSMB);
@@ -1606,6 +1615,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
                *nbytes = le16_to_cpu(pSMBr->CountHigh);
                *nbytes = (*nbytes) << 16;
                *nbytes += le16_to_cpu(pSMBr->Count);
+
+               /*
+                * Mask off high 16 bits when bytes written as returned by the
+                * server is greater than bytes requested by the client. OS/2
+                * servers are known to set incorrect CountHigh values.
+                */
+               if (*nbytes > count)
+                       *nbytes &= 0xFFFF;
        }
 
 /*     cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
@@ -1794,8 +1811,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                }
                parm_data = (struct cifs_posix_lock *)
                        ((char *)&pSMBr->hdr.Protocol + data_offset);
-               if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
+               if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
                        pLockData->fl_type = F_UNLCK;
+               else {
+                       if (parm_data->lock_type ==
+                                       __constant_cpu_to_le16(CIFS_RDLCK))
+                               pLockData->fl_type = F_RDLCK;
+                       else if (parm_data->lock_type ==
+                                       __constant_cpu_to_le16(CIFS_WRLCK))
+                               pLockData->fl_type = F_WRLCK;
+
+                       pLockData->fl_start = parm_data->start;
+                       pLockData->fl_end = parm_data->start +
+                                               parm_data->length - 1;
+                       pLockData->fl_pid = parm_data->pid;
+               }
        }
 
 plk_err_exit:
index 058b390..9b11a8f 100644 (file)
@@ -839,8 +839,32 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
 
                } else {
                        /* if rc == ERR_SHARING_VIOLATION ? */
-                       rc = 0; /* do not change lock type to unlock
-                                  since range in use */
+                       rc = 0;
+
+                       if (lockType & LOCKING_ANDX_SHARED_LOCK) {
+                               pfLock->fl_type = F_WRLCK;
+                       } else {
+                               rc = CIFSSMBLock(xid, tcon, netfid, length,
+                                       pfLock->fl_start, 0, 1,
+                                       lockType | LOCKING_ANDX_SHARED_LOCK,
+                                       0 /* wait flag */);
+                               if (rc == 0) {
+                                       rc = CIFSSMBLock(xid, tcon, netfid,
+                                               length, pfLock->fl_start, 1, 0,
+                                               lockType |
+                                               LOCKING_ANDX_SHARED_LOCK,
+                                               0 /* wait flag */);
+                                       pfLock->fl_type = F_RDLCK;
+                                       if (rc != 0)
+                                               cERROR(1, ("Error unlocking "
+                                               "previously locked range %d "
+                                               "during test of lock", rc));
+                                       rc = 0;
+                               } else {
+                                       pfLock->fl_type = F_WRLCK;
+                                       rc = 0;
+                               }
+                       }
                }
 
                FreeXid(xid);
index efb2b94..1cc0876 100644 (file)
@@ -382,8 +382,8 @@ out:
 static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
                                             struct ecryptfs_crypt_stat *crypt_stat)
 {
-       (*offset) = (crypt_stat->num_header_bytes_at_front
-                    + (crypt_stat->extent_size * extent_num));
+       (*offset) = ecryptfs_lower_header_size(crypt_stat)
+                   + (crypt_stat->extent_size * extent_num);
 }
 
 /**
@@ -835,13 +835,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
        set_extent_mask_and_shift(crypt_stat);
        crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
        if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-               crypt_stat->num_header_bytes_at_front = 0;
+               crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
        else {
                if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
-                       crypt_stat->num_header_bytes_at_front =
+                       crypt_stat->metadata_size =
                                ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
                else
-                       crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE;
+                       crypt_stat->metadata_size = PAGE_CACHE_SIZE;
        }
 }
 
@@ -1108,9 +1108,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written)
        (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
 }
 
-static void
-write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
-                    size_t *written)
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+                                    struct ecryptfs_crypt_stat *crypt_stat,
+                                    size_t *written)
 {
        u32 flags = 0;
        int i;
@@ -1238,8 +1238,7 @@ ecryptfs_write_header_metadata(char *virt,
 
        header_extent_size = (u32)crypt_stat->extent_size;
        num_header_extents_at_front =
-               (u16)(crypt_stat->num_header_bytes_at_front
-                     / crypt_stat->extent_size);
+               (u16)(crypt_stat->metadata_size / crypt_stat->extent_size);
        put_unaligned_be32(header_extent_size, virt);
        virt += 4;
        put_unaligned_be16(num_header_extents_at_front, virt);
@@ -1292,7 +1291,8 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
        offset = ECRYPTFS_FILE_SIZE_BYTES;
        write_ecryptfs_marker((page_virt + offset), &written);
        offset += written;
-       write_ecryptfs_flags((page_virt + offset), crypt_stat, &written);
+       ecryptfs_write_crypt_stat_flags((page_virt + offset), crypt_stat,
+                                       &written);
        offset += written;
        ecryptfs_write_header_metadata((page_virt + offset), crypt_stat,
                                       &written);
@@ -1382,7 +1382,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                rc = -EINVAL;
                goto out;
        }
-       virt_len = crypt_stat->num_header_bytes_at_front;
+       virt_len = crypt_stat->metadata_size;
        order = get_order(virt_len);
        /* Released in this function */
        virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
@@ -1428,16 +1428,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
        header_extent_size = get_unaligned_be32(virt);
        virt += sizeof(__be32);
        num_header_extents_at_front = get_unaligned_be16(virt);
-       crypt_stat->num_header_bytes_at_front =
-               (((size_t)num_header_extents_at_front
-                 * (size_t)header_extent_size));
+       crypt_stat->metadata_size = (((size_t)num_header_extents_at_front
+                                    * (size_t)header_extent_size));
        (*bytes_read) = (sizeof(__be32) + sizeof(__be16));
        if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
-           && (crypt_stat->num_header_bytes_at_front
+           && (crypt_stat->metadata_size
                < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
                rc = -EINVAL;
                printk(KERN_WARNING "Invalid header size: [%zd]\n",
-                      crypt_stat->num_header_bytes_at_front);
+                      crypt_stat->metadata_size);
        }
        return rc;
 }
@@ -1452,8 +1451,7 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
  */
 static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
 {
-       crypt_stat->num_header_bytes_at_front =
-               ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
+       crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
 }
 
 /**
@@ -1607,6 +1605,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
                                                ecryptfs_dentry,
                                                ECRYPTFS_VALIDATE_HEADER_SIZE);
        if (rc) {
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
                rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
                if (rc) {
                        printk(KERN_DEBUG "Valid eCryptfs headers not found in "
index 542f625..bc71154 100644 (file)
@@ -273,7 +273,7 @@ struct ecryptfs_crypt_stat {
        u32 flags;
        unsigned int file_version;
        size_t iv_bytes;
-       size_t num_header_bytes_at_front;
+       size_t metadata_size;
        size_t extent_size; /* Data extent size; default is 4096 */
        size_t key_size;
        size_t extent_shift;
@@ -464,6 +464,14 @@ struct ecryptfs_daemon {
 
 extern struct mutex ecryptfs_daemon_hash_mux;
 
+static inline size_t
+ecryptfs_lower_header_size(struct ecryptfs_crypt_stat *crypt_stat)
+{
+       if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
+               return 0;
+       return crypt_stat->metadata_size;
+}
+
 static inline struct ecryptfs_file_info *
 ecryptfs_file_to_private(struct file *file)
 {
@@ -651,6 +659,9 @@ int ecryptfs_decrypt_page(struct page *page);
 int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
 int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
+void ecryptfs_write_crypt_stat_flags(char *page_virt,
+                                    struct ecryptfs_crypt_stat *crypt_stat,
+                                    size_t *written);
 int ecryptfs_read_and_validate_header_region(char *data,
                                             struct inode *ecryptfs_inode);
 int ecryptfs_read_and_validate_xattr_region(char *page_virt,
index d3362fa..e2d4418 100644 (file)
@@ -324,6 +324,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
        rc = ecryptfs_read_and_validate_header_region(page_virt,
                                                      ecryptfs_dentry->d_inode);
        if (rc) {
+               memset(page_virt, 0, PAGE_CACHE_SIZE);
                rc = ecryptfs_read_and_validate_xattr_region(page_virt,
                                                             ecryptfs_dentry);
                if (rc) {
@@ -336,7 +337,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry,
                ecryptfs_dentry->d_sb)->mount_crypt_stat;
        if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
                if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-                       file_size = (crypt_stat->num_header_bytes_at_front
+                       file_size = (crypt_stat->metadata_size
                                     + i_size_read(lower_dentry->d_inode));
                else
                        file_size = i_size_read(lower_dentry->d_inode);
@@ -388,9 +389,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
-               printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-                      "lower_dentry = [%s]\n", __func__, rc,
-                      ecryptfs_dentry->d_name.name);
+               ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+                               "[%d] on lower_dentry = [%s]\n", __func__, rc,
+                               encrypted_and_encoded_name);
                goto out_d_drop;
        }
        if (lower_dentry->d_inode)
@@ -417,9 +418,9 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        mutex_unlock(&lower_dir_dentry->d_inode->i_mutex);
        if (IS_ERR(lower_dentry)) {
                rc = PTR_ERR(lower_dentry);
-               printk(KERN_ERR "%s: lookup_one_len() returned [%d] on "
-                      "lower_dentry = [%s]\n", __func__, rc,
-                      encrypted_and_encoded_name);
+               ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+                               "[%d] on lower_dentry = [%s]\n", __func__, rc,
+                               encrypted_and_encoded_name);
                goto out_d_drop;
        }
 lookup_and_interpose:
@@ -456,8 +457,8 @@ static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
        rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
        if (rc)
                goto out_lock;
-       fsstack_copy_attr_times(dir, lower_new_dentry->d_inode);
-       fsstack_copy_inode_size(dir, lower_new_dentry->d_inode);
+       fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
+       fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
        old_dentry->d_inode->i_nlink =
                ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
        i_size_write(new_dentry->d_inode, file_size_save);
@@ -648,38 +649,17 @@ out_lock:
        return rc;
 }
 
-static int
-ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
+                                  size_t *bufsiz)
 {
+       struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
        char *lower_buf;
-       size_t lower_bufsiz;
-       struct dentry *lower_dentry;
-       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
-       char *plaintext_name;
-       size_t plaintext_name_size;
+       size_t lower_bufsiz = PATH_MAX;
        mm_segment_t old_fs;
        int rc;
 
-       lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       if (!lower_dentry->d_inode->i_op->readlink) {
-               rc = -EINVAL;
-               goto out;
-       }
-       mount_crypt_stat = &ecryptfs_superblock_to_private(
-                                               dentry->d_sb)->mount_crypt_stat;
-       /*
-        * If the lower filename is encrypted, it will result in a significantly
-        * longer name.  If needed, truncate the name after decode and decrypt.
-        */
-       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
-               lower_bufsiz = PATH_MAX;
-       else
-               lower_bufsiz = bufsiz;
-       /* Released in this function */
        lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
-       if (lower_buf == NULL) {
-               printk(KERN_ERR "%s: Out of memory whilst attempting to "
-                      "kmalloc [%zd] bytes\n", __func__, lower_bufsiz);
+       if (!lower_buf) {
                rc = -ENOMEM;
                goto out;
        }
@@ -689,29 +669,31 @@ ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
                                                   (char __user *)lower_buf,
                                                   lower_bufsiz);
        set_fs(old_fs);
-       if (rc >= 0) {
-               rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name,
-                                                         &plaintext_name_size,
-                                                         dentry, lower_buf,
-                                                         rc);
-               if (rc) {
-                       printk(KERN_ERR "%s: Error attempting to decode and "
-                              "decrypt filename; rc = [%d]\n", __func__,
-                               rc);
-                       goto out_free_lower_buf;
-               }
-               /* Check for bufsiz <= 0 done in sys_readlinkat() */
-               rc = copy_to_user(buf, plaintext_name,
-                                 min((size_t) bufsiz, plaintext_name_size));
-               if (rc)
-                       rc = -EFAULT;
-               else
-                       rc = plaintext_name_size;
-               kfree(plaintext_name);
-               fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode);
-       }
-out_free_lower_buf:
+       if (rc < 0)
+               goto out;
+       lower_bufsiz = rc;
+       rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry,
+                                                 lower_buf, lower_bufsiz);
+out:
        kfree(lower_buf);
+       return rc;
+}
+
+static int
+ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
+{
+       char *kbuf;
+       size_t kbufsiz, copied;
+       int rc;
+
+       rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz);
+       if (rc)
+               goto out;
+       copied = min_t(size_t, bufsiz, kbufsiz);
+       rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied;
+       kfree(kbuf);
+       fsstack_copy_attr_atime(dentry->d_inode,
+                               ecryptfs_dentry_to_lower(dentry)->d_inode);
 out:
        return rc;
 }
@@ -769,7 +751,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
 {
        loff_t lower_size;
 
-       lower_size = crypt_stat->num_header_bytes_at_front;
+       lower_size = ecryptfs_lower_header_size(crypt_stat);
        if (upper_size != 0) {
                loff_t num_extents;
 
@@ -1016,6 +998,28 @@ out:
        return rc;
 }
 
+int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry,
+                         struct kstat *stat)
+{
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
+       int rc = 0;
+
+       mount_crypt_stat = &ecryptfs_superblock_to_private(
+                                               dentry->d_sb)->mount_crypt_stat;
+       generic_fillattr(dentry->d_inode, stat);
+       if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
+               char *target;
+               size_t targetsiz;
+
+               rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz);
+               if (!rc) {
+                       kfree(target);
+                       stat->size = targetsiz;
+               }
+       }
+       return rc;
+}
+
 int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
                     struct kstat *stat)
 {
@@ -1040,7 +1044,7 @@ ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->setxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1058,7 +1062,7 @@ ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
        int rc = 0;
 
        if (!lower_dentry->d_inode->i_op->getxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1085,7 +1089,7 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->listxattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1102,7 +1106,7 @@ static int ecryptfs_removexattr(struct dentry *dentry, const char *name)
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        if (!lower_dentry->d_inode->i_op->removexattr) {
-               rc = -ENOSYS;
+               rc = -EOPNOTSUPP;
                goto out;
        }
        mutex_lock(&lower_dentry->d_inode->i_mutex);
@@ -1133,6 +1137,7 @@ const struct inode_operations ecryptfs_symlink_iops = {
        .put_link = ecryptfs_put_link,
        .permission = ecryptfs_permission,
        .setattr = ecryptfs_setattr,
+       .getattr = ecryptfs_getattr_link,
        .setxattr = ecryptfs_setxattr,
        .getxattr = ecryptfs_getxattr,
        .listxattr = ecryptfs_listxattr,
index d491237..2ee9a3a 100644 (file)
@@ -83,6 +83,19 @@ out:
        return rc;
 }
 
+static void strip_xattr_flag(char *page_virt,
+                            struct ecryptfs_crypt_stat *crypt_stat)
+{
+       if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
+               size_t written;
+
+               crypt_stat->flags &= ~ECRYPTFS_METADATA_IN_XATTR;
+               ecryptfs_write_crypt_stat_flags(page_virt, crypt_stat,
+                                               &written);
+               crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
+       }
+}
+
 /**
  *   Header Extent:
  *     Octets 0-7:        Unencrypted file size (big-endian)
@@ -98,19 +111,6 @@ out:
  *                        (big-endian)
  *     Octet  26:         Begin RFC 2440 authentication token packet set
  */
-static void set_header_info(char *page_virt,
-                           struct ecryptfs_crypt_stat *crypt_stat)
-{
-       size_t written;
-       size_t save_num_header_bytes_at_front =
-               crypt_stat->num_header_bytes_at_front;
-
-       crypt_stat->num_header_bytes_at_front =
-               ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
-       ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written);
-       crypt_stat->num_header_bytes_at_front =
-               save_num_header_bytes_at_front;
-}
 
 /**
  * ecryptfs_copy_up_encrypted_with_header
@@ -136,8 +136,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                                           * num_extents_per_page)
                                          + extent_num_in_page);
                size_t num_header_extents_at_front =
-                       (crypt_stat->num_header_bytes_at_front
-                        / crypt_stat->extent_size);
+                       (crypt_stat->metadata_size / crypt_stat->extent_size);
 
                if (view_extent_num < num_header_extents_at_front) {
                        /* This is a header extent */
@@ -147,9 +146,14 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                        memset(page_virt, 0, PAGE_CACHE_SIZE);
                        /* TODO: Support more than one header extent */
                        if (view_extent_num == 0) {
+                               size_t written;
+
                                rc = ecryptfs_read_xattr_region(
                                        page_virt, page->mapping->host);
-                               set_header_info(page_virt, crypt_stat);
+                               strip_xattr_flag(page_virt + 16, crypt_stat);
+                               ecryptfs_write_header_metadata(page_virt + 20,
+                                                              crypt_stat,
+                                                              &written);
                        }
                        kunmap_atomic(page_virt, KM_USER0);
                        flush_dcache_page(page);
@@ -162,7 +166,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page,
                        /* This is an encrypted data extent */
                        loff_t lower_offset =
                                ((view_extent_num * crypt_stat->extent_size)
-                                - crypt_stat->num_header_bytes_at_front);
+                                - crypt_stat->metadata_size);
 
                        rc = ecryptfs_read_lower_page_segment(
                                page, (lower_offset >> PAGE_CACHE_SHIFT),
index fcef41c..278743c 100644 (file)
@@ -86,7 +86,6 @@ static void ecryptfs_destroy_inode(struct inode *inode)
                if (lower_dentry->d_inode) {
                        fput(inode_info->lower_file);
                        inode_info->lower_file = NULL;
-                       d_drop(lower_dentry);
                }
        }
        ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
index 4e2426e..565cf81 100644 (file)
@@ -32,6 +32,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .setattr        = ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
@@ -43,6 +44,7 @@ const struct inode_operations ext2_symlink_inode_operations = {
 const struct inode_operations ext2_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = ext2_follow_link,
+       .setattr        = ext2_setattr,
 #ifdef CONFIG_EXT2_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index ff7b4cc..7c48982 100644 (file)
@@ -34,6 +34,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
+       .setattr        = ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
@@ -45,6 +46,7 @@ const struct inode_operations ext3_symlink_inode_operations = {
 const struct inode_operations ext3_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = ext3_follow_link,
+       .setattr        = ext3_setattr,
 #ifdef CONFIG_EXT3_FS_XATTR
        .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
index 781a322..4b37f7c 100644 (file)
@@ -554,108 +554,85 @@ select_queue:
        return ret;
 }
 
-static void unpin_sb_for_writeback(struct super_block **psb)
+static void unpin_sb_for_writeback(struct super_block *sb)
 {
-       struct super_block *sb = *psb;
-
-       if (sb) {
-               up_read(&sb->s_umount);
-               put_super(sb);
-               *psb = NULL;
-       }
+       up_read(&sb->s_umount);
+       put_super(sb);
 }
 
+enum sb_pin_state {
+       SB_PINNED,
+       SB_NOT_PINNED,
+       SB_PIN_FAILED
+};
+
 /*
  * For WB_SYNC_NONE writeback, the caller does not have the sb pinned
  * before calling writeback. So make sure that we do pin it, so it doesn't
  * go away while we are writing inodes from it.
- *
- * Returns 0 if the super was successfully pinned (or pinning wasn't needed),
- * 1 if we failed.
  */
-static int pin_sb_for_writeback(struct writeback_control *wbc,
-                               struct inode *inode, struct super_block **psb)
+static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc,
+                                             struct super_block *sb)
 {
-       struct super_block *sb = inode->i_sb;
-
-       /*
-        * If this sb is already pinned, nothing more to do. If not and
-        * *psb is non-NULL, unpin the old one first
-        */
-       if (sb == *psb)
-               return 0;
-       else if (*psb)
-               unpin_sb_for_writeback(psb);
-
        /*
         * Caller must already hold the ref for this
         */
        if (wbc->sync_mode == WB_SYNC_ALL) {
                WARN_ON(!rwsem_is_locked(&sb->s_umount));
-               return 0;
+               return SB_NOT_PINNED;
        }
-
        spin_lock(&sb_lock);
        sb->s_count++;
        if (down_read_trylock(&sb->s_umount)) {
                if (sb->s_root) {
                        spin_unlock(&sb_lock);
-                       goto pinned;
+                       return SB_PINNED;
                }
                /*
                 * umounted, drop rwsem again and fall through to failure
                 */
                up_read(&sb->s_umount);
        }
-
        sb->s_count--;
        spin_unlock(&sb_lock);
-       return 1;
-pinned:
-       *psb = sb;
-       return 0;
+       return SB_PIN_FAILED;
 }
 
-static void writeback_inodes_wb(struct bdi_writeback *wb,
-                               struct writeback_control *wbc)
+/*
+ * Write a portion of b_io inodes which belong to @sb.
+ * If @wbc->sb != NULL, then find and write all such
+ * inodes. Otherwise write only ones which go sequentially
+ * in reverse order.
+ * Return 1, if the caller writeback routine should be
+ * interrupted. Otherwise return 0.
+ */
+static int writeback_sb_inodes(struct super_block *sb,
+                              struct bdi_writeback *wb,
+                              struct writeback_control *wbc)
 {
-       struct super_block *sb = wbc->sb, *pin_sb = NULL;
-       const unsigned long start = jiffies;    /* livelock avoidance */
-
-       spin_lock(&inode_lock);
-
-       if (!wbc->for_kupdate || list_empty(&wb->b_io))
-               queue_io(wb, wbc->older_than_this);
-
        while (!list_empty(&wb->b_io)) {
-               struct inode *inode = list_entry(wb->b_io.prev,
-                                               struct inode, i_list);
                long pages_skipped;
-
-               /*
-                * super block given and doesn't match, skip this inode
-                */
-               if (sb && sb != inode->i_sb) {
+               struct inode *inode = list_entry(wb->b_io.prev,
+                                                struct inode, i_list);
+               if (wbc->sb && sb != inode->i_sb) {
+                       /* super block given and doesn't
+                          match, skip this inode */
                        redirty_tail(inode);
                        continue;
                }
-
+               if (sb != inode->i_sb)
+                       /* finish with this superblock */
+                       return 0;
                if (inode->i_state & (I_NEW | I_WILL_FREE)) {
                        requeue_io(inode);
                        continue;
                }
-
                /*
                 * Was this inode dirtied after sync_sb_inodes was called?
                 * This keeps sync from extra jobs and livelock.
                 */
-               if (inode_dirtied_after(inode, start))
-                       break;
-
-               if (pin_sb_for_writeback(wbc, inode, &pin_sb)) {
-                       requeue_io(inode);
-                       continue;
-               }
+               if (inode_dirtied_after(inode, wbc->wb_start))
+                       return 1;
 
                BUG_ON(inode->i_state & (I_FREEING | I_CLEAR));
                __iget(inode);
@@ -674,14 +651,50 @@ static void writeback_inodes_wb(struct bdi_writeback *wb,
                spin_lock(&inode_lock);
                if (wbc->nr_to_write <= 0) {
                        wbc->more_io = 1;
-                       break;
+                       return 1;
                }
                if (!list_empty(&wb->b_more_io))
                        wbc->more_io = 1;
        }
+       /* b_io is empty */
+       return 1;
+}
+
+static void writeback_inodes_wb(struct bdi_writeback *wb,
+                               struct writeback_control *wbc)
+{
+       int ret = 0;
 
-       unpin_sb_for_writeback(&pin_sb);
+       wbc->wb_start = jiffies; /* livelock avoidance */
+       spin_lock(&inode_lock);
+       if (!wbc->for_kupdate || list_empty(&wb->b_io))
+               queue_io(wb, wbc->older_than_this);
+
+       while (!list_empty(&wb->b_io)) {
+               struct inode *inode = list_entry(wb->b_io.prev,
+                                                struct inode, i_list);
+               struct super_block *sb = inode->i_sb;
+               enum sb_pin_state state;
+
+               if (wbc->sb && sb != wbc->sb) {
+                       /* super block given and doesn't
+                          match, skip this inode */
+                       redirty_tail(inode);
+                       continue;
+               }
+               state = pin_sb_for_writeback(wbc, sb);
+
+               if (state == SB_PIN_FAILED) {
+                       requeue_io(inode);
+                       continue;
+               }
+               ret = writeback_sb_inodes(sb, wb, wbc);
 
+               if (state == SB_PINNED)
+                       unpin_sb_for_writeback(sb);
+               if (ret)
+                       break;
+       }
        spin_unlock(&inode_lock);
        /* Leave any unwritten inodes on b_io */
 }
index 9dd1262..ed9ba6f 100644 (file)
@@ -61,7 +61,7 @@ struct inode *jfs_iget(struct super_block *sb, unsigned long ino)
                        inode->i_op = &page_symlink_inode_operations;
                        inode->i_mapping->a_ops = &jfs_aops;
                } else {
-                       inode->i_op = &jfs_symlink_inode_operations;
+                       inode->i_op = &jfs_fast_symlink_inode_operations;
                        /*
                         * The inline data should be null-terminated, but
                         * don't let on-disk corruption crash the kernel
index 6c4dfcb..9e2f6a7 100644 (file)
@@ -196,7 +196,7 @@ int dbMount(struct inode *ipbmap)
        bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
        bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
        bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
-       bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth);
+       bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
        bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
        bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
        bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
@@ -288,7 +288,7 @@ int dbSync(struct inode *ipbmap)
        dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag);
        dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref);
        dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel);
-       dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth);
+       dbmp_le->dn_agheight = cpu_to_le32(bmp->db_agheight);
        dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth);
        dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart);
        dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size);
@@ -1441,7 +1441,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
         * tree index of this allocation group within the control page.
         */
        agperlev =
-           (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
+           (1 << (L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth;
        ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
 
        /* dmap control page trees fan-out by 4 and a single allocation
@@ -1460,7 +1460,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
                 * the subtree to find the leftmost leaf that describes this
                 * free space.
                 */
-               for (k = bmp->db_agheigth; k > 0; k--) {
+               for (k = bmp->db_agheight; k > 0; k--) {
                        for (n = 0, m = (ti << 2) + 1; n < 4; n++) {
                                if (l2nb <= dcp->stree[m + n]) {
                                        ti = m + n;
@@ -3607,7 +3607,7 @@ void dbFinalizeBmap(struct inode *ipbmap)
        }
 
        /*
-        * compute db_aglevel, db_agheigth, db_width, db_agstart:
+        * compute db_aglevel, db_agheight, db_width, db_agstart:
         * an ag is covered in aglevel dmapctl summary tree,
         * at agheight level height (from leaf) with agwidth number of nodes
         * each, which starts at agstart index node of the smmary tree node
@@ -3616,9 +3616,9 @@ void dbFinalizeBmap(struct inode *ipbmap)
        bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
        l2nl =
            bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL);
-       bmp->db_agheigth = l2nl >> 1;
-       bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1));
-       for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0;
+       bmp->db_agheight = l2nl >> 1;
+       bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheight << 1));
+       for (i = 5 - bmp->db_agheight, bmp->db_agstart = 0, n = 1; i > 0;
             i--) {
                bmp->db_agstart += n;
                n <<= 2;
index 1a6eb41..6dcb906 100644 (file)
@@ -210,7 +210,7 @@ struct dbmap_disk {
        __le32 dn_maxag;        /* 4: max active alloc group number     */
        __le32 dn_agpref;       /* 4: preferred alloc group (hint)      */
        __le32 dn_aglevel;      /* 4: dmapctl level holding the AG      */
-       __le32 dn_agheigth;     /* 4: height in dmapctl of the AG       */
+       __le32 dn_agheight;     /* 4: height in dmapctl of the AG       */
        __le32 dn_agwidth;      /* 4: width in dmapctl of the AG        */
        __le32 dn_agstart;      /* 4: start tree index at AG height     */
        __le32 dn_agl2size;     /* 4: l2 num of blks per alloc group    */
@@ -229,7 +229,7 @@ struct dbmap {
        int dn_maxag;           /* max active alloc group number        */
        int dn_agpref;          /* preferred alloc group (hint)         */
        int dn_aglevel;         /* dmapctl level holding the AG         */
-       int dn_agheigth;        /* height in dmapctl of the AG          */
+       int dn_agheight;        /* height in dmapctl of the AG          */
        int dn_agwidth;         /* width in dmapctl of the AG           */
        int dn_agstart;         /* start tree index at AG height        */
        int dn_agl2size;        /* l2 num of blks per alloc group       */
@@ -255,7 +255,7 @@ struct bmap {
 #define        db_agsize       db_bmap.dn_agsize
 #define        db_agl2size     db_bmap.dn_agl2size
 #define        db_agwidth      db_bmap.dn_agwidth
-#define        db_agheigth     db_bmap.dn_agheigth
+#define        db_agheight     db_bmap.dn_agheight
 #define        db_agstart      db_bmap.dn_agstart
 #define        db_numag        db_bmap.dn_numag
 #define        db_maxlevel     db_bmap.dn_maxlevel
index 79e2c79..9e6bda3 100644 (file)
@@ -48,5 +48,6 @@ extern const struct file_operations jfs_dir_operations;
 extern const struct inode_operations jfs_file_inode_operations;
 extern const struct file_operations jfs_file_operations;
 extern const struct inode_operations jfs_symlink_inode_operations;
+extern const struct inode_operations jfs_fast_symlink_inode_operations;
 extern const struct dentry_operations jfs_ci_dentry_operations;
 #endif                         /* _H_JFS_INODE */
index 4a3e9f3..a9cf8e8 100644 (file)
@@ -956,7 +956,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
         */
 
        if (ssize <= IDATASIZE) {
-               ip->i_op = &jfs_symlink_inode_operations;
+               ip->i_op = &jfs_fast_symlink_inode_operations;
 
                i_fastsymlink = JFS_IP(ip)->i_inline;
                memcpy(i_fastsymlink, name, ssize);
@@ -978,7 +978,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
        else {
                jfs_info("jfs_symlink: allocate extent ip:0x%p", ip);
 
-               ip->i_op = &page_symlink_inode_operations;
+               ip->i_op = &jfs_symlink_inode_operations;
                ip->i_mapping->a_ops = &jfs_aops;
 
                /*
index 7f24a0b..1aba003 100644 (file)
@@ -81,6 +81,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
        struct inode *iplist[1];
        struct jfs_superblock *j_sb, *j_sb2;
        uint old_agsize;
+       int agsizechanged = 0;
        struct buffer_head *bh, *bh2;
 
        /* If the volume hasn't grown, get out now */
@@ -333,6 +334,9 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
         */
        if ((rc = dbExtendFS(ipbmap, XAddress, nblocks)))
                goto error_out;
+
+       agsizechanged |= (bmp->db_agsize != old_agsize);
+
        /*
         * the map now has extended to cover additional nblocks:
         * dn_mapsize = oldMapsize + nblocks;
@@ -432,7 +436,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
         * will correctly identify the new ag);
         */
        /* if new AG size the same as old AG size, done! */
-       if (bmp->db_agsize != old_agsize) {
+       if (agsizechanged) {
                if ((rc = diExtendFS(ipimap, ipbmap)))
                        goto error_out;
 
index 4af1a05..205b946 100644 (file)
@@ -29,9 +29,21 @@ static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
        return NULL;
 }
 
-const struct inode_operations jfs_symlink_inode_operations = {
+const struct inode_operations jfs_fast_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .follow_link    = jfs_follow_link,
+       .setattr        = jfs_setattr,
+       .setxattr       = jfs_setxattr,
+       .getxattr       = jfs_getxattr,
+       .listxattr      = jfs_listxattr,
+       .removexattr    = jfs_removexattr,
+};
+
+const struct inode_operations jfs_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+       .setattr        = jfs_setattr,
        .setxattr       = jfs_setxattr,
        .getxattr       = jfs_getxattr,
        .listxattr      = jfs_listxattr,
index 84e36f5..76c242f 100644 (file)
@@ -459,6 +459,14 @@ static void __logfs_gc_pass(struct super_block *sb, int target)
        struct logfs_block *block;
        int round, progress, last_progress = 0;
 
+       /*
+        * Doing too many changes to the segfile at once would result
+        * in a large number of aliases.  Write the journal before
+        * things get out of hand.
+        */
+       if (super->s_shadow_tree.no_shadowed_segments >= MAX_OBJ_ALIASES)
+               logfs_write_anchor(sb);
+
        if (no_free_segments(sb) >= target &&
                        super->s_no_object_aliases < MAX_OBJ_ALIASES)
                return;
index 33bd260..fb0a613 100644 (file)
@@ -389,7 +389,10 @@ static void journal_get_erase_count(struct logfs_area *area)
 static int journal_erase_segment(struct logfs_area *area)
 {
        struct super_block *sb = area->a_sb;
-       struct logfs_segment_header sh;
+       union {
+               struct logfs_segment_header sh;
+               unsigned char c[ALIGN(sizeof(struct logfs_segment_header), 16)];
+       } u;
        u64 ofs;
        int err;
 
@@ -397,20 +400,21 @@ static int journal_erase_segment(struct logfs_area *area)
        if (err)
                return err;
 
-       sh.pad = 0;
-       sh.type = SEG_JOURNAL;
-       sh.level = 0;
-       sh.segno = cpu_to_be32(area->a_segno);
-       sh.ec = cpu_to_be32(area->a_erase_count);
-       sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
-       sh.crc = logfs_crc32(&sh, sizeof(sh), 4);
+       memset(&u, 0, sizeof(u));
+       u.sh.pad = 0;
+       u.sh.type = SEG_JOURNAL;
+       u.sh.level = 0;
+       u.sh.segno = cpu_to_be32(area->a_segno);
+       u.sh.ec = cpu_to_be32(area->a_erase_count);
+       u.sh.gec = cpu_to_be64(logfs_super(sb)->s_gec);
+       u.sh.crc = logfs_crc32(&u.sh, sizeof(u.sh), 4);
 
        /* This causes a bug in segment.c.  Not yet. */
        //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0);
 
        ofs = dev_ofs(sb, area->a_segno, 0);
-       area->a_used_bytes = ALIGN(sizeof(sh), 16);
-       logfs_buf_write(area, ofs, &sh, sizeof(sh));
+       area->a_used_bytes = sizeof(u);
+       logfs_buf_write(area, ofs, &u, sizeof(u));
        return 0;
 }
 
@@ -494,6 +498,8 @@ static void account_shadows(struct super_block *sb)
 
        btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow);
        btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow);
+       btree_grim_visitor32(&tree->segment_map, 0, NULL);
+       tree->no_shadowed_segments = 0;
 
        if (li->li_block) {
                /*
@@ -607,9 +613,9 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type,
        if (len == 0)
                return logfs_write_header(super, header, 0, type);
 
+       BUG_ON(len > sb->s_blocksize);
        compr_len = logfs_compress(buf, data, len, sb->s_blocksize);
        if (compr_len < 0 || type == JE_ANCHOR) {
-               BUG_ON(len > sb->s_blocksize);
                memcpy(data, buf, len);
                compr_len = len;
                compr = COMPR_NONE;
@@ -661,6 +667,7 @@ static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type,
        if (ofs < 0)
                return ofs;
        logfs_buf_write(area, ofs, super->s_compressed_je, len);
+       BUG_ON(super->s_no_je >= MAX_JOURNAL_ENTRIES);
        super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs);
        return 0;
 }
index b84b0ee..0a3df1a 100644 (file)
@@ -257,10 +257,14 @@ struct logfs_shadow {
  * struct shadow_tree
  * @new:                       shadows where old_ofs==0, indexed by new_ofs
  * @old:                       shadows where old_ofs!=0, indexed by old_ofs
+ * @segment_map:               bitfield of segments containing shadows
+ * @no_shadowed_segment:       number of segments containing shadows
  */
 struct shadow_tree {
        struct btree_head64 new;
        struct btree_head64 old;
+       struct btree_head32 segment_map;
+       int no_shadowed_segments;
 };
 
 struct object_alias_item {
@@ -305,13 +309,14 @@ typedef int write_alias_t(struct super_block *sb, u64 ino, u64 bix,
                level_t level, int child_no, __be64 val);
 struct logfs_block_ops {
        void    (*write_block)(struct logfs_block *block);
-       gc_level_t      (*block_level)(struct logfs_block *block);
        void    (*free_block)(struct super_block *sb, struct logfs_block*block);
        int     (*write_alias)(struct super_block *sb,
                        struct logfs_block *block,
                        write_alias_t *write_one_alias);
 };
 
+#define MAX_JOURNAL_ENTRIES 256
+
 struct logfs_super {
        struct mtd_info *s_mtd;                 /* underlying device */
        struct block_device *s_bdev;            /* underlying device */
@@ -378,7 +383,7 @@ struct logfs_super {
        u32      s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */
        u64      s_last_version;
        struct logfs_area *s_journal_area;      /* open journal segment */
-       __be64  s_je_array[64];
+       __be64  s_je_array[MAX_JOURNAL_ENTRIES];
        int     s_no_je;
 
        int      s_sum_index;                   /* for the 12 summaries */
@@ -722,4 +727,10 @@ static inline struct logfs_area *get_area(struct super_block *sb,
        return logfs_super(sb)->s_area[(__force u8)gc_level];
 }
 
+static inline void logfs_mempool_destroy(mempool_t *pool)
+{
+       if (pool)
+               mempool_destroy(pool);
+}
+
 #endif
index bff4025..3159db6 100644 (file)
@@ -430,25 +430,6 @@ static void inode_write_block(struct logfs_block *block)
        }
 }
 
-static gc_level_t inode_block_level(struct logfs_block *block)
-{
-       BUG_ON(block->inode->i_ino == LOGFS_INO_MASTER);
-       return GC_LEVEL(LOGFS_MAX_LEVELS);
-}
-
-static gc_level_t indirect_block_level(struct logfs_block *block)
-{
-       struct page *page;
-       struct inode *inode;
-       u64 bix;
-       level_t level;
-
-       page = block->page;
-       inode = page->mapping->host;
-       logfs_unpack_index(page->index, &bix, &level);
-       return expand_level(inode->i_ino, level);
-}
-
 /*
  * This silences a false, yet annoying gcc warning.  I hate it when my editor
  * jumps into bitops.h each time I recompile this file.
@@ -587,14 +568,12 @@ static void indirect_free_block(struct super_block *sb,
 
 static struct logfs_block_ops inode_block_ops = {
        .write_block = inode_write_block,
-       .block_level = inode_block_level,
        .free_block = inode_free_block,
        .write_alias = inode_write_alias,
 };
 
 struct logfs_block_ops indirect_block_ops = {
        .write_block = indirect_write_block,
-       .block_level = indirect_block_level,
        .free_block = indirect_free_block,
        .write_alias = indirect_write_alias,
 };
@@ -1241,6 +1220,18 @@ static void free_shadow(struct inode *inode, struct logfs_shadow *shadow)
        mempool_free(shadow, super->s_shadow_pool);
 }
 
+static void mark_segment(struct shadow_tree *tree, u32 segno)
+{
+       int err;
+
+       if (!btree_lookup32(&tree->segment_map, segno)) {
+               err = btree_insert32(&tree->segment_map, segno, (void *)1,
+                               GFP_NOFS);
+               BUG_ON(err);
+               tree->no_shadowed_segments++;
+       }
+}
+
 /**
  * fill_shadow_tree - Propagate shadow tree changes due to a write
  * @inode:     Inode owning the page
@@ -1288,6 +1279,8 @@ static void fill_shadow_tree(struct inode *inode, struct page *page,
 
                super->s_dirty_used_bytes += shadow->new_len;
                super->s_dirty_free_bytes += shadow->old_len;
+               mark_segment(tree, shadow->old_ofs >> super->s_segshift);
+               mark_segment(tree, shadow->new_ofs >> super->s_segshift);
        }
 }
 
@@ -1845,19 +1838,37 @@ static int __logfs_truncate(struct inode *inode, u64 size)
        return logfs_truncate_direct(inode, size);
 }
 
-int logfs_truncate(struct inode *inode, u64 size)
+/*
+ * Truncate, by changing the segment file, can consume a fair amount
+ * of resources.  So back off from time to time and do some GC.
+ * 8 or 2048 blocks should be well within safety limits even if
+ * every single block resided in a different segment.
+ */
+#define TRUNCATE_STEP  (8 * 1024 * 1024)
+int logfs_truncate(struct inode *inode, u64 target)
 {
        struct super_block *sb = inode->i_sb;
-       int err;
+       u64 size = i_size_read(inode);
+       int err = 0;
 
-       logfs_get_wblocks(sb, NULL, 1);
-       err = __logfs_truncate(inode, size);
-       if (!err)
-               err = __logfs_write_inode(inode, 0);
-       logfs_put_wblocks(sb, NULL, 1);
+       size = ALIGN(size, TRUNCATE_STEP);
+       while (size > target) {
+               if (size > TRUNCATE_STEP)
+                       size -= TRUNCATE_STEP;
+               else
+                       size = 0;
+               if (size < target)
+                       size = target;
+
+               logfs_get_wblocks(sb, NULL, 1);
+               err = __logfs_truncate(inode, target);
+               if (!err)
+                       err = __logfs_write_inode(inode, 0);
+               logfs_put_wblocks(sb, NULL, 1);
+       }
 
        if (!err)
-               err = vmtruncate(inode, size);
+               err = vmtruncate(inode, target);
 
        /* I don't trust error recovery yet. */
        WARN_ON(err);
@@ -2251,8 +2262,6 @@ void logfs_cleanup_rw(struct super_block *sb)
        struct logfs_super *super = logfs_super(sb);
 
        destroy_meta_inode(super->s_segfile_inode);
-       if (super->s_block_pool)
-               mempool_destroy(super->s_block_pool);
-       if (super->s_shadow_pool)
-               mempool_destroy(super->s_shadow_pool);
+       logfs_mempool_destroy(super->s_block_pool);
+       logfs_mempool_destroy(super->s_shadow_pool);
 }
index 801a3a1..f77ce2b 100644 (file)
@@ -183,14 +183,8 @@ static int btree_write_alias(struct super_block *sb, struct logfs_block *block,
        return 0;
 }
 
-static gc_level_t btree_block_level(struct logfs_block *block)
-{
-       return expand_level(block->ino, block->level);
-}
-
 static struct logfs_block_ops btree_block_ops = {
        .write_block    = btree_write_block,
-       .block_level    = btree_block_level,
        .free_block     = __free_block,
        .write_alias    = btree_write_alias,
 };
@@ -919,7 +913,7 @@ err:
        for (i--; i >= 0; i--)
                free_area(super->s_area[i]);
        free_area(super->s_journal_area);
-       mempool_destroy(super->s_alias_pool);
+       logfs_mempool_destroy(super->s_alias_pool);
        return -ENOMEM;
 }
 
index b60bfac..5866ee6 100644 (file)
@@ -12,6 +12,7 @@
 #include "logfs.h"
 #include <linux/bio.h>
 #include <linux/slab.h>
+#include <linux/blkdev.h>
 #include <linux/mtd/mtd.h>
 #include <linux/statfs.h>
 #include <linux/buffer_head.h>
@@ -137,6 +138,10 @@ static int logfs_sb_set(struct super_block *sb, void *_super)
        sb->s_fs_info = super;
        sb->s_mtd = super->s_mtd;
        sb->s_bdev = super->s_bdev;
+       if (sb->s_bdev)
+               sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info;
+       if (sb->s_mtd)
+               sb->s_bdi = sb->s_mtd->backing_dev_info;
        return 0;
 }
 
@@ -452,6 +457,8 @@ static int logfs_read_sb(struct super_block *sb, int read_only)
 
        btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool);
        btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool);
+       btree_init_mempool32(&super->s_shadow_tree.segment_map,
+                       super->s_btree_pool);
 
        ret = logfs_init_mapping(sb);
        if (ret)
@@ -516,8 +523,8 @@ static void logfs_kill_sb(struct super_block *sb)
        if (super->s_erase_page)
                __free_page(super->s_erase_page);
        super->s_devops->put_device(sb);
-       mempool_destroy(super->s_btree_pool);
-       mempool_destroy(super->s_alias_pool);
+       logfs_mempool_destroy(super->s_btree_pool);
+       logfs_mempool_destroy(super->s_alias_pool);
        kfree(super);
        log_super("LogFS: Finished unmounting\n");
 }
index 2a3d352..a8766c4 100644 (file)
@@ -1294,7 +1294,8 @@ static int nfs4_init_server(struct nfs_server *server,
 
        /* Initialise the client representation from the mount data */
        server->flags = data->flags;
-       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR;
+       server->caps |= NFS_CAP_ATOMIC_OPEN|NFS_CAP_CHANGE_ATTR|
+               NFS_CAP_POSIX_LOCK;
        server->options = data->options;
 
        /* Get a client record */
index c6f2750..be46f26 100644 (file)
@@ -1025,12 +1025,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                                res = NULL;
                                goto out;
                        /* This turned out not to be a regular file */
+                       case -EISDIR:
                        case -ENOTDIR:
                                goto no_open;
                        case -ELOOP:
                                if (!(nd->intent.open.flags & O_NOFOLLOW))
                                        goto no_open;
-                       /* case -EISDIR: */
                        /* case -EINVAL: */
                        default:
                                goto out;
index 737128f..50a56ed 100644 (file)
@@ -623,10 +623,10 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_c
        list_for_each_entry(pos, &nfsi->open_files, list) {
                if (cred != NULL && pos->cred != cred)
                        continue;
-               if ((pos->mode & mode) == mode) {
-                       ctx = get_nfs_open_context(pos);
-                       break;
-               }
+               if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode)
+                       continue;
+               ctx = get_nfs_open_context(pos);
+               break;
        }
        spin_unlock(&inode->i_lock);
        return ctx;
index fe0cd9e..6380670 100644 (file)
@@ -1523,6 +1523,8 @@ static int _nfs4_proc_open(struct nfs4_opendata *data)
                nfs_post_op_update_inode(dir, o_res->dir_attr);
        } else
                nfs_refresh_inode(dir, o_res->dir_attr);
+       if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
+               server->caps &= ~NFS_CAP_POSIX_LOCK;
        if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
                status = _nfs4_proc_open_confirm(data);
                if (status != 0)
@@ -1664,7 +1666,7 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
        status = PTR_ERR(state);
        if (IS_ERR(state))
                goto err_opendata_put;
-       if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0)
+       if (server->caps & NFS_CAP_POSIX_LOCK)
                set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
        nfs4_opendata_put(opendata);
        nfs4_put_state_owner(sp);
index 53ff70e..de38d63 100644 (file)
@@ -201,6 +201,7 @@ static int nfs_set_page_writeback(struct page *page)
                struct inode *inode = page->mapping->host;
                struct nfs_server *nfss = NFS_SERVER(inode);
 
+               page_cache_get(page);
                if (atomic_long_inc_return(&nfss->writeback) >
                                NFS_CONGESTION_ON_THRESH) {
                        set_bdi_congested(&nfss->backing_dev_info,
@@ -216,6 +217,7 @@ static void nfs_end_page_writeback(struct page *page)
        struct nfs_server *nfss = NFS_SERVER(inode);
 
        end_page_writeback(page);
+       page_cache_release(page);
        if (atomic_long_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH)
                clear_bdi_congested(&nfss->backing_dev_info, BLK_RW_ASYNC);
 }
@@ -421,6 +423,7 @@ static void
 nfs_mark_request_dirty(struct nfs_page *req)
 {
        __set_page_dirty_nobuffers(req->wb_page);
+       __mark_inode_dirty(req->wb_page->mapping->host, I_DIRTY_DATASYNC);
 }
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -660,9 +663,11 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page,
        req = nfs_setup_write_request(ctx, page, offset, count);
        if (IS_ERR(req))
                return PTR_ERR(req);
+       nfs_mark_request_dirty(req);
        /* Update file length */
        nfs_grow_file(page, offset, count);
        nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes);
+       nfs_mark_request_dirty(req);
        nfs_clear_page_tag_locked(req);
        return 0;
 }
@@ -739,8 +744,6 @@ int nfs_updatepage(struct file *file, struct page *page,
        status = nfs_writepage_setup(ctx, page, offset, count);
        if (status < 0)
                nfs_set_pageerror(page);
-       else
-               __set_page_dirty_nobuffers(page);
 
        dprintk("NFS:       nfs_updatepage returns %d (isize %lld)\n",
                        status, (long long)i_size_read(inode));
@@ -749,13 +752,12 @@ int nfs_updatepage(struct file *file, struct page *page,
 
 static void nfs_writepage_release(struct nfs_page *req)
 {
+       struct page *page = req->wb_page;
 
-       if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
-               nfs_end_page_writeback(req->wb_page);
+       if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req))
                nfs_inode_remove_request(req);
-       } else
-               nfs_end_page_writeback(req->wb_page);
        nfs_clear_page_tag_locked(req);
+       nfs_end_page_writeback(page);
 }
 
 static int flush_task_priority(int how)
@@ -779,7 +781,6 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                int how)
 {
        struct inode *inode = req->wb_context->path.dentry->d_inode;
-       int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
        int priority = flush_task_priority(how);
        struct rpc_task *task;
        struct rpc_message msg = {
@@ -794,9 +795,10 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                .callback_ops = call_ops,
                .callback_data = data,
                .workqueue = nfsiod_workqueue,
-               .flags = flags,
+               .flags = RPC_TASK_ASYNC,
                .priority = priority,
        };
+       int ret = 0;
 
        /* Set up the RPC argument and reply structs
         * NB: take care not to mess about with data->commit et al. */
@@ -835,10 +837,18 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
                (unsigned long long)data->args.offset);
 
        task = rpc_run_task(&task_setup_data);
-       if (IS_ERR(task))
-               return PTR_ERR(task);
+       if (IS_ERR(task)) {
+               ret = PTR_ERR(task);
+               goto out;
+       }
+       if (how & FLUSH_SYNC) {
+               ret = rpc_wait_for_completion_task(task);
+               if (ret == 0)
+                       ret = task->tk_status;
+       }
        rpc_put_task(task);
-       return 0;
+out:
+       return ret;
 }
 
 /* If a nfs_flush_* function fails, it should remove reqs from @head and
@@ -847,9 +857,11 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
  */
 static void nfs_redirty_request(struct nfs_page *req)
 {
+       struct page *page = req->wb_page;
+
        nfs_mark_request_dirty(req);
-       nfs_end_page_writeback(req->wb_page);
        nfs_clear_page_tag_locked(req);
+       nfs_end_page_writeback(page);
 }
 
 /*
@@ -1084,16 +1096,15 @@ static void nfs_writeback_release_full(void *calldata)
                if (nfs_write_need_commit(data)) {
                        memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
                        nfs_mark_request_commit(req);
-                       nfs_end_page_writeback(page);
                        dprintk(" marked for commit\n");
                        goto next;
                }
                dprintk(" OK\n");
 remove_request:
-               nfs_end_page_writeback(page);
                nfs_inode_remove_request(req);
        next:
                nfs_clear_page_tag_locked(req);
+               nfs_end_page_writeback(page);
        }
        nfs_writedata_release(calldata);
 }
@@ -1207,7 +1218,6 @@ static int nfs_commit_rpcsetup(struct list_head *head,
 {
        struct nfs_page *first = nfs_list_entry(head->next);
        struct inode *inode = first->wb_context->path.dentry->d_inode;
-       int flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
        int priority = flush_task_priority(how);
        struct rpc_task *task;
        struct rpc_message msg = {
@@ -1222,7 +1232,7 @@ static int nfs_commit_rpcsetup(struct list_head *head,
                .callback_ops = &nfs_commit_ops,
                .callback_data = data,
                .workqueue = nfsiod_workqueue,
-               .flags = flags,
+               .flags = RPC_TASK_ASYNC,
                .priority = priority,
        };
 
@@ -1252,6 +1262,8 @@ static int nfs_commit_rpcsetup(struct list_head *head,
        task = rpc_run_task(&task_setup_data);
        if (IS_ERR(task))
                return PTR_ERR(task);
+       if (how & FLUSH_SYNC)
+               rpc_wait_for_completion_task(task);
        rpc_put_task(task);
        return 0;
 }
index 8d6356a..7cfb87e 100644 (file)
@@ -426,7 +426,7 @@ void nilfs_palloc_abort_alloc_entry(struct inode *inode,
        bitmap = bitmap_kaddr + bh_offset(req->pr_bitmap_bh);
        if (!nilfs_clear_bit_atomic(nilfs_mdt_bgl_lock(inode, group),
                                    group_offset, bitmap))
-               printk(KERN_WARNING "%s: entry numer %llu already freed\n",
+               printk(KERN_WARNING "%s: entry number %llu already freed\n",
                       __func__, (unsigned long long)req->pr_entry_nr);
 
        nilfs_palloc_group_desc_add_entries(inode, group, desc, 1);
index 7cdd98b..76c38e3 100644 (file)
@@ -1879,7 +1879,7 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
                                   struct nilfs_btree_path *path,
                                   int level, struct buffer_head *bh)
 {
-       int maxlevel, ret;
+       int maxlevel = 0, ret;
        struct nilfs_btree_node *parent;
        struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
        __u64 ptr;
index c2ff1b3..f90a33d 100644 (file)
@@ -649,7 +649,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
 long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        struct inode *inode = filp->f_dentry->d_inode;
-       void __user *argp = (void __user *)arg;
+       void __user *argp = (void __user *)arg;
 
        switch (cmd) {
        case NILFS_IOCTL_CHANGE_CPMODE:
index dad7fb2..3e21b1e 100644 (file)
@@ -33,6 +33,14 @@ config PRINT_QUOTA_WARNING
          Note that this behavior is currently deprecated and may go away in
          future. Please use notification via netlink socket instead.
 
+config QUOTA_DEBUG
+       bool "Additional quota sanity checks"
+       depends on QUOTA
+       default n
+       help
+         If you say Y here, quota subsystem will perform some additional
+         sanity checks of quota internal structures. If unsure, say N.
+
 # Generic support for tree structured quota files. Selected when needed.
 config QUOTA_TREE
         tristate
index e0b870f..788b580 100644 (file)
@@ -80,8 +80,6 @@
 
 #include <asm/uaccess.h>
 
-#define __DQUOT_PARANOIA
-
 /*
  * There are three quota SMP locks. dq_list_lock protects all lists with quotas
  * and quota formats, dqstats structure containing statistics about the lists
@@ -695,7 +693,7 @@ void dqput(struct dquot *dquot)
 
        if (!dquot)
                return;
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        if (!atomic_read(&dquot->dq_count)) {
                printk("VFS: dqput: trying to free free dquot\n");
                printk("VFS: device %s, dquot of %s %d\n",
@@ -748,7 +746,7 @@ we_slept:
                goto we_slept;
        }
        atomic_dec(&dquot->dq_count);
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        /* sanity check */
        BUG_ON(!list_empty(&dquot->dq_free));
 #endif
@@ -845,7 +843,7 @@ we_slept:
                dquot = NULL;
                goto out;
        }
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
        BUG_ON(!dquot->dq_sb);  /* Has somebody invalidated entry under us? */
 #endif
 out:
@@ -874,14 +872,18 @@ static int dqinit_needed(struct inode *inode, int type)
 static void add_dquot_ref(struct super_block *sb, int type)
 {
        struct inode *inode, *old_inode = NULL;
+#ifdef CONFIG_QUOTA_DEBUG
        int reserved = 0;
+#endif
 
        spin_lock(&inode_lock);
        list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
                if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
                        continue;
+#ifdef CONFIG_QUOTA_DEBUG
                if (unlikely(inode_get_rsv_space(inode) > 0))
                        reserved = 1;
+#endif
                if (!atomic_read(&inode->i_writecount))
                        continue;
                if (!dqinit_needed(inode, type))
@@ -903,11 +905,13 @@ static void add_dquot_ref(struct super_block *sb, int type)
        spin_unlock(&inode_lock);
        iput(old_inode);
 
+#ifdef CONFIG_QUOTA_DEBUG
        if (reserved) {
                printk(KERN_WARNING "VFS (%s): Writes happened before quota"
                        " was turned on thus quota information is probably "
                        "inconsistent. Please run quotacheck(8).\n", sb->s_id);
        }
+#endif
 }
 
 /*
@@ -934,7 +938,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type,
        inode->i_dquot[type] = NULL;
        if (dquot) {
                if (dqput_blocks(dquot)) {
-#ifdef __DQUOT_PARANOIA
+#ifdef CONFIG_QUOTA_DEBUG
                        if (atomic_read(&dquot->dq_count) != 1)
                                printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count));
 #endif
@@ -2322,34 +2326,34 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
        if (di->dqb_valid & QIF_SPACE) {
                dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_BLIMITS) {
                dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
                dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_INODES) {
                dm->dqb_curinodes = di->dqb_curinodes;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_ILIMITS) {
                dm->dqb_isoftlimit = di->dqb_isoftlimit;
                dm->dqb_ihardlimit = di->dqb_ihardlimit;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_BTIME) {
                dm->dqb_btime = di->dqb_btime;
                check_blim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
        }
        if (di->dqb_valid & QIF_ITIME) {
                dm->dqb_itime = di->dqb_itime;
                check_ilim = 1;
-               __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
+               set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
        }
 
        if (check_blim) {
index 19626e2..9a9378b 100644 (file)
@@ -125,9 +125,8 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-       if (bloc->logicalBlockNum < 0 ||
-           (bloc->logicalBlockNum + count) >
-               partmap->s_partition_len) {
+       if (bloc->logicalBlockNum + count < count ||
+           (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
                udf_debug("%d < %d || %d + %d > %d\n",
                          bloc->logicalBlockNum, 0, bloc->logicalBlockNum,
                          count, partmap->s_partition_len);
@@ -393,9 +392,8 @@ static void udf_table_free_blocks(struct super_block *sb,
 
        mutex_lock(&sbi->s_alloc_mutex);
        partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-       if (bloc->logicalBlockNum < 0 ||
-           (bloc->logicalBlockNum + count) >
-               partmap->s_partition_len) {
+       if (bloc->logicalBlockNum + count < count ||
+           (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
                udf_debug("%d < %d || %d + %d > %d\n",
                          bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count,
                          partmap->s_partition_len);
index 1eb0677..4b6a46c 100644 (file)
@@ -218,7 +218,7 @@ const struct file_operations udf_file_operations = {
        .llseek                 = generic_file_llseek,
 };
 
-static int udf_setattr(struct dentry *dentry, struct iattr *iattr)
+int udf_setattr(struct dentry *dentry, struct iattr *iattr)
 {
        struct inode *inode = dentry->d_inode;
        int error;
index bb863fe..8a3fbd1 100644 (file)
@@ -1314,7 +1314,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                break;
        case ICBTAG_FILE_TYPE_SYMLINK:
                inode->i_data.a_ops = &udf_symlink_aops;
-               inode->i_op = &page_symlink_inode_operations;
+               inode->i_op = &udf_symlink_inode_operations;
                inode->i_mode = S_IFLNK | S_IRWXUGO;
                break;
        case ICBTAG_FILE_TYPE_MAIN:
index db423ab..7581602 100644 (file)
@@ -925,7 +925,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        iinfo = UDF_I(inode);
        inode->i_mode = S_IFLNK | S_IRWXUGO;
        inode->i_data.a_ops = &udf_symlink_aops;
-       inode->i_op = &page_symlink_inode_operations;
+       inode->i_op = &udf_symlink_inode_operations;
 
        if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
                struct kernel_lb_addr eloc;
@@ -1393,6 +1393,7 @@ const struct export_operations udf_export_ops = {
 const struct inode_operations udf_dir_inode_operations = {
        .lookup                         = udf_lookup,
        .create                         = udf_create,
+       .setattr                        = udf_setattr,
        .link                           = udf_link,
        .unlink                         = udf_unlink,
        .symlink                        = udf_symlink,
@@ -1401,3 +1402,9 @@ const struct inode_operations udf_dir_inode_operations = {
        .mknod                          = udf_mknod,
        .rename                         = udf_rename,
 };
+const struct inode_operations udf_symlink_inode_operations = {
+       .readlink       = generic_readlink,
+       .follow_link    = page_follow_link_light,
+       .put_link       = page_put_link,
+       .setattr        = udf_setattr,
+};
index 4223ac8..702a114 100644 (file)
@@ -76,6 +76,7 @@ extern const struct inode_operations udf_dir_inode_operations;
 extern const struct file_operations udf_dir_operations;
 extern const struct inode_operations udf_file_inode_operations;
 extern const struct file_operations udf_file_operations;
+extern const struct inode_operations udf_symlink_inode_operations;
 extern const struct address_space_operations udf_aops;
 extern const struct address_space_operations udf_adinicb_aops;
 extern const struct address_space_operations udf_symlink_aops;
@@ -131,7 +132,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *,
 /* file.c */
 extern int udf_ioctl(struct inode *, struct file *, unsigned int,
                     unsigned long);
-
+extern int udf_setattr(struct dentry *dentry, struct iattr *iattr);
 /* inode.c */
 extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *);
 extern int udf_sync_inode(struct inode *);
index 05cd853..fd96982 100644 (file)
@@ -820,10 +820,10 @@ xfs_reclaim_inode(
         * call into reclaim to find it in a clean state instead of waiting for
         * it now. We also don't return errors here - if the error is transient
         * then the next reclaim pass will flush the inode, and if the error
-        * is permanent then the next sync reclaim will relcaim the inode and
+        * is permanent then the next sync reclaim will reclaim the inode and
         * pass on the error.
         */
-       if (error && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+       if (error && error != EAGAIN && !XFS_FORCED_SHUTDOWN(ip->i_mount)) {
                xfs_fs_cmn_err(CE_WARN, ip->i_mount,
                        "inode 0x%llx background reclaim flush failed with %d",
                        (long long)ip->i_ino, error);
index e8fba92..2be0191 100644 (file)
@@ -745,9 +745,16 @@ xfs_log_move_tail(xfs_mount_t      *mp,
 
 /*
  * Determine if we have a transaction that has gone to disk
- * that needs to be covered. Log activity needs to be idle (no AIL and
- * nothing in the iclogs). And, we need to be in the right state indicating
- * something has gone out.
+ * that needs to be covered. To begin the transition to the idle state
+ * firstly the log needs to be idle (no AIL and nothing in the iclogs).
+ * If we are then in a state where covering is needed, the caller is informed
+ * that dummy transactions are required to move the log into the idle state.
+ *
+ * Because this is called as part of the sync process, we should also indicate
+ * that dummy transactions should be issued in anything but the covered or
+ * idle states. This ensures that the log tail is accurately reflected in
+ * the log at the end of the sync, hence if a crash occurrs avoids replay
+ * of transactions where the metadata is already on disk.
  */
 int
 xfs_log_need_covered(xfs_mount_t *mp)
@@ -759,17 +766,24 @@ xfs_log_need_covered(xfs_mount_t *mp)
                return 0;
 
        spin_lock(&log->l_icloglock);
-       if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
-               (log->l_covered_state == XLOG_STATE_COVER_NEED2))
-                       && !xfs_trans_ail_tail(log->l_ailp)
-                       && xlog_iclogs_empty(log)) {
-               if (log->l_covered_state == XLOG_STATE_COVER_NEED)
-                       log->l_covered_state = XLOG_STATE_COVER_DONE;
-               else {
-                       ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2);
-                       log->l_covered_state = XLOG_STATE_COVER_DONE2;
+       switch (log->l_covered_state) {
+       case XLOG_STATE_COVER_DONE:
+       case XLOG_STATE_COVER_DONE2:
+       case XLOG_STATE_COVER_IDLE:
+               break;
+       case XLOG_STATE_COVER_NEED:
+       case XLOG_STATE_COVER_NEED2:
+               if (!xfs_trans_ail_tail(log->l_ailp) &&
+                   xlog_iclogs_empty(log)) {
+                       if (log->l_covered_state == XLOG_STATE_COVER_NEED)
+                               log->l_covered_state = XLOG_STATE_COVER_DONE;
+                       else
+                               log->l_covered_state = XLOG_STATE_COVER_DONE2;
                }
+               /* FALLTHRU */
+       default:
                needed = 1;
+               break;
        }
        spin_unlock(&log->l_icloglock);
        return needed;
index 04a6ebc..2d428b0 100644 (file)
@@ -6,6 +6,7 @@
        {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
        {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+       {0x1002, 0x3155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \
index ebd22db..6690e8b 100644 (file)
@@ -158,7 +158,6 @@ enum rq_flag_bits {
 struct request {
        struct list_head queuelist;
        struct call_single_data csd;
-       int cpu;
 
        struct request_queue *q;
 
@@ -166,9 +165,11 @@ struct request {
        enum rq_cmd_type_bits cmd_type;
        unsigned long atomic_flags;
 
+       int cpu;
+
        /* the following two fields are internal, NEVER access directly */
-       sector_t __sector;              /* sector cursor */
        unsigned int __data_len;        /* total data len */
+       sector_t __sector;              /* sector cursor */
 
        struct bio *bio;
        struct bio *biotail;
@@ -201,20 +202,20 @@ struct request {
 
        unsigned short ioprio;
 
+       int ref_count;
+
        void *special;          /* opaque pointer available for LLD use */
        char *buffer;           /* kaddr of the current segment if available */
 
        int tag;
        int errors;
 
-       int ref_count;
-
        /*
         * when request is used as a packet command carrier
         */
-       unsigned short cmd_len;
        unsigned char __cmd[BLK_MAX_CDB];
        unsigned char *cmd;
+       unsigned short cmd_len;
 
        unsigned int extra_len; /* length of alignment and padding */
        unsigned int sense_len;
@@ -921,26 +922,7 @@ extern void blk_cleanup_queue(struct request_queue *);
 extern void blk_queue_make_request(struct request_queue *, make_request_fn *);
 extern void blk_queue_bounce_limit(struct request_queue *, u64);
 extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
-
-/* Temporary compatibility wrapper */
-static inline void blk_queue_max_sectors(struct request_queue *q, unsigned int max)
-{
-       blk_queue_max_hw_sectors(q, max);
-}
-
 extern void blk_queue_max_segments(struct request_queue *, unsigned short);
-
-static inline void blk_queue_max_phys_segments(struct request_queue *q, unsigned short max)
-{
-       blk_queue_max_segments(q, max);
-}
-
-static inline void blk_queue_max_hw_segments(struct request_queue *q, unsigned short max)
-{
-       blk_queue_max_segments(q, max);
-}
-
-
 extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
 extern void blk_queue_max_discard_sectors(struct request_queue *q,
                unsigned int max_discard_sectors);
@@ -1030,11 +1012,6 @@ static inline int sb_issue_discard(struct super_block *sb,
 
 extern int blk_verify_command(unsigned char *cmd, fmode_t has_write_perm);
 
-#define MAX_PHYS_SEGMENTS 128
-#define MAX_HW_SEGMENTS 128
-#define SAFE_MAX_SECTORS 255
-#define MAX_SEGMENT_SIZE       65536
-
 enum blk_default_limits {
        BLK_MAX_SEGMENTS        = 128,
        BLK_SAFE_MAX_SECTORS    = 255,
index 7896227..4341b1a 100644 (file)
@@ -56,7 +56,7 @@ extern const char *drbd_buildtag(void);
 #define REL_VERSION "8.3.7"
 #define API_VERSION 88
 #define PRO_VERSION_MIN 86
-#define PRO_VERSION_MAX 91
+#define PRO_VERSION_MAX 92
 
 
 enum drbd_io_error_p {
index a4d82f8..f7431a4 100644 (file)
@@ -12,7 +12,7 @@
 #endif
 
 NL_PACKET(primary, 1,
-       NL_BIT(         1,      T_MAY_IGNORE,   overwrite_peer)
+       NL_BIT(         1,      T_MAY_IGNORE,   primary_force)
 )
 
 NL_PACKET(secondary, 2, )
@@ -63,6 +63,7 @@ NL_PACKET(net_conf, 5,
        NL_BIT(         41,     T_MAY_IGNORE,   always_asbp)
        NL_BIT(         61,     T_MAY_IGNORE,   no_cork)
        NL_BIT(         62,     T_MANDATORY,    auto_sndbuf_size)
+       NL_BIT(         70,     T_MANDATORY,    dry_run)
 )
 
 NL_PACKET(disconnect, 6, )
index 40b1101..81f3b14 100644 (file)
@@ -1,21 +1,26 @@
 /*
  * Char device interface.
  *
- * Copyright (C) 2005-2006  Kristian Hoegsberg <krh@bitplanet.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Copyright (C) 2005-2007  Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  */
 
 #ifndef _LINUX_FIREWIRE_CDEV_H
@@ -438,7 +443,7 @@ struct fw_cdev_remove_descriptor {
  * @type:      %FW_CDEV_ISO_CONTEXT_TRANSMIT or %FW_CDEV_ISO_CONTEXT_RECEIVE
  * @header_size: Header size to strip for receive contexts
  * @channel:   Channel to bind to
- * @speed:     Speed to transmit at
+ * @speed:     Speed for transmit contexts
  * @closure:   To be returned in &fw_cdev_event_iso_interrupt
  * @handle:    Handle to context, written back by kernel
  *
@@ -451,6 +456,9 @@ struct fw_cdev_remove_descriptor {
  * If a context was successfully created, the kernel writes back a handle to the
  * context, which must be passed in for subsequent operations on that context.
  *
+ * For receive contexts, @header_size must be at least 4 and must be a multiple
+ * of 4.
+ *
  * Note that the effect of a @header_size > 4 depends on
  * &fw_cdev_get_info.version, as documented at &fw_cdev_event_iso_interrupt.
  */
@@ -481,10 +489,34 @@ struct fw_cdev_create_iso_context {
  *
  * &struct fw_cdev_iso_packet is used to describe isochronous packet queues.
  *
- * Use the FW_CDEV_ISO_ macros to fill in @control.  The sy and tag fields are
- * specified by IEEE 1394a and IEC 61883.
- *
- * FIXME - finish this documentation
+ * Use the FW_CDEV_ISO_ macros to fill in @control.
+ *
+ * For transmit packets, the header length must be a multiple of 4 and specifies
+ * the numbers of bytes in @header that will be prepended to the packet's
+ * payload; these bytes are copied into the kernel and will not be accessed
+ * after the ioctl has returned.  The sy and tag fields are copied to the iso
+ * packet header (these fields are specified by IEEE 1394a and IEC 61883-1).
+ * The skip flag specifies that no packet is to be sent in a frame; when using
+ * this, all other fields except the interrupt flag must be zero.
+ *
+ * For receive packets, the header length must be a multiple of the context's
+ * header size; if the header length is larger than the context's header size,
+ * multiple packets are queued for this entry.  The sy and tag fields are
+ * ignored.  If the sync flag is set, the context drops all packets until
+ * a packet with a matching sy field is received (the sync value to wait for is
+ * specified in the &fw_cdev_start_iso structure).  The payload length defines
+ * how many payload bytes can be received for one packet (in addition to payload
+ * quadlets that have been defined as headers and are stripped and returned in
+ * the &fw_cdev_event_iso_interrupt structure).  If more bytes are received, the
+ * additional bytes are dropped.  If less bytes are received, the remaining
+ * bytes in this part of the payload buffer will not be written to, not even by
+ * the next packet, i.e., packets received in consecutive frames will not
+ * necessarily be consecutive in memory.  If an entry has queued multiple
+ * packets, the payload length is divided equally among them.
+ *
+ * When a packet with the interrupt flag set has been completed, the
+ * &fw_cdev_event_iso_interrupt event will be sent.  An entry that has queued
+ * multiple receive packets is completed when its last packet is completed.
  */
 struct fw_cdev_iso_packet {
        __u32 control;
@@ -501,7 +533,7 @@ struct fw_cdev_iso_packet {
  * Queue a number of isochronous packets for reception or transmission.
  * This ioctl takes a pointer to an array of &fw_cdev_iso_packet structs,
  * which describe how to transmit from or receive into a contiguous region
- * of a mmap()'ed payload buffer.  As part of the packet descriptors,
+ * of a mmap()'ed payload buffer.  As part of transmit packet descriptors,
  * a series of headers can be supplied, which will be prepended to the
  * payload during DMA.
  *
@@ -620,8 +652,8 @@ struct fw_cdev_get_cycle_timer2 {
  * instead of allocated.
  * An %FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED event concludes this operation.
  *
- * To summarize, %FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE allocates iso resources
- * for the lifetime of the fd or handle.
+ * To summarize, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE allocates iso resources
+ * for the lifetime of the fd or @handle.
  * In contrast, %FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE allocates iso resources
  * for the duration of a bus generation.
  *
index b316770..9c63f06 100644 (file)
@@ -1,3 +1,28 @@
+/*
+ * IEEE 1394 constants.
+ *
+ * Copyright (C) 2005-2007  Kristian Hoegsberg <krh@bitplanet.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
 #ifndef _LINUX_FIREWIRE_CONSTANTS_H
 #define _LINUX_FIREWIRE_CONSTANTS_H
 
@@ -21,7 +46,7 @@
 #define EXTCODE_WRAP_ADD               0x6
 #define EXTCODE_VENDOR_DEPENDENT       0x7
 
-/* Juju specific tcodes */
+/* Linux firewire-core (Juju) specific tcodes */
 #define TCODE_LOCK_MASK_SWAP           (0x10 | EXTCODE_MASK_SWAP)
 #define TCODE_LOCK_COMPARE_SWAP                (0x10 | EXTCODE_COMPARE_SWAP)
 #define TCODE_LOCK_FETCH_ADD           (0x10 | EXTCODE_FETCH_ADD)
@@ -36,7 +61,7 @@
 #define RCODE_TYPE_ERROR               0x6
 #define RCODE_ADDRESS_ERROR            0x7
 
-/* Juju specific rcodes */
+/* Linux firewire-core (Juju) specific rcodes */
 #define RCODE_SEND_ERROR               0x10
 #define RCODE_CANCELLED                        0x11
 #define RCODE_BUSY                     0x12
index 56b5051..5f2f4c4 100644 (file)
@@ -109,7 +109,7 @@ struct hd_struct {
 };
 
 #define GENHD_FL_REMOVABLE                     1
-#define GENHD_FL_DRIVERFS                      2
+/* 2 is unused */
 #define GENHD_FL_MEDIA_CHANGE_NOTIFY           4
 #define GENHD_FL_CD                            8
 #define GENHD_FL_UP                            16
index 87018dc..9e7a12d 100644 (file)
@@ -782,7 +782,6 @@ extern int i2o_exec_lct_get(struct i2o_controller *);
 #define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
 #define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
 #define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
-#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))
 
 /**
  *     i2o_out_to_virt - Turn an I2O message to a virtual address
index 3bd018b..c964cd7 100644 (file)
@@ -44,6 +44,7 @@ struct matrix_keymap_data {
  * @active_low: gpio polarity
  * @wakeup: controls whether the device should be set up as wakeup
  *     source
+ * @no_autorepeat: disable key autorepeat
  *
  * This structure represents platform-specific data that use used by
  * matrix_keypad driver to perform proper initialization.
@@ -64,6 +65,7 @@ struct matrix_keypad_platform_data {
 
        bool            active_low;
        bool            wakeup;
+       bool            no_autorepeat;
 };
 
 /**
index a3fd0f9..169d077 100644 (file)
@@ -54,7 +54,7 @@ extern struct kmem_cache *kvm_vcpu_cache;
  */
 struct kvm_io_bus {
        int                   dev_count;
-#define NR_IOBUS_DEVS 6
+#define NR_IOBUS_DEVS 200
        struct kvm_io_device *devs[NR_IOBUS_DEVS];
 };
 
@@ -119,6 +119,11 @@ struct kvm_memory_slot {
        int user_alloc;
 };
 
+static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memslot)
+{
+       return ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+}
+
 struct kvm_kernel_irq_routing_entry {
        u32 gsi;
        u32 type;
diff --git a/include/linux/lcm.h b/include/linux/lcm.h
new file mode 100644 (file)
index 0000000..7bf01d7
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LCM_H
+#define _LCM_H
+
+#include <linux/compiler.h>
+
+unsigned long lcm(unsigned long a, unsigned long b) __attribute_const__;
+
+#endif /* _LCM_H */
index 717a5e5..e82957a 100644 (file)
@@ -176,6 +176,7 @@ struct nfs_server {
 #define NFS_CAP_ATIME          (1U << 11)
 #define NFS_CAP_CTIME          (1U << 12)
 #define NFS_CAP_MTIME          (1U << 13)
+#define NFS_CAP_POSIX_LOCK     (1U << 14)
 
 
 /* maximum number of slots to use */
index c5da749..55ca73c 100644 (file)
@@ -121,6 +121,13 @@ do {                                                                       \
  * (Note, rcu_assign_pointer and rcu_dereference are not needed to control
  * access to data items when inserting into or looking up from the radix tree)
  *
+ * Note that the value returned by radix_tree_tag_get() may not be relied upon
+ * if only the RCU read lock is held.  Functions to set/clear tags and to
+ * delete nodes running concurrently with it may affect its result such that
+ * two consecutive reads in the same locked section may return different
+ * values.  If reliability is required, modification functions must also be
+ * excluded from concurrency.
+ *
  * radix_tree_tagged is able to be called without locking or RCU.
  */
 
index 872a98e..07db2fe 100644 (file)
@@ -101,10 +101,7 @@ extern struct lockdep_map rcu_sched_lock_map;
 # define rcu_read_release_sched() \
                lock_release(&rcu_sched_lock_map, 1, _THIS_IP_)
 
-static inline int debug_lockdep_rcu_enabled(void)
-{
-       return likely(rcu_scheduler_active && debug_locks);
-}
+extern int debug_lockdep_rcu_enabled(void);
 
 /**
  * rcu_read_lock_held - might we be in RCU read-side critical section?
@@ -195,12 +192,30 @@ static inline int rcu_read_lock_sched_held(void)
 
 /**
  * rcu_dereference_check - rcu_dereference with debug checking
+ * @p: The pointer to read, prior to dereferencing
+ * @c: The conditions under which the dereference will take place
+ *
+ * Do an rcu_dereference(), but check that the conditions under which the
+ * dereference will take place are correct.  Typically the conditions indicate
+ * the various locking conditions that should be held at that point.  The check
+ * should return true if the conditions are satisfied.
+ *
+ * For example:
+ *
+ *     bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ *                                           lockdep_is_held(&foo->lock));
  *
- * Do an rcu_dereference(), but check that the context is correct.
- * For example, rcu_dereference_check(gp, rcu_read_lock_held()) to
- * ensure that the rcu_dereference_check() executes within an RCU
- * read-side critical section.  It is also possible to check for
- * locks being held, for example, by using lockdep_is_held().
+ * could be used to indicate to lockdep that foo->bar may only be dereferenced
+ * if either the RCU read lock is held, or that the lock required to replace
+ * the bar struct at foo->bar is held.
+ *
+ * Note that the list of conditions may also include indications of when a lock
+ * need not be held, for example during initialisation or destruction of the
+ * target struct:
+ *
+ *     bar = rcu_dereference_check(foo->bar, rcu_read_lock_held() ||
+ *                                           lockdep_is_held(&foo->lock) ||
+ *                                           atomic_read(&foo->usage) == 0);
  */
 #define rcu_dereference_check(p, c) \
        ({ \
@@ -209,13 +224,45 @@ static inline int rcu_read_lock_sched_held(void)
                rcu_dereference_raw(p); \
        })
 
+/**
+ * rcu_dereference_protected - fetch RCU pointer when updates prevented
+ *
+ * Return the value of the specified RCU-protected pointer, but omit
+ * both the smp_read_barrier_depends() and the ACCESS_ONCE().  This
+ * is useful in cases where update-side locks prevent the value of the
+ * pointer from changing.  Please note that this primitive does -not-
+ * prevent the compiler from repeating this reference or combining it
+ * with other references, so it should not be used without protection
+ * of appropriate locks.
+ */
+#define rcu_dereference_protected(p, c) \
+       ({ \
+               if (debug_lockdep_rcu_enabled() && !(c)) \
+                       lockdep_rcu_dereference(__FILE__, __LINE__); \
+               (p); \
+       })
+
 #else /* #ifdef CONFIG_PROVE_RCU */
 
 #define rcu_dereference_check(p, c)    rcu_dereference_raw(p)
+#define rcu_dereference_protected(p, c) (p)
 
 #endif /* #else #ifdef CONFIG_PROVE_RCU */
 
 /**
+ * rcu_access_pointer - fetch RCU pointer with no dereferencing
+ *
+ * Return the value of the specified RCU-protected pointer, but omit the
+ * smp_read_barrier_depends() and keep the ACCESS_ONCE().  This is useful
+ * when the value of this pointer is accessed, but the pointer is not
+ * dereferenced, for example, when testing an RCU-protected pointer against
+ * NULL.  This may also be used in cases where update-side locks prevent
+ * the value of the pointer from changing, but rcu_dereference_protected()
+ * is a lighter-weight primitive for this use case.
+ */
+#define rcu_access_pointer(p)  ACCESS_ONCE(p)
+
+/**
  * rcu_read_lock - mark the beginning of an RCU read-side critical section.
  *
  * When synchronize_rcu() is invoked on one CPU while other CPUs
index 28c9fd0..ebd7472 100644 (file)
@@ -183,9 +183,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev,
 {
        /* Nothing except the stubbed out regulator API should be
         * looking at the value except to check if it is an error
-        * value so the actual return value doesn't matter.
+        * value. Drivers are free to handle NULL specifically by
+        * skipping all regulator API calls, but they don't have to.
+        * Drivers which don't, should make sure they properly handle
+        * corner cases of the API, such as regulator_get_voltage()
+        * returning 0.
         */
-       return (struct regulator *)id;
+       return NULL;
 }
 static inline void regulator_put(struct regulator *regulator)
 {
index 4884462..49d1247 100644 (file)
@@ -106,6 +106,7 @@ int kmem_cache_shrink(struct kmem_cache *);
 void kmem_cache_free(struct kmem_cache *, void *);
 unsigned int kmem_cache_size(struct kmem_cache *);
 const char *kmem_cache_name(struct kmem_cache *);
+int kern_ptr_validate(const void *ptr, unsigned long size);
 int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
 
 /*
index 76e8903..36520de 100644 (file)
@@ -34,6 +34,9 @@ struct writeback_control {
        enum writeback_sync_modes sync_mode;
        unsigned long *older_than_this; /* If !NULL, only write back inodes
                                           older than this */
+       unsigned long wb_start;         /* Time writeback_inodes_wb was
+                                          called. This is needed to avoid
+                                          extra jobs and livelock */
        long nr_to_write;               /* Write this many pages, and decrement
                                           this for each page written */
        long pages_skipped;             /* Pages which were not written */
index 15ef962..468551e 100644 (file)
@@ -183,6 +183,10 @@ extern int  sysctl_x25_clear_request_timeout;
 extern int  sysctl_x25_ack_holdback_timeout;
 extern int  sysctl_x25_forward;
 
+extern int x25_parse_address_block(struct sk_buff *skb,
+               struct x25_address *called_addr,
+               struct x25_address *calling_addr);
+
 extern int  x25_addr_ntoa(unsigned char *, struct x25_address *,
                          struct x25_address *);
 extern int  x25_addr_aton(unsigned char *, struct x25_address *,
index 5fb7273..d870a91 100644 (file)
@@ -40,6 +40,16 @@ DECLARE_EVENT_CLASS(block_rq_with_error,
                  __entry->nr_sector, __entry->errors)
 );
 
+/**
+ * block_rq_abort - abort block operation request
+ * @q: queue containing the block operation request
+ * @rq: block IO operation request
+ *
+ * Called immediately after pending block IO operation request @rq in
+ * queue @q is aborted. The fields in the operation request @rq
+ * can be examined to determine which device and sectors the pending
+ * operation would access.
+ */
 DEFINE_EVENT(block_rq_with_error, block_rq_abort,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -47,6 +57,15 @@ DEFINE_EVENT(block_rq_with_error, block_rq_abort,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_rq_requeue - place block IO request back on a queue
+ * @q: queue holding operation
+ * @rq: block IO operation request
+ *
+ * The block operation request @rq is being placed back into queue
+ * @q.  For some reason the request was not completed and needs to be
+ * put back in the queue.
+ */
 DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -54,6 +73,17 @@ DEFINE_EVENT(block_rq_with_error, block_rq_requeue,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_rq_complete - block IO operation completed by device driver
+ * @q: queue containing the block operation request
+ * @rq: block operations request
+ *
+ * The block_rq_complete tracepoint event indicates that some portion
+ * of operation request has been completed by the device driver.  If
+ * the @rq->bio is %NULL, then there is absolutely no additional work to
+ * do for the request. If @rq->bio is non-NULL then there is
+ * additional work required to complete the request.
+ */
 DEFINE_EVENT(block_rq_with_error, block_rq_complete,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -95,6 +125,16 @@ DECLARE_EVENT_CLASS(block_rq,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_rq_insert - insert block operation request into queue
+ * @q: target queue
+ * @rq: block IO operation request
+ *
+ * Called immediately before block operation request @rq is inserted
+ * into queue @q.  The fields in the operation request @rq struct can
+ * be examined to determine which device and sectors the pending
+ * operation would access.
+ */
 DEFINE_EVENT(block_rq, block_rq_insert,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -102,6 +142,14 @@ DEFINE_EVENT(block_rq, block_rq_insert,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_rq_issue - issue pending block IO request operation to device driver
+ * @q: queue holding operation
+ * @rq: block IO operation operation request
+ *
+ * Called when block operation request @rq from queue @q is sent to a
+ * device driver for processing.
+ */
 DEFINE_EVENT(block_rq, block_rq_issue,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
@@ -109,6 +157,17 @@ DEFINE_EVENT(block_rq, block_rq_issue,
        TP_ARGS(q, rq)
 );
 
+/**
+ * block_bio_bounce - used bounce buffer when processing block operation
+ * @q: queue holding the block operation
+ * @bio: block operation
+ *
+ * A bounce buffer was used to handle the block operation @bio in @q.
+ * This occurs when hardware limitations prevent a direct transfer of
+ * data between the @bio data memory area and the IO device.  Use of a
+ * bounce buffer requires extra copying of data and decreases
+ * performance.
+ */
 TRACE_EVENT(block_bio_bounce,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -138,6 +197,14 @@ TRACE_EVENT(block_bio_bounce,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_bio_complete - completed all work on the block operation
+ * @q: queue holding the block operation
+ * @bio: block operation completed
+ *
+ * This tracepoint indicates there is no further work to do on this
+ * block IO operation @bio.
+ */
 TRACE_EVENT(block_bio_complete,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -193,6 +260,14 @@ DECLARE_EVENT_CLASS(block_bio,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_bio_backmerge - merging block operation to the end of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block request @bio to the end of an existing block request
+ * in queue @q.
+ */
 DEFINE_EVENT(block_bio, block_bio_backmerge,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -200,6 +275,14 @@ DEFINE_EVENT(block_bio, block_bio_backmerge,
        TP_ARGS(q, bio)
 );
 
+/**
+ * block_bio_frontmerge - merging block operation to the beginning of an existing operation
+ * @q: queue holding operation
+ * @bio: new block operation to merge
+ *
+ * Merging block IO operation @bio to the beginning of an existing block
+ * operation in queue @q.
+ */
 DEFINE_EVENT(block_bio, block_bio_frontmerge,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -207,6 +290,13 @@ DEFINE_EVENT(block_bio, block_bio_frontmerge,
        TP_ARGS(q, bio)
 );
 
+/**
+ * block_bio_queue - putting new block IO operation in queue
+ * @q: queue holding operation
+ * @bio: new block operation
+ *
+ * About to place the block IO operation @bio into queue @q.
+ */
 DEFINE_EVENT(block_bio, block_bio_queue,
 
        TP_PROTO(struct request_queue *q, struct bio *bio),
@@ -243,6 +333,15 @@ DECLARE_EVENT_CLASS(block_get_rq,
                  __entry->nr_sector, __entry->comm)
 );
 
+/**
+ * block_getrq - get a free request entry in queue for block IO operations
+ * @q: queue for operations
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * A request struct for queue @q has been allocated to handle the
+ * block IO operation @bio.
+ */
 DEFINE_EVENT(block_get_rq, block_getrq,
 
        TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
@@ -250,6 +349,17 @@ DEFINE_EVENT(block_get_rq, block_getrq,
        TP_ARGS(q, bio, rw)
 );
 
+/**
+ * block_sleeprq - waiting to get a free request entry in queue for block IO operation
+ * @q: queue for operation
+ * @bio: pending block IO operation
+ * @rw: low bit indicates a read (%0) or a write (%1)
+ *
+ * In the case where a request struct cannot be provided for queue @q
+ * the process needs to wait for an request struct to become
+ * available.  This tracepoint event is generated each time the
+ * process goes to sleep waiting for request struct become available.
+ */
 DEFINE_EVENT(block_get_rq, block_sleeprq,
 
        TP_PROTO(struct request_queue *q, struct bio *bio, int rw),
@@ -257,6 +367,14 @@ DEFINE_EVENT(block_get_rq, block_sleeprq,
        TP_ARGS(q, bio, rw)
 );
 
+/**
+ * block_plug - keep operations requests in request queue
+ * @q: request queue to plug
+ *
+ * Plug the request queue @q.  Do not allow block operation requests
+ * to be sent to the device driver. Instead, accumulate requests in
+ * the queue to improve throughput performance of the block device.
+ */
 TRACE_EVENT(block_plug,
 
        TP_PROTO(struct request_queue *q),
@@ -293,6 +411,13 @@ DECLARE_EVENT_CLASS(block_unplug,
        TP_printk("[%s] %d", __entry->comm, __entry->nr_rq)
 );
 
+/**
+ * block_unplug_timer - timed release of operations requests in queue to device driver
+ * @q: request queue to unplug
+ *
+ * Unplug the request queue @q because a timer expired and allow block
+ * operation requests to be sent to the device driver.
+ */
 DEFINE_EVENT(block_unplug, block_unplug_timer,
 
        TP_PROTO(struct request_queue *q),
@@ -300,6 +425,13 @@ DEFINE_EVENT(block_unplug, block_unplug_timer,
        TP_ARGS(q)
 );
 
+/**
+ * block_unplug_io - release of operations requests in request queue
+ * @q: request queue to unplug
+ *
+ * Unplug request queue @q because device driver is scheduled to work
+ * on elements in the request queue.
+ */
 DEFINE_EVENT(block_unplug, block_unplug_io,
 
        TP_PROTO(struct request_queue *q),
@@ -307,6 +439,17 @@ DEFINE_EVENT(block_unplug, block_unplug_io,
        TP_ARGS(q)
 );
 
+/**
+ * block_split - split a single bio struct into two bio structs
+ * @q: queue containing the bio
+ * @bio: block operation being split
+ * @new_sector: The starting sector for the new bio
+ *
+ * The bio request @bio in request queue @q needs to be split into two
+ * bio requests. The newly created @bio request starts at
+ * @new_sector. This split may be required due to hardware limitation
+ * such as operation crossing device boundaries in a RAID system.
+ */
 TRACE_EVENT(block_split,
 
        TP_PROTO(struct request_queue *q, struct bio *bio,
@@ -337,6 +480,16 @@ TRACE_EVENT(block_split,
                  __entry->comm)
 );
 
+/**
+ * block_remap - map request for a partition to the raw device
+ * @q: queue holding the operation
+ * @bio: revised operation
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * An operation for a partition on a block device has been mapped to the
+ * raw block device.
+ */
 TRACE_EVENT(block_remap,
 
        TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev,
@@ -370,6 +523,17 @@ TRACE_EVENT(block_remap,
                  (unsigned long long)__entry->old_sector)
 );
 
+/**
+ * block_rq_remap - map request for a block operation request
+ * @q: queue holding the operation
+ * @rq: block IO operation request
+ * @dev: device for the operation
+ * @from: original sector for the operation
+ *
+ * The block operation request @rq in @q has been remapped.  The block
+ * operation request @rq holds the current information and @from hold
+ * the original sector.
+ */
 TRACE_EVENT(block_rq_remap,
 
        TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
index e1dbe9e..62af181 100644 (file)
@@ -398,6 +398,8 @@ struct cred *prepare_usermodehelper_creds(void)
 
 error:
        put_cred(new);
+       return NULL;
+
 free_tgcred:
 #ifdef CONFIG_KEYS
        kfree(tgcred);
@@ -791,8 +793,6 @@ bool creds_are_invalid(const struct cred *cred)
 {
        if (cred->magic != CRED_MAGIC)
                return true;
-       if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
-               return true;
 #ifdef CONFIG_SECURITY_SELINUX
        if (selinux_is_enabled()) {
                if ((unsigned long) cred->security < PAGE_SIZE)
index 4d22896..a8c9621 100644 (file)
@@ -420,7 +420,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
                         * User space encodes device types as two-byte values,
                         * so we need to recode them
                         */
-                       swdev = old_decode_dev(swap_area.dev);
+                       swdev = new_decode_dev(swap_area.dev);
                        if (swdev) {
                                offset = swap_area.offset;
                                data->swap = swap_type_of(swdev, offset, NULL);
index 63fe254..03a7ea1 100644 (file)
@@ -69,6 +69,13 @@ EXPORT_SYMBOL_GPL(rcu_scheduler_active);
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
+int debug_lockdep_rcu_enabled(void)
+{
+       return rcu_scheduler_active && debug_locks &&
+              current->lockdep_recursion == 0;
+}
+EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled);
+
 /**
  * rcu_read_lock_bh_held - might we be in RCU-bh read-side critical section?
  *
index ff01710..935248b 100644 (file)
@@ -356,7 +356,7 @@ config SLUB_STATS
 config DEBUG_KMEMLEAK
        bool "Kernel memory leak detector"
        depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
-               (X86 || ARM || PPC || S390 || SUPERH || MICROBLAZE)
+               (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE)
 
        select DEBUG_FS if SYSFS
        select STACKTRACE if STACKTRACE_SUPPORT
index 2e152ae..0d40152 100644 (file)
@@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o
 
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
         bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
-        string_helpers.o gcd.o list_sort.o
+        string_helpers.o gcd.o lcm.o list_sort.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
index ba8b670..01e6427 100644 (file)
@@ -570,7 +570,7 @@ static ssize_t filter_write(struct file *file, const char __user *userbuf,
         * Now parse out the first token and use it as the name for the
         * driver to filter for.
         */
-       for (i = 0; i < NAME_MAX_LEN; ++i) {
+       for (i = 0; i < NAME_MAX_LEN - 1; ++i) {
                current_driver_name[i] = buf[i];
                if (isspace(buf[i]) || buf[i] == ' ' || buf[i] == 0)
                        break;
diff --git a/lib/lcm.c b/lib/lcm.c
new file mode 100644 (file)
index 0000000..157cd88
--- /dev/null
+++ b/lib/lcm.c
@@ -0,0 +1,15 @@
+#include <linux/kernel.h>
+#include <linux/gcd.h>
+#include <linux/module.h>
+
+/* Lowest common multiple */
+unsigned long lcm(unsigned long a, unsigned long b)
+{
+       if (a && b)
+               return (a * b) / gcd(a, b);
+       else if (b)
+               return b;
+
+       return a;
+}
+EXPORT_SYMBOL_GPL(lcm);
index 0871582..2a087e0 100644 (file)
@@ -555,6 +555,10 @@ EXPORT_SYMBOL(radix_tree_tag_clear);
  *
  *  0: tag not present or not set
  *  1: tag set
+ *
+ * Note that the return value of this function may not be relied on, even if
+ * the RCU lock is held, unless tag modification and node deletion are excluded
+ * from concurrency.
  */
 int radix_tree_tag_get(struct radix_tree_root *root,
                        unsigned long index, unsigned int tag)
@@ -595,12 +599,8 @@ int radix_tree_tag_get(struct radix_tree_root *root,
                 */
                if (!tag_get(node, tag, offset))
                        saw_unset_tag = 1;
-               if (height == 1) {
-                       int ret = tag_get(node, tag, offset);
-
-                       BUG_ON(ret && saw_unset_tag);
-                       return !!ret;
-               }
+               if (height == 1)
+                       return !!tag_get(node, tag, offset);
                node = rcu_dereference_raw(node->slots[offset]);
                shift -= RADIX_TREE_MAP_SHIFT;
                height--;
index 24112e5..7376b7c 100644 (file)
@@ -408,12 +408,12 @@ enum format_type {
 };
 
 struct printf_spec {
-       u16     type;
-       s16     field_width;    /* width of output field */
+       u8      type;           /* format_type enum */
        u8      flags;          /* flags to number() */
-       u8      base;
-       s8      precision;      /* # of digits/chars */
-       u8      qualifier;
+       u8      base;           /* number base, 8, 10 or 16 only */
+       u8      qualifier;      /* number qualifier, one of 'hHlLtzZ' */
+       s16     field_width;    /* width of output field */
+       s16     precision;      /* # of digits/chars */
 };
 
 static char *number(char *buf, char *end, unsigned long long num,
index 0e8ca03..f13e067 100644 (file)
@@ -227,6 +227,9 @@ static struct device_attribute bdi_dev_attrs[] = {
 static __init int bdi_class_init(void)
 {
        bdi_class = class_create(THIS_MODULE, "bdi");
+       if (IS_ERR(bdi_class))
+               return PTR_ERR(bdi_class);
+
        bdi_class->dev_attrs = bdi_dev_attrs;
        bdi_debug_init();
        return 0;
index 75557c6..f90ea92 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -507,11 +507,12 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
        struct address_space *mapping = NULL;
        struct prio_tree_root *root = NULL;
        struct file *file = vma->vm_file;
-       struct anon_vma *anon_vma = NULL;
        long adjust_next = 0;
        int remove_next = 0;
 
        if (next && !insert) {
+               struct vm_area_struct *exporter = NULL;
+
                if (end >= next->vm_end) {
                        /*
                         * vma expands, overlapping all the next, and
@@ -519,7 +520,7 @@ int vma_adjust(struct vm_area_struct *vma, unsigned long start,
                         */
 again:                 remove_next = 1 + (end > next->vm_end);
                        end = next->vm_end;
-                       anon_vma = next->anon_vma;
+                       exporter = next;
                        importer = vma;
                } else if (end > next->vm_start) {
                        /*
@@ -527,7 +528,7 @@ again:                      remove_next = 1 + (end > next->vm_end);
                         * mprotect case 5 shifting the boundary up.
                         */
                        adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
-                       anon_vma = next->anon_vma;
+                       exporter = next;
                        importer = vma;
                } else if (end < vma->vm_end) {
                        /*
@@ -536,28 +537,19 @@ again:                    remove_next = 1 + (end > next->vm_end);
                         * mprotect case 4 shifting the boundary down.
                         */
                        adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
-                       anon_vma = next->anon_vma;
+                       exporter = vma;
                        importer = next;
                }
-       }
 
-       /*
-        * When changing only vma->vm_end, we don't really need anon_vma lock.
-        */
-       if (vma->anon_vma && (insert || importer || start != vma->vm_start))
-               anon_vma = vma->anon_vma;
-       if (anon_vma) {
                /*
                 * Easily overlooked: when mprotect shifts the boundary,
                 * make sure the expanding vma has anon_vma set if the
                 * shrinking vma had, to cover any anon pages imported.
                 */
-               if (importer && !importer->anon_vma) {
-                       /* Block reverse map lookups until things are set up. */
-                       if (anon_vma_clone(importer, vma)) {
+               if (exporter && exporter->anon_vma && !importer->anon_vma) {
+                       if (anon_vma_clone(importer, exporter))
                                return -ENOMEM;
-                       }
-                       importer->anon_vma = anon_vma;
+                       importer->anon_vma = exporter->anon_vma;
                }
        }
 
@@ -825,6 +817,61 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
 }
 
 /*
+ * Rough compatbility check to quickly see if it's even worth looking
+ * at sharing an anon_vma.
+ *
+ * They need to have the same vm_file, and the flags can only differ
+ * in things that mprotect may change.
+ *
+ * NOTE! The fact that we share an anon_vma doesn't _have_ to mean that
+ * we can merge the two vma's. For example, we refuse to merge a vma if
+ * there is a vm_ops->close() function, because that indicates that the
+ * driver is doing some kind of reference counting. But that doesn't
+ * really matter for the anon_vma sharing case.
+ */
+static int anon_vma_compatible(struct vm_area_struct *a, struct vm_area_struct *b)
+{
+       return a->vm_end == b->vm_start &&
+               mpol_equal(vma_policy(a), vma_policy(b)) &&
+               a->vm_file == b->vm_file &&
+               !((a->vm_flags ^ b->vm_flags) & ~(VM_READ|VM_WRITE|VM_EXEC)) &&
+               b->vm_pgoff == a->vm_pgoff + ((b->vm_start - a->vm_start) >> PAGE_SHIFT);
+}
+
+/*
+ * Do some basic sanity checking to see if we can re-use the anon_vma
+ * from 'old'. The 'a'/'b' vma's are in VM order - one of them will be
+ * the same as 'old', the other will be the new one that is trying
+ * to share the anon_vma.
+ *
+ * NOTE! This runs with mm_sem held for reading, so it is possible that
+ * the anon_vma of 'old' is concurrently in the process of being set up
+ * by another page fault trying to merge _that_. But that's ok: if it
+ * is being set up, that automatically means that it will be a singleton
+ * acceptable for merging, so we can do all of this optimistically. But
+ * we do that ACCESS_ONCE() to make sure that we never re-load the pointer.
+ *
+ * IOW: that the "list_is_singular()" test on the anon_vma_chain only
+ * matters for the 'stable anon_vma' case (ie the thing we want to avoid
+ * is to return an anon_vma that is "complex" due to having gone through
+ * a fork).
+ *
+ * We also make sure that the two vma's are compatible (adjacent,
+ * and with the same memory policies). That's all stable, even with just
+ * a read lock on the mm_sem.
+ */
+static struct anon_vma *reusable_anon_vma(struct vm_area_struct *old, struct vm_area_struct *a, struct vm_area_struct *b)
+{
+       if (anon_vma_compatible(a, b)) {
+               struct anon_vma *anon_vma = ACCESS_ONCE(old->anon_vma);
+
+               if (anon_vma && list_is_singular(&old->anon_vma_chain))
+                       return anon_vma;
+       }
+       return NULL;
+}
+
+/*
  * find_mergeable_anon_vma is used by anon_vma_prepare, to check
  * neighbouring vmas for a suitable anon_vma, before it goes off
  * to allocate a new anon_vma.  It checks because a repetitive
@@ -834,28 +881,16 @@ struct vm_area_struct *vma_merge(struct mm_struct *mm,
  */
 struct anon_vma *find_mergeable_anon_vma(struct vm_area_struct *vma)
 {
+       struct anon_vma *anon_vma;
        struct vm_area_struct *near;
-       unsigned long vm_flags;
 
        near = vma->vm_next;
        if (!near)
                goto try_prev;
 
-       /*
-        * Since only mprotect tries to remerge vmas, match flags
-        * which might be mprotected into each other later on.
-        * Neither mlock nor madvise tries to remerge at present,
-        * so leave their flags as obstructing a merge.
-        */
-       vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
-       vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
-       if (near->anon_vma && vma->vm_end == near->vm_start &&
-                       mpol_equal(vma_policy(vma), vma_policy(near)) &&
-                       can_vma_merge_before(near, vm_flags,
-                               NULL, vma->vm_file, vma->vm_pgoff +
-                               ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT)))
-               return near->anon_vma;
+       anon_vma = reusable_anon_vma(near, vma, near);
+       if (anon_vma)
+               return anon_vma;
 try_prev:
        /*
         * It is potentially slow to have to call find_vma_prev here.
@@ -868,14 +903,9 @@ try_prev:
        if (!near)
                goto none;
 
-       vm_flags = vma->vm_flags & ~(VM_READ|VM_WRITE|VM_EXEC);
-       vm_flags |= near->vm_flags & (VM_READ|VM_WRITE|VM_EXEC);
-
-       if (near->anon_vma && near->vm_end == vma->vm_start &&
-                       mpol_equal(vma_policy(near), vma_policy(vma)) &&
-                       can_vma_merge_after(near, vm_flags,
-                               NULL, vma->vm_file, vma->vm_pgoff))
-               return near->anon_vma;
+       anon_vma = reusable_anon_vma(near, near, vma);
+       if (anon_vma)
+               return anon_vma;
 none:
        /*
         * There's no absolute need to look only at touching neighbours:
index eaa7a09..526704e 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -182,7 +182,7 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
 {
        struct anon_vma_chain *avc, *pavc;
 
-       list_for_each_entry(pavc, &src->anon_vma_chain, same_vma) {
+       list_for_each_entry_reverse(pavc, &src->anon_vma_chain, same_vma) {
                avc = anon_vma_chain_alloc();
                if (!avc)
                        goto enomem_failure;
@@ -730,13 +730,29 @@ void page_move_anon_rmap(struct page *page,
  * @page:      the page to add the mapping to
  * @vma:       the vm area in which the mapping is added
  * @address:   the user virtual address mapped
+ * @exclusive: the page is exclusively owned by the current process
  */
 static void __page_set_anon_rmap(struct page *page,
-       struct vm_area_struct *vma, unsigned long address)
+       struct vm_area_struct *vma, unsigned long address, int exclusive)
 {
        struct anon_vma *anon_vma = vma->anon_vma;
 
        BUG_ON(!anon_vma);
+
+       /*
+        * If the page isn't exclusively mapped into this vma,
+        * we must use the _oldest_ possible anon_vma for the
+        * page mapping!
+        *
+        * So take the last AVC chain entry in the vma, which is
+        * the deepest ancestor, and use the anon_vma from that.
+        */
+       if (!exclusive) {
+               struct anon_vma_chain *avc;
+               avc = list_entry(vma->anon_vma_chain.prev, struct anon_vma_chain, same_vma);
+               anon_vma = avc->anon_vma;
+       }
+
        anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
        page->mapping = (struct address_space *) anon_vma;
        page->index = linear_page_index(vma, address);
@@ -791,7 +807,7 @@ void page_add_anon_rmap(struct page *page,
        VM_BUG_ON(!PageLocked(page));
        VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end);
        if (first)
-               __page_set_anon_rmap(page, vma, address);
+               __page_set_anon_rmap(page, vma, address, 0);
        else
                __page_check_anon_rmap(page, vma, address);
 }
@@ -813,7 +829,7 @@ void page_add_new_anon_rmap(struct page *page,
        SetPageSwapBacked(page);
        atomic_set(&page->_mapcount, 0); /* increment count (starts at -1) */
        __inc_zone_page_state(page, NR_ANON_PAGES);
-       __page_set_anon_rmap(page, vma, address);
+       __page_set_anon_rmap(page, vma, address, 1);
        if (page_evictable(page, vma))
                lru_cache_add_lru(page, LRU_ACTIVE_ANON);
        else
index a9f325b..bac0f4f 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3602,21 +3602,10 @@ EXPORT_SYMBOL(kmem_cache_alloc_notrace);
  */
 int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
 {
-       unsigned long addr = (unsigned long)ptr;
-       unsigned long min_addr = PAGE_OFFSET;
-       unsigned long align_mask = BYTES_PER_WORD - 1;
        unsigned long size = cachep->buffer_size;
        struct page *page;
 
-       if (unlikely(addr < min_addr))
-               goto out;
-       if (unlikely(addr > (unsigned long)high_memory - size))
-               goto out;
-       if (unlikely(addr & align_mask))
-               goto out;
-       if (unlikely(!kern_addr_valid(addr)))
-               goto out;
-       if (unlikely(!kern_addr_valid(addr + size - 1)))
+       if (unlikely(!kern_ptr_validate(ptr, size)))
                goto out;
        page = virt_to_page(ptr);
        if (unlikely(!PageSlab(page)))
index b364844..7d6c8b1 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2386,6 +2386,9 @@ int kmem_ptr_validate(struct kmem_cache *s, const void *object)
 {
        struct page *page;
 
+       if (!kern_ptr_validate(object, s->size))
+               return 0;
+
        page = get_object_page(object);
 
        if (!page || s != page->slab)
index 834db7b..f5712e8 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -186,6 +186,27 @@ void kzfree(const void *p)
 }
 EXPORT_SYMBOL(kzfree);
 
+int kern_ptr_validate(const void *ptr, unsigned long size)
+{
+       unsigned long addr = (unsigned long)ptr;
+       unsigned long min_addr = PAGE_OFFSET;
+       unsigned long align_mask = sizeof(void *) - 1;
+
+       if (unlikely(addr < min_addr))
+               goto out;
+       if (unlikely(addr > (unsigned long)high_memory - size))
+               goto out;
+       if (unlikely(addr & align_mask))
+               goto out;
+       if (unlikely(!kern_addr_valid(addr)))
+               goto out;
+       if (unlikely(!kern_addr_valid(addr + size - 1)))
+               goto out;
+       return 1;
+out:
+       return 0;
+}
+
 /*
  * strndup_user - duplicate an existing string from user space
  * @s: The string to duplicate
index 6980625..f29ada8 100644 (file)
@@ -723,7 +723,7 @@ static int br_multicast_igmp3_report(struct net_bridge *br,
                if (!pskb_may_pull(skb, len))
                        return -EINVAL;
 
-               grec = (void *)(skb->data + len);
+               grec = (void *)(skb->data + len - sizeof(*grec));
                group = grec->grec_mca;
                type = grec->grec_type;
 
index 3a7dffb..da99cf1 100644 (file)
@@ -445,7 +445,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
                                return -EFAULT;
                        }
                } else if (count == 1) {
-                       if (copy_from_user(&sfilter, optval, optlen))
+                       if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
                                return -EFAULT;
                }
 
index 1c8a0ce..92584bf 100644 (file)
@@ -1989,8 +1989,12 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
                        if (dev->real_num_tx_queues > 1)
                                queue_index = skb_tx_hash(dev, skb);
 
-                       if (sk && sk->sk_dst_cache)
-                               sk_tx_queue_set(sk, queue_index);
+                       if (sk) {
+                               struct dst_entry *dst = rcu_dereference(sk->sk_dst_cache);
+
+                               if (dst && skb_dst(skb) == dst)
+                                       sk_tx_queue_set(sk, queue_index);
+                       }
                }
        }
 
index 59a8387..c98f115 100644 (file)
@@ -209,7 +209,9 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i)
 {
        struct node *ret = tnode_get_child(tn, i);
 
-       return rcu_dereference(ret);
+       return rcu_dereference_check(ret,
+                                    rcu_read_lock_held() ||
+                                    lockdep_rtnl_is_held());
 }
 
 static inline int tnode_child_length(const struct tnode *tn)
index c65f18e..d1bcc9f 100644 (file)
@@ -120,7 +120,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
        newskb->pkt_type = PACKET_LOOPBACK;
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
        WARN_ON(!skb_dst(newskb));
-       netif_rx(newskb);
+       netif_rx_ni(newskb);
        return 0;
 }
 
index 954bbfb..8fef859 100644 (file)
@@ -472,8 +472,8 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
                        if (hslot->count < hslot2->count)
                                goto begin;
 
-                       result = udp4_lib_lookup2(net, INADDR_ANY, sport,
-                                                 daddr, hnum, dif,
+                       result = udp4_lib_lookup2(net, saddr, sport,
+                                                 INADDR_ANY, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
index 16c4391..65f9c37 100644 (file)
@@ -108,7 +108,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
        WARN_ON(!skb_dst(newskb));
 
-       netif_rx(newskb);
+       netif_rx_ni(newskb);
        return 0;
 }
 
index c177aea..9082485 100644 (file)
@@ -259,8 +259,8 @@ static struct sock *__udp6_lib_lookup(struct net *net,
                        if (hslot->count < hslot2->count)
                                goto begin;
 
-                       result = udp6_lib_lookup2(net, &in6addr_any, sport,
-                                                 daddr, hnum, dif,
+                       result = udp6_lib_lookup2(net, saddr, sport,
+                                                 &in6addr_any, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
index 06c33b6..b887e48 100644 (file)
@@ -225,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
                        switch (sdata->vif.type) {
                        case NL80211_IFTYPE_AP:
                                sdata->vif.bss_conf.enable_beacon =
-                                       !!rcu_dereference(sdata->u.ap.beacon);
+                                       !!sdata->u.ap.beacon;
                                break;
                        case NL80211_IFTYPE_ADHOC:
                                sdata->vif.bss_conf.enable_beacon =
-                                       !!rcu_dereference(sdata->u.ibss.presp);
+                                       !!sdata->u.ibss.presp;
                                break;
                        case NL80211_IFTYPE_MESH_POINT:
                                sdata->vif.bss_conf.enable_beacon = true;
index 58e3e3a..859ee5f 100644 (file)
@@ -750,9 +750,6 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
 
        switch (fc & IEEE80211_FCTL_STYPE) {
        case IEEE80211_STYPE_ACTION:
-               if (skb->len < IEEE80211_MIN_ACTION_SIZE)
-                       return RX_DROP_MONITOR;
-               /* fall through */
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
                skb_queue_tail(&ifmsh->skb_queue, skb);
index f0accf6..04ea07f 100644 (file)
@@ -1974,6 +1974,11 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        goto handled;
                }
                break;
+       case MESH_PLINK_CATEGORY:
+       case MESH_PATH_SEL_CATEGORY:
+               if (ieee80211_vif_is_mesh(&sdata->vif))
+                       return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
+               break;
        }
 
        /*
index 56422d8..fb12cec 100644 (file)
@@ -93,12 +93,18 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+                                   rcu_read_lock_held() ||
+                                   lockdep_is_held(&local->sta_lock) ||
+                                   lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if (sta->sdata == sdata &&
                    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
                        break;
-               sta = rcu_dereference(sta->hnext);
+               sta = rcu_dereference_check(sta->hnext,
+                                           rcu_read_lock_held() ||
+                                           lockdep_is_held(&local->sta_lock) ||
+                                           lockdep_is_held(&local->sta_mtx));
        }
        return sta;
 }
@@ -113,13 +119,19 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
+       sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)],
+                                   rcu_read_lock_held() ||
+                                   lockdep_is_held(&local->sta_lock) ||
+                                   lockdep_is_held(&local->sta_mtx));
        while (sta) {
                if ((sta->sdata == sdata ||
                     sta->sdata->bss == sdata->bss) &&
                    memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
                        break;
-               sta = rcu_dereference(sta->hnext);
+               sta = rcu_dereference_check(sta->hnext,
+                                           rcu_read_lock_held() ||
+                                           lockdep_is_held(&local->sta_lock) ||
+                                           lockdep_is_held(&local->sta_mtx));
        }
        return sta;
 }
index cc90363..243946d 100644 (file)
@@ -2169,8 +2169,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
        case SIOCGIFDSTADDR:
        case SIOCSIFDSTADDR:
        case SIOCSIFFLAGS:
-               if (!net_eq(sock_net(sk), &init_net))
-                       return -ENOIOCTLCMD;
                return inet_dgram_ops.ioctl(sock, cmd, arg);
 #endif
 
index fd90eb8..edea15a 100644 (file)
@@ -679,7 +679,10 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
        int ret;
 
        dprintk("svcrdma: Creating RDMA socket\n");
-
+       if (sa->sa_family != AF_INET) {
+               dprintk("svcrdma: Address family %d is not supported.\n", sa->sa_family);
+               return ERR_PTR(-EAFNOSUPPORT);
+       }
        cma_xprt = rdma_create_xprt(serv, 1);
        if (!cma_xprt)
                return ERR_PTR(-ENOMEM);
index e56f711..cbddd0c 100644 (file)
@@ -83,6 +83,41 @@ struct compat_x25_subscrip_struct {
 };
 #endif
 
+
+int x25_parse_address_block(struct sk_buff *skb,
+               struct x25_address *called_addr,
+               struct x25_address *calling_addr)
+{
+       unsigned char len;
+       int needed;
+       int rc;
+
+       if (skb->len < 1) {
+               /* packet has no address block */
+               rc = 0;
+               goto empty;
+       }
+
+       len = *skb->data;
+       needed = 1 + (len >> 4) + (len & 0x0f);
+
+       if (skb->len < needed) {
+               /* packet is too short to hold the addresses it claims
+                  to hold */
+               rc = -1;
+               goto empty;
+       }
+
+       return x25_addr_ntoa(skb->data, called_addr, calling_addr);
+
+empty:
+       *called_addr->x25_addr = 0;
+       *calling_addr->x25_addr = 0;
+
+       return rc;
+}
+
+
 int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
                  struct x25_address *calling_addr)
 {
@@ -554,7 +589,8 @@ static int x25_create(struct net *net, struct socket *sock, int protocol,
        x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
        x25->facilities.pacsize_in  = X25_DEFAULT_PACKET_SIZE;
        x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
-       x25->facilities.throughput  = X25_DEFAULT_THROUGHPUT;
+       x25->facilities.throughput  = 0;        /* by default don't negotiate
+                                                  throughput */
        x25->facilities.reverse     = X25_DEFAULT_REVERSE;
        x25->dte_facilities.calling_len = 0;
        x25->dte_facilities.called_len = 0;
@@ -922,16 +958,26 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
        /*
         *      Extract the X.25 addresses and convert them to ASCII strings,
         *      and remove them.
+        *
+        *      Address block is mandatory in call request packets
         */
-       addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr);
+       addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
+       if (addr_len <= 0)
+               goto out_clear_request;
        skb_pull(skb, addr_len);
 
        /*
         *      Get the length of the facilities, skip past them for the moment
         *      get the call user data because this is needed to determine
         *      the correct listener
+        *
+        *      Facilities length is mandatory in call request packets
         */
+       if (skb->len < 1)
+               goto out_clear_request;
        len = skb->data[0] + 1;
+       if (skb->len < len)
+               goto out_clear_request;
        skb_pull(skb,len);
 
        /*
@@ -1415,9 +1461,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                        if (facilities.winsize_in < 1 ||
                            facilities.winsize_in > 127)
                                break;
-                       if (facilities.throughput < 0x03 ||
-                           facilities.throughput > 0xDD)
-                               break;
+                       if (facilities.throughput) {
+                               int out = facilities.throughput & 0xf0;
+                               int in  = facilities.throughput & 0x0f;
+                               if (!out)
+                                       facilities.throughput |=
+                                               X25_DEFAULT_THROUGHPUT << 4;
+                               else if (out < 0x30 || out > 0xD0)
+                                       break;
+                               if (!in)
+                                       facilities.throughput |=
+                                               X25_DEFAULT_THROUGHPUT;
+                               else if (in < 0x03 || in > 0x0D)
+                                       break;
+                       }
                        if (facilities.reverse &&
                                (facilities.reverse & 0x81) != 0x81)
                                break;
index a21f664..771bab0 100644 (file)
@@ -35,7 +35,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
                struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
 {
        unsigned char *p = skb->data;
-       unsigned int len = *p++;
+       unsigned int len;
 
        *vc_fac_mask = 0;
 
@@ -50,6 +50,14 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
        memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
        memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
 
+       if (skb->len < 1)
+               return 0;
+
+       len = *p++;
+
+       if (len >= skb->len)
+               return -1;
+
        while (len > 0) {
                switch (*p & X25_FAC_CLASS_MASK) {
                case X25_FAC_CLASS_A:
@@ -247,6 +255,8 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
        memcpy(new, ours, sizeof(*new));
 
        len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask);
+       if (len < 0)
+               return len;
 
        /*
         *      They want reverse charging, we won't accept it.
@@ -259,9 +269,18 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
        new->reverse = theirs.reverse;
 
        if (theirs.throughput) {
-               if (theirs.throughput < ours->throughput) {
-                       SOCK_DEBUG(sk, "X.25: throughput negotiated down\n");
-                       new->throughput = theirs.throughput;
+               int theirs_in =  theirs.throughput & 0x0f;
+               int theirs_out = theirs.throughput & 0xf0;
+               int ours_in  = ours->throughput & 0x0f;
+               int ours_out = ours->throughput & 0xf0;
+               if (!ours_in || theirs_in < ours_in) {
+                       SOCK_DEBUG(sk, "X.25: inbound throughput negotiated\n");
+                       new->throughput = (new->throughput & 0xf0) | theirs_in;
+               }
+               if (!ours_out || theirs_out < ours_out) {
+                       SOCK_DEBUG(sk,
+                               "X.25: outbound throughput negotiated\n");
+                       new->throughput = (new->throughput & 0x0f) | theirs_out;
                }
        }
 
index a31b3b9..372ac22 100644 (file)
@@ -90,6 +90,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
 static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
 {
        struct x25_address source_addr, dest_addr;
+       int len;
 
        switch (frametype) {
                case X25_CALL_ACCEPTED: {
@@ -107,11 +108,17 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
                         *      Parse the data in the frame.
                         */
                        skb_pull(skb, X25_STD_MIN_LEN);
-                       skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
-                       skb_pull(skb,
-                                x25_parse_facilities(skb, &x25->facilities,
+
+                       len = x25_parse_address_block(skb, &source_addr,
+                                               &dest_addr);
+                       if (len > 0)
+                               skb_pull(skb, len);
+
+                       len = x25_parse_facilities(skb, &x25->facilities,
                                                &x25->dte_facilities,
-                                               &x25->vc_facil_mask));
+                                               &x25->vc_facil_mask);
+                       if (len > 0)
+                               skb_pull(skb, len);
                        /*
                         *      Copy any Call User Data.
                         */
index c3a7938..1c812e8 100644 (file)
@@ -161,13 +161,13 @@ static int create_by_name(const char *name, mode_t mode,
 
        mutex_lock(&parent->d_inode->i_mutex);
        *dentry = lookup_one_len(name, parent, strlen(name));
-       if (!IS_ERR(dentry)) {
+       if (!IS_ERR(*dentry)) {
                if ((mode & S_IFMT) == S_IFDIR)
                        error = mkdir(parent->d_inode, *dentry, mode);
                else
                        error = create(parent->d_inode, *dentry, mode);
        } else
-               error = PTR_ERR(dentry);
+               error = PTR_ERR(*dentry);
        mutex_unlock(&parent->d_inode->i_mutex);
 
        return error;
index 8da6a84..cd4f734 100644 (file)
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
 void avtab_cache_init(void);
 void avtab_cache_destroy(void);
 
-#define MAX_AVTAB_HASH_BITS 13
+#define MAX_AVTAB_HASH_BITS 11
 #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
 #define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
 #define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
index 656e474..91acc9a 100644 (file)
@@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
        struct snd_ac97 *ac97;
        int ret;
 
-       writel(0, aaci->base + AC97_POWERDOWN);
        /*
         * Assert AACIRESET for 2us
         */
@@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
 
        writel(0x1fff, aaci->base + AACI_INTCLR);
        writel(aaci->maincr, aaci->base + AACI_MAINCR);
-
+       /*
+        * Fix: ac97 read back fail errors by reading
+        * from any arbitrary aaci register.
+        */
+       readl(aaci->base + AACI_CSCH1);
        ret = aaci_probe_ac97(aaci);
        if (ret)
                goto out;
index f8fd586..f669442 100644 (file)
@@ -2272,6 +2272,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
        SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
+       SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
        SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
        {}
 };
index c7730db..aad1627 100644 (file)
@@ -230,6 +230,7 @@ enum {
        ALC888_ACER_ASPIRE_7730G,
        ALC883_MEDION,
        ALC883_MEDION_MD2,
+       ALC883_MEDION_WIM2160,
        ALC883_LAPTOP_EAPD,
        ALC883_LENOVO_101E_2ch,
        ALC883_LENOVO_NB0763,
@@ -1389,22 +1390,31 @@ struct alc_fixup {
 
 static void alc_pick_fixup(struct hda_codec *codec,
                           const struct snd_pci_quirk *quirk,
-                          const struct alc_fixup *fix)
+                          const struct alc_fixup *fix,
+                          int pre_init)
 {
        const struct alc_pincfg *cfg;
 
        quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
        if (!quirk)
                return;
-
        fix += quirk->value;
        cfg = fix->pins;
-       if (cfg) {
+       if (pre_init && cfg) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+               snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
+                           codec->chip_name, quirk->name);
+#endif
                for (; cfg->nid; cfg++)
                        snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
        }
-       if (fix->verbs)
+       if (!pre_init && fix->verbs) {
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+               snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
+                           codec->chip_name, quirk->name);
+#endif
                add_verb(codec->spec, fix->verbs);
+       }
 }
 
 static int alc_read_coef_idx(struct hda_codec *codec,
@@ -4808,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
        }
 }
 
+static void alc880_auto_init_input_src(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       int c;
+
+       for (c = 0; c < spec->num_adc_nids; c++) {
+               unsigned int mux_idx;
+               const struct hda_input_mux *imux;
+               mux_idx = c >= spec->num_mux_defs ? 0 : c;
+               imux = &spec->input_mux[mux_idx];
+               if (!imux->num_items && mux_idx > 0)
+                       imux = &spec->input_mux[0];
+               if (imux)
+                       snd_hda_codec_write(codec, spec->adc_nids[c], 0,
+                                           AC_VERB_SET_CONNECT_SEL,
+                                           imux->items[0].index);
+       }
+}
+
 /* parse the BIOS configuration and set up the alc_spec */
 /* return 1 if successful, 0 if the proper config is not found,
  * or a negative error code
@@ -4886,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec)
        alc880_auto_init_multi_out(codec);
        alc880_auto_init_extra_out(codec);
        alc880_auto_init_analog_input(codec);
+       alc880_auto_init_input_src(codec);
        if (spec->unsol_event)
                alc_inithook(codec);
 }
@@ -6397,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)
        }
 }
 
+#define alc260_auto_init_input_src     alc880_auto_init_input_src
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -6483,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec)
        struct alc_spec *spec = codec->spec;
        alc260_auto_init_multi_out(codec);
        alc260_auto_init_analog_input(codec);
+       alc260_auto_init_input_src(codec);
        if (spec->unsol_event)
                alc_inithook(codec);
 }
@@ -8455,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
        { } /* end */
 };
 
+static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
+       HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+       HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+       HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+       HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
+       HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
+       HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
+       { } /* end */
+};
+
+static struct hda_verb alc883_medion_wim2160_verbs[] = {
+       /* Unmute front mixer */
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+       {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+       /* Set speaker pin to front mixer */
+       {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+       /* Init headphone pin */
+       {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+       {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+       {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
+       {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+
+       { } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_medion_wim2160_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+
+       spec->autocfg.hp_pins[0] = 0x1a;
+       spec->autocfg.speaker_pins[0] = 0x15;
+}
+
 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -9164,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
        [ALC888_ACER_ASPIRE_7730G]      = "acer-aspire-7730g",
        [ALC883_MEDION]         = "medion",
        [ALC883_MEDION_MD2]     = "medion-md2",
+       [ALC883_MEDION_WIM2160] = "medion-wim2160",
        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
        [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
        [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
@@ -9280,6 +9350,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
        SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
 
        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
+       SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
        SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
@@ -9818,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = {
                .setup = alc883_medion_md2_setup,
                .init_hook = alc_automute_amp,
        },
+       [ALC883_MEDION_WIM2160] = {
+               .mixers = { alc883_medion_wim2160_mixer },
+               .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
+               .num_dacs = ARRAY_SIZE(alc883_dac_nids),
+               .dac_nids = alc883_dac_nids,
+               .dig_out_nid = ALC883_DIGOUT_NID,
+               .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+               .adc_nids = alc883_adc_nids,
+               .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+               .channel_mode = alc883_3ST_2ch_modes,
+               .input_mux = &alc883_capture_source,
+               .unsol_event = alc_automute_amp_unsol_event,
+               .setup = alc883_medion_wim2160_setup,
+               .init_hook = alc_automute_amp,
+       },
        [ALC883_LAPTOP_EAPD] = {
                .mixers = { alc883_base_mixer },
                .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
@@ -10363,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec)
                board_config = ALC882_AUTO;
        }
 
-       alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
+       if (board_config == ALC882_AUTO)
+               alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
 
        if (board_config == ALC882_AUTO) {
                /* automatic parse from the BIOS config */
@@ -10436,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec)
        set_capture_mixer(codec);
        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
 
+       if (board_config == ALC882_AUTO)
+               alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
+
        spec->vmaster_nid = 0x0c;
 
        codec->patch_ops = alc_patch_ops;
@@ -12816,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
                dac = 0x02;
                break;
        case 0x15:
+       case 0x21: /* ALC269vb has this pin, too */
                dac = 0x03;
                break;
        default:
@@ -13735,19 +13826,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,
        }
 }
 
-static void alc269_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_amic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        spec->autocfg.hp_pins[0] = 0x15;
        spec->autocfg.speaker_pins[0] = 0x14;
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
-       spec->int_mic.pin = 0x12;
-       spec->int_mic.mux_idx = 5;
+       spec->int_mic.pin = 0x19;
+       spec->int_mic.mux_idx = 1;
        spec->auto_mic = 1;
 }
 
-static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+static void alc269_laptop_dmic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
        spec->autocfg.hp_pins[0] = 0x15;
@@ -13755,14 +13846,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
        spec->int_mic.pin = 0x12;
-       spec->int_mic.mux_idx = 6;
+       spec->int_mic.mux_idx = 5;
        spec->auto_mic = 1;
 }
 
-static void alc269_laptop_amic_setup(struct hda_codec *codec)
+static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
-       spec->autocfg.hp_pins[0] = 0x15;
+       spec->autocfg.hp_pins[0] = 0x21;
        spec->autocfg.speaker_pins[0] = 0x14;
        spec->ext_mic.pin = 0x18;
        spec->ext_mic.mux_idx = 0;
@@ -13771,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec)
        spec->auto_mic = 1;
 }
 
+static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
+{
+       struct alc_spec *spec = codec->spec;
+       spec->autocfg.hp_pins[0] = 0x21;
+       spec->autocfg.speaker_pins[0] = 0x14;
+       spec->ext_mic.pin = 0x18;
+       spec->ext_mic.mux_idx = 0;
+       spec->int_mic.pin = 0x12;
+       spec->int_mic.mux_idx = 6;
+       spec->auto_mic = 1;
+}
+
 static void alc269_laptop_inithook(struct hda_codec *codec)
 {
        alc269_speaker_automute(codec);
@@ -13975,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec)
                alc_inithook(codec);
 }
 
+enum {
+       ALC269_FIXUP_SONY_VAIO,
+};
+
+const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
+       {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
+       {}
+};
+
+static const struct alc_fixup alc269_fixups[] = {
+       [ALC269_FIXUP_SONY_VAIO] = {
+               .verbs = alc269_sony_vaio_fixup_verbs
+       },
+};
+
+static struct snd_pci_quirk alc269_fixup_tbl[] = {
+       SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
+       {}
+};
+
+
 /*
  * configuration and preset
  */
@@ -14034,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
                      ALC269_DMIC),
        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
        SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
-       SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
+       SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
        SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
        SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
        SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
@@ -14108,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc269_modes),
                .channel_mode = alc269_modes,
                .unsol_event = alc269_laptop_unsol_event,
-               .setup = alc269_laptop_amic_setup,
+               .setup = alc269vb_laptop_amic_setup,
                .init_hook = alc269_laptop_inithook,
        },
        [ALC269VB_DMIC] = {
@@ -14188,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec)
                board_config = ALC269_AUTO;
        }
 
+       if (board_config == ALC269_AUTO)
+               alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
+
        if (board_config == ALC269_AUTO) {
                /* automatic parse from the BIOS config */
                err = alc269_parse_auto_config(codec);
@@ -14240,6 +14367,9 @@ static int patch_alc269(struct hda_codec *codec)
                set_capture_mixer(codec);
        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 
+       if (board_config == ALC269_AUTO)
+               alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
+
        spec->vmaster_nid = 0x02;
 
        codec->patch_ops = alc_patch_ops;
@@ -15328,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec)
                board_config = ALC861_AUTO;
        }
 
-       alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
+       if (board_config == ALC861_AUTO)
+               alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
 
        if (board_config == ALC861_AUTO) {
                /* automatic parse from the BIOS config */
@@ -15365,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec)
 
        spec->vmaster_nid = 0x03;
 
+       if (board_config == ALC861_AUTO)
+               alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
+
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC861_AUTO) {
                spec->init_hook = alc861_auto_init;
@@ -16299,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec)
                board_config = ALC861VD_AUTO;
        }
 
-       alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
+       if (board_config == ALC861VD_AUTO)
+               alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
 
        if (board_config == ALC861VD_AUTO) {
                /* automatic parse from the BIOS config */
@@ -16347,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec)
 
        spec->vmaster_nid = 0x02;
 
+       if (board_config == ALC861VD_AUTO)
+               alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
+
        codec->patch_ops = alc_patch_ops;
 
        if (board_config == ALC861VD_AUTO)
index 9ddc373..7345381 100644 (file)
@@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
        knew->name = kstrdup(tmpl->name, GFP_KERNEL);
        if (!knew->name)
                return NULL;
-       return 0;
+       return knew;
 }
 
 static void via_free_kctls(struct hda_codec *codec)
@@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = {
        },
 };
 
-static int via_hp_build(struct via_spec *spec)
+static int via_hp_build(struct hda_codec *codec)
 {
+       struct via_spec *spec = codec->spec;
        struct snd_kcontrol_new *knew;
        hda_nid_t nid;
-
-       knew = via_clone_control(spec, &via_hp_mixer[0]);
-       if (knew == NULL)
-               return -ENOMEM;
+       int nums;
+       hda_nid_t conn[HDA_MAX_CONNECTIONS];
 
        switch (spec->codec_type) {
        case VT1718S:
@@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec)
                break;
        }
 
+       nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
+       if (nums <= 1)
+               return 0;
+
+       knew = via_clone_control(spec, &via_hp_mixer[0]);
+       if (knew == NULL)
+               return -ENOMEM;
+
        knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
        knew->private_value = nid;
 
@@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
        return 1;
@@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
@@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
 
@@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        via_smart51_build(spec);
 
@@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
@@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
 
        /* Line-Out: PortE */
        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
-                             "Master Front Playback Volume",
+                             "Front Playback Volume",
                              HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
        if (err < 0)
                return err;
        err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
-                             "Master Front Playback Switch",
+                             "Front Playback Switch",
                              HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
        if (err < 0)
                return err;
@@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec)
        spec->input_mux = &spec->private_imux[0];
 
        if (spec->hp_mux)
-               via_hp_build(spec);
+               via_hp_build(codec);
 
        return 1;
 }
index a34cbcf..002e289 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/firmware.h>
index 2e79d71..2b31ac6 100644 (file)
@@ -71,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data)
 
 static void snd_imx_dma_err_callback(int channel, void *data, int err)
 {
-       pr_err("DMA error callback called\n");
+       struct snd_pcm_substream *substream = data;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+       int ret;
 
        pr_err("DMA timeout on channel %d -%s%s%s%s\n",
                 channel,
@@ -79,6 +84,14 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
                 err & IMX_DMA_ERR_REQUEST ?  " request" : "",
                 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
                 err & IMX_DMA_ERR_BUFFER ?   " buffer" : "");
+
+       imx_dma_disable(iprtd->dma);
+       ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
+                       IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
+                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+                       DMA_MODE_WRITE : DMA_MODE_READ);
+       if (!ret)
+               imx_dma_enable(iprtd->dma);
 }
 
 static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
index f96a373..6b518e0 100644 (file)
@@ -39,23 +39,24 @@ struct imx_pcm_runtime_data {
        unsigned long offset;
        unsigned long last_offset;
        unsigned long size;
-       struct timer_list timer;
-       int poll_time;
+       struct hrtimer hrt;
+       int poll_time_ns;
+       struct snd_pcm_substream *substream;
+       atomic_t running;
 };
 
-static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd)
+static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
 {
-       iprtd->timer.expires = jiffies + iprtd->poll_time;
-}
-
-static void imx_ssi_timer_callback(unsigned long data)
-{
-       struct snd_pcm_substream *substream = (void *)data;
+       struct imx_pcm_runtime_data *iprtd =
+               container_of(hrt, struct imx_pcm_runtime_data, hrt);
+       struct snd_pcm_substream *substream = iprtd->substream;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct imx_pcm_runtime_data *iprtd = runtime->private_data;
        struct pt_regs regs;
        unsigned long delta;
 
+       if (!atomic_read(&iprtd->running))
+               return HRTIMER_NORESTART;
+
        get_fiq_regs(&regs);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -72,16 +73,14 @@ static void imx_ssi_timer_callback(unsigned long data)
 
        /* If we've transferred at least a period then report it and
         * reset our poll time */
-       if (delta >= runtime->period_size) {
+       if (delta >= iprtd->period) {
                snd_pcm_period_elapsed(substream);
                iprtd->last_offset = iprtd->offset;
-
-               imx_ssi_set_next_poll(iprtd);
        }
 
-       /* Restart the timer; if we didn't report we'll run on the next tick */
-       add_timer(&iprtd->timer);
+       hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns));
 
+       return HRTIMER_RESTART;
 }
 
 static struct fiq_handler fh = {
@@ -99,8 +98,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
        iprtd->period = params_period_bytes(params) ;
        iprtd->offset = 0;
        iprtd->last_offset = 0;
-       iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));
-
+       iprtd->poll_time_ns = 1000000000 / params_rate(params) *
+                               params_period_size(params);
        snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
        return 0;
@@ -135,8 +134,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               imx_ssi_set_next_poll(iprtd);
-               add_timer(&iprtd->timer);
+               atomic_set(&iprtd->running, 1);
+               hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns),
+                     HRTIMER_MODE_REL);
                if (++fiq_enable == 1)
                        enable_fiq(imx_pcm_fiq);
 
@@ -145,11 +145,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               del_timer(&iprtd->timer);
+               atomic_set(&iprtd->running, 0);
+
                if (--fiq_enable == 0)
                        disable_fiq(imx_pcm_fiq);
 
-
                break;
        default:
                return -EINVAL;
@@ -180,7 +180,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
        .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
        .period_bytes_min = 128,
        .period_bytes_max = 16 * 1024,
-       .periods_min = 2,
+       .periods_min = 4,
        .periods_max = 255,
        .fifo_size = 0,
 };
@@ -194,9 +194,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
        iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
        runtime->private_data = iprtd;
 
-       init_timer(&iprtd->timer);
-       iprtd->timer.data = (unsigned long)substream;
-       iprtd->timer.function = imx_ssi_timer_callback;
+       iprtd->substream = substream;
+
+       atomic_set(&iprtd->running, 0);
+       hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       iprtd->hrt.function = snd_hrtimer_callback;
 
        ret = snd_pcm_hw_constraint_integer(substream->runtime,
                        SNDRV_PCM_HW_PARAM_PERIODS);
@@ -212,7 +214,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
-       del_timer_sync(&iprtd->timer);
+       hrtimer_cancel(&iprtd->hrt);
+
        kfree(iprtd);
 
        return 0;
index 0bcc6d7..80b4fee 100644 (file)
@@ -656,7 +656,8 @@ static int imx_ssi_probe(struct platform_device *pdev)
        dai->private_data = ssi;
 
        if ((cpu_is_mx27() || cpu_is_mx21()) &&
-                       !(ssi->flags & IMX_SSI_USE_AC97)) {
+                       !(ssi->flags & IMX_SSI_USE_AC97) &&
+                       (ssi->flags & IMX_SSI_DMA)) {
                ssi->flags |= IMX_SSI_DMA;
                platform = imx_ssi_dma_mx2_init(pdev, ssi);
        } else
index 2c59afd..9e28b20 100644 (file)
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
        DEFINE_WAIT(wait);
        long timeout = msecs_to_jiffies(50);
 
+       if (ep->umidi->disconnected)
+               return;
        /*
         * The substream buffer is empty, but some data might still be in the
         * currently active URBs, so we have to wait for those to complete.
@@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
  * Frees an output endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
+static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
 {
        unsigned int i;
 
        for (i = 0; i < OUTPUT_URBS; ++i)
-               if (ep->urbs[i].urb)
+               if (ep->urbs[i].urb) {
                        free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
                                            ep->max_transfer);
+                       ep->urbs[i].urb = NULL;
+               }
+}
+
+static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
+{
+       snd_usbmidi_out_endpoint_clear(ep);
        kfree(ep);
 }
 
@@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
                                usb_kill_urb(ep->out->urbs[j].urb);
                        if (umidi->usb_protocol_ops->finish_out_endpoint)
                                umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
+                       ep->out->active_urbs = 0;
+                       if (ep->out->drain_urbs) {
+                               ep->out->drain_urbs = 0;
+                               wake_up(&ep->out->drain_wait);
+                       }
                }
                if (ep->in)
                        for (j = 0; j < INPUT_URBS; ++j)
                                usb_kill_urb(ep->in->urbs[j]);
                /* free endpoints here; later call can result in Oops */
-               if (ep->out) {
-                       snd_usbmidi_out_endpoint_delete(ep->out);
-                       ep->out = NULL;
-               }
+               if (ep->out)
+                       snd_usbmidi_out_endpoint_clear(ep->out);
                if (ep->in) {
                        snd_usbmidi_in_endpoint_delete(ep->in);
                        ep->in = NULL;
index 5a0cd19..c82ae24 100644 (file)
@@ -341,7 +341,11 @@ static void kvm_mmu_notifier_release(struct mmu_notifier *mn,
                                     struct mm_struct *mm)
 {
        struct kvm *kvm = mmu_notifier_to_kvm(mn);
+       int idx;
+
+       idx = srcu_read_lock(&kvm->srcu);
        kvm_arch_flush_shadow(kvm);
+       srcu_read_unlock(&kvm->srcu, idx);
 }
 
 static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
@@ -648,7 +652,7 @@ skip_lpage:
 
        /* Allocate page dirty bitmap if needed */
        if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
-               unsigned dirty_bytes = ALIGN(npages, BITS_PER_LONG) / 8;
+               unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
 
                new.dirty_bitmap = vmalloc(dirty_bytes);
                if (!new.dirty_bitmap)
@@ -768,7 +772,7 @@ int kvm_get_dirty_log(struct kvm *kvm,
 {
        struct kvm_memory_slot *memslot;
        int r, i;
-       int n;
+       unsigned long n;
        unsigned long any = 0;
 
        r = -EINVAL;
@@ -780,7 +784,7 @@ int kvm_get_dirty_log(struct kvm *kvm,
        if (!memslot->dirty_bitmap)
                goto out;
 
-       n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
+       n = kvm_dirty_bitmap_bytes(memslot);
 
        for (i = 0; !any && i < n/sizeof(long); ++i)
                any = memslot->dirty_bitmap[i];
@@ -1186,10 +1190,13 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
        memslot = gfn_to_memslot_unaliased(kvm, gfn);
        if (memslot && memslot->dirty_bitmap) {
                unsigned long rel_gfn = gfn - memslot->base_gfn;
+               unsigned long *p = memslot->dirty_bitmap +
+                                       rel_gfn / BITS_PER_LONG;
+               int offset = rel_gfn % BITS_PER_LONG;
 
                /* avoid RMW */
-               if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap))
-                       generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+               if (!generic_test_le_bit(offset, p))
+                       generic___set_le_bit(offset, p);
        }
 }