]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Jul 2008 01:58:56 +0000 (18:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Jul 2008 01:58:56 +0000 (18:58 -0700)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: fix NODES_SHIFT Kconfig range

277 files changed:
.gitignore
Documentation/DocBook/kgdb.tmpl
Documentation/cpusets.txt
Documentation/feature-removal-schedule.txt
Documentation/hwmon/sysfs-interface
Documentation/networking/ip-sysctl.txt
Documentation/networking/s2io.txt
Documentation/video4linux/CARDLIST.au0828
MAINTAINERS
Makefile
arch/alpha/Makefile
arch/alpha/kernel/core_t2.c
arch/alpha/kernel/pci.c
arch/alpha/kernel/traps.c
arch/blackfin/kernel/cplb-nompu/cplbinit.c
arch/blackfin/kernel/irqchip.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/setup.c
arch/ia64/sn/kernel/sn2/sn2_smp.c
arch/powerpc/boot/Makefile
arch/powerpc/kernel/legacy_serial.c
arch/powerpc/kernel/vdso.c
arch/powerpc/platforms/52xx/lite5200_pm.c
arch/x86/Kconfig
arch/x86/kernel/Makefile
arch/x86/kernel/kvmclock.c
arch/x86/kernel/pvclock.c [new file with mode: 0644]
arch/x86/kvm/i8254.c
arch/x86/kvm/lapic.c
arch/x86/kvm/mmu.c
arch/x86/kvm/vmx.c
arch/x86/kvm/x86.c
arch/x86/xen/Kconfig
arch/x86/xen/time.c
drivers/acpi/ac.c
drivers/acpi/bay.c
drivers/acpi/dock.c
drivers/acpi/glue.c
drivers/acpi/video.c
drivers/ata/Kconfig
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/libata.h
drivers/ata/pata_pcmcia.c
drivers/ata/sata_mv.c
drivers/char/agp/intel-agp.c
drivers/char/drm/ati_pcigart.c
drivers/char/drm/drm.h
drivers/char/drm/drm_drv.c
drivers/char/drm/drm_pciids.h
drivers/char/drm/i915_drv.c
drivers/char/drm/i915_drv.h
drivers/char/drm/i915_irq.c
drivers/char/drm/r300_cmdbuf.c
drivers/char/drm/r300_reg.h
drivers/char/drm/radeon_cp.c
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_irq.c
drivers/char/drm/radeon_microcode.h [new file with mode: 0644]
drivers/char/drm/radeon_state.c
drivers/char/tty_ioctl.c
drivers/connector/connector.c
drivers/firewire/Kconfig
drivers/firewire/fw-cdev.c
drivers/firewire/fw-ohci.c
drivers/firewire/fw-sbp2.c
drivers/firewire/fw-transaction.c
drivers/hwmon/abituguru3.c
drivers/hwmon/adt7473.c
drivers/hwmon/lm75.c
drivers/hwmon/lm85.c
drivers/ide/Kconfig
drivers/ide/arm/Makefile
drivers/ide/arm/bast-ide.c [deleted file]
drivers/ide/arm/palm_bk3710.c
drivers/ide/ide-taskfile.c
drivers/ide/legacy/ide-cs.c
drivers/ieee1394/Kconfig
drivers/infiniband/hw/mthca/mthca_memfree.c
drivers/input/ff-core.c
drivers/md/dm-crypt.c
drivers/md/md.c
drivers/md/raid10.c
drivers/md/raid5.c
drivers/media/common/ir-keymaps.c
drivers/media/common/tuners/tda18271-common.c
drivers/media/common/tuners/tda18271-fe.c
drivers/media/common/tuners/xc5000.c
drivers/media/common/tuners/xc5000_priv.h
drivers/media/dvb/dvb-usb/gl861.c
drivers/media/dvb/dvb-usb/umt-010.c
drivers/media/dvb/frontends/au8522.c
drivers/media/dvb/frontends/stv0299.c
drivers/media/dvb/frontends/tda10023.c
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/ttpci/Kconfig
drivers/media/dvb/ttpci/av7110_hw.c
drivers/media/video/au0828/au0828-cards.c
drivers/media/video/cx18/Kconfig
drivers/media/video/cx18/cx18-av-core.c
drivers/media/video/cx18/cx18-av-core.h
drivers/media/video/cx18/cx18-cards.c
drivers/media/video/cx18/cx18-cards.h
drivers/media/video/cx18/cx18-dvb.c
drivers/media/video/cx18/cx18-gpio.c
drivers/media/video/cx18/cx18-gpio.h
drivers/media/video/cx18/cx18-i2c.c
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx88/cx88-alsa.c
drivers/media/video/em28xx/em28xx-audio.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-dvb.c
drivers/media/video/em28xx/em28xx-reg.h
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/pxa_camera.c
drivers/media/video/saa7134/saa7134-alsa.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/soc_camera.c
drivers/media/video/videodev.c
drivers/media/video/vivi.c
drivers/net/3c59x.c
drivers/net/e100.c
drivers/net/e1000/e1000_ethtool.c
drivers/net/e1000e/netdev.c
drivers/net/hamradio/dmascc.c
drivers/net/igb/igb_main.c
drivers/net/ipg.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pppoe.c
drivers/net/qla3xxx.c
drivers/net/r6040.c
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/tc35815.c
drivers/net/wan/x25_asy.c
drivers/net/wireless/b43/leds.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_main.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/prism54/islpci_eth.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/scsi/esp_scsi.c
drivers/scsi/ses.c
drivers/serial/bfin_5xx.c
drivers/thermal/Kconfig
drivers/thermal/thermal_sys.c
drivers/watchdog/Makefile
drivers/watchdog/hpwdt.c
fs/block_dev.c
fs/dcache.c
fs/ext4/resize.c
fs/gfs2/bmap.c
fs/gfs2/rgrp.c
fs/locks.c
fs/namei.c
fs/nfs/mount_clnt.c
fs/nfs/super.c
fs/nfs/write.c
fs/pipe.c
fs/select.c
fs/udf/super.c
fs/utimes.c
include/asm-alpha/core_mcpcia.h
include/asm-alpha/core_t2.h
include/asm-alpha/io.h
include/asm-alpha/mmu_context.h
include/asm-alpha/percpu.h
include/asm-alpha/system.h
include/asm-alpha/vga.h
include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
include/asm-blackfin/mach-bf533/bfin_serial_5xx.h
include/asm-blackfin/mach-bf537/bfin_serial_5xx.h
include/asm-blackfin/mach-bf548/bfin_serial_5xx.h
include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
include/asm-generic/Kbuild.asm
include/asm-powerpc/Kbuild
include/asm-x86/kvm_host.h
include/asm-x86/kvm_para.h
include/asm-x86/pvclock-abi.h [new file with mode: 0644]
include/asm-x86/pvclock.h [new file with mode: 0644]
include/linux/Kbuild
include/linux/audit.h
include/linux/bootmem.h
include/linux/dcache.h
include/linux/fs.h
include/linux/inet_lro.h
include/linux/input.h
include/linux/kvm_host.h
include/linux/netdevice.h
include/linux/thermal.h
include/linux/tty_driver.h
include/media/cx25840.h
include/media/ir-common.h
include/media/v4l2-dev.h
include/net/ipv6.h
include/net/mac80211.h
include/net/net_namespace.h
include/net/sch_generic.h
include/xen/interface/xen.h
kernel/audit.c
kernel/auditfilter.c
kernel/cpuset.c
kernel/futex.c
kernel/kgdb.c
kernel/rcupreempt.c
kernel/sched.c
kernel/sched_rt.c
kernel/sched_stats.h
kernel/softlockup.c
lib/debugobjects.c
lib/ts_bm.c
mm/bootmem.c
mm/memory.c
mm/migrate.c
mm/slab.c
net/core/dev.c
net/core/fib_rules.c
net/core/filter.c
net/core/net_namespace.c
net/core/skbuff.c
net/ipv4/inet_fragment.c
net/ipv4/inet_lro.c
net/ipv4/ip_fragment.c
net/ipv4/tcp.c
net/ipv4/tcp_ipv4.c
net/ipv6/ip6_input.c
net/ipv6/ipv6_sockglue.c
net/ipv6/netfilter/ip6table_mangle.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/mac80211/key.c
net/mac80211/tx.c
net/mac80211/wext.c
net/mac80211/wme.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netlabel/netlabel_unlabeled.c
net/netlink/af_netlink.c
net/netlink/attr.c
net/sched/Kconfig
net/sched/sch_api.c
net/sched/sch_atm.c
net/sched/sch_cbq.c
net/sched/sch_dsmark.c
net/sched/sch_generic.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_ingress.c
net/sched/sch_prio.c
net/sched/sch_sfq.c
net/sctp/socket.c
net/unix/af_unix.c
net/wireless/reg.c
sound/isa/sb/sb_mixer.c
sound/pci/aw2/aw2-alsa.c
virt/kvm/ioapic.c

index 9bb1cb6d825d540bc92dfe5c34343438b860b009..869e1a3b64b6bf969eeced820691e955e03e3068 100644 (file)
@@ -3,6 +3,10 @@
 # subdirectories here. Add them in the ".gitignore" file
 # in that subdirectory instead.
 #
+# NOTE! Please use 'git-ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
 # Normal rules
 #
 .*
 *.lst
 *.symtypes
 *.order
+*.elf
+*.bin
+*.gz
 
 #
 # Top-level generic files
 #
 tags
 TAGS
-vmlinux*
-!vmlinux.lds.S
-!vmlinux.lds.h
+vmlinux
 System.map
 Module.markers
 Module.symvers
 !.gitignore
+!.mailmap
 
 #
 # Generated include files
index 028a8444d95e252a4c0830b70eb6b71311509660..e8acd1f034567b217f9e9998f5bc05b4c24e276e 100644 (file)
     runs an instance of gdb against the vmlinux file which contains
     the symbols (not boot image such as bzImage, zImage, uImage...).
     In gdb the developer specifies the connection parameters and
-    connects to kgdb.  Depending on which kgdb I/O modules exist in
-    the kernel for a given architecture, it may be possible to debug
-    the test machine's kernel with the development machine using a
-    rs232 or ethernet connection.
+    connects to kgdb.  The type of connection a developer makes with
+    gdb depends on the availability of kgdb I/O modules compiled as
+    builtin's or kernel modules in the test machine's kernel.
     </para>
   </chapter>
   <chapter id="CompilingAKernel">
   </para>
   <para>
   IMPORTANT NOTE: Using this option with kgdb over the console
-  (kgdboc) or kgdb over ethernet (kgdboe) is not supported.
+  (kgdboc) is not supported.
   </para>
   </sect1>
   </chapter>
     (gdb) target remote /dev/ttyS0
     </programlisting>
     <para>
-    Example (kgdb to a terminal server):
+    Example (kgdb to a terminal server on tcp port 2012):
     </para>
     <programlisting>
     % gdb ./vmlinux
-    (gdb) target remote udp:192.168.2.2:6443
-    </programlisting>
-    <para>
-    Example (kgdb over ethernet):
-    </para>
-    <programlisting>
-    % gdb ./vmlinux
-    (gdb) target remote udp:192.168.2.2:6443
+    (gdb) target remote 192.168.2.2:2012
     </programlisting>
     <para>
     Once connected, you can debug a kernel the way you would debug an
index d803c5c68ab5e981d3f101b00489ca32c6930681..353504de3084a645931788b6bd4d7e529428562e 100644 (file)
@@ -542,7 +542,7 @@ otherwise initial value -1 that indicates the cpuset has no request.
    2  : search cores in a package.
    3  : search cpus in a node [= system wide on non-NUMA system]
  ( 4  : search nodes in a chunk of node [on NUMA system] )
- ( 5~ : search system wide [on NUMA system])
+ ( 5  : search system wide [on NUMA system] )
 
 This file is per-cpuset and affect the sched domain where the cpuset
 belongs to.  Therefore if the flag 'sched_load_balance' of a cpuset
index 5b3f31faed56872b84fbd293494613f6d627a987..46ece3fba6f94c2924c94d6f96b4402984705102 100644 (file)
@@ -312,3 +312,12 @@ When:      2.6.26
 Why:   Implementation became generic; users should now include
        linux/semaphore.h instead.
 Who:   Matthew Wilcox <willy@linux.intel.com>
+
+---------------------------
+
+What:  CONFIG_THERMAL_HWMON
+When:  January 2009
+Why:   This option was introduced just to allow older lm-sensors userspace
+       to keep working over the upgrade to 2.6.26. At the scheduled time of
+       removal fixed lm-sensors (2.x or 3.x) should be readily available.
+Who:   Rene Herman <rene.herman@gmail.com>
index f4a8ebc1ef1acc11ae4bdd22c9299f4b84467c73..2d845730d4e0e81c65ff5ceb5299a79724daf62f 100644 (file)
@@ -2,17 +2,12 @@ Naming and data format standards for sysfs files
 ------------------------------------------------
 
 The libsensors library offers an interface to the raw sensors data
-through the sysfs interface. See libsensors documentation and source for
-further information. As of writing this document, libsensors
-(from lm_sensors 2.8.3) is heavily chip-dependent. Adding or updating
-support for any given chip requires modifying the library's code.
-This is because libsensors was written for the procfs interface
-older kernel modules were using, which wasn't standardized enough.
-Recent versions of libsensors (from lm_sensors 2.8.2 and later) have
-support for the sysfs interface, though.
-
-The new sysfs interface was designed to be as chip-independent as
-possible.
+through the sysfs interface. Since lm-sensors 3.0.0, libsensors is
+completely chip-independent. It assumes that all the kernel drivers
+implement the standard sysfs interface described in this document.
+This makes adding or updating support for any given chip very easy, as
+libsensors, and applications using it, do not need to be modified.
+This is a major improvement compared to lm-sensors 2.
 
 Note that motherboards vary widely in the connections to sensor chips.
 There is no standard that ensures, for example, that the second
@@ -35,19 +30,17 @@ access this data in a simple and consistent way. That said, such programs
 will have to implement conversion, labeling and hiding of inputs. For
 this reason, it is still not recommended to bypass the library.
 
-If you are developing a userspace application please send us feedback on
-this standard.
-
-Note that this standard isn't completely established yet, so it is subject
-to changes. If you are writing a new hardware monitoring driver those
-features can't seem to fit in this interface, please contact us with your
-extension proposal. Keep in mind that backward compatibility must be
-preserved.
-
 Each chip gets its own directory in the sysfs /sys/devices tree.  To
 find all sensor chips, it is easier to follow the device symlinks from
 /sys/class/hwmon/hwmon*.
 
+Up to lm-sensors 3.0.0, libsensors looks for hardware monitoring attributes
+in the "physical" device directory. Since lm-sensors 3.0.1, attributes found
+in the hwmon "class" device directory are also supported. Complex drivers
+(e.g. drivers for multifunction chips) may want to use this possibility to
+avoid namespace pollution. The only drawback will be that older versions of
+libsensors won't support the driver in question.
+
 All sysfs values are fixed point numbers.
 
 There is only one value per file, unlike the older /proc specification.
index 17a6e46fbd43abfce8ad5558f99200f8389ac650..17f1f91af35c7db3e80fed84c5833c80bc48526b 100644 (file)
@@ -81,23 +81,23 @@ inet_peer_minttl - INTEGER
        Minimum time-to-live of entries.  Should be enough to cover fragment
        time-to-live on the reassembling side.  This minimum time-to-live  is
        guaranteed if the pool size is less than inet_peer_threshold.
-       Measured in jiffies(1).
+       Measured in seconds.
 
 inet_peer_maxttl - INTEGER
        Maximum time-to-live of entries.  Unused entries will expire after
        this period of time if there is no memory pressure on the pool (i.e.
        when the number of entries in the pool is very small).
-       Measured in jiffies(1).
+       Measured in seconds.
 
 inet_peer_gc_mintime - INTEGER
        Minimum interval between garbage collection passes.  This interval is
        in effect under high memory pressure on the pool.
-       Measured in jiffies(1).
+       Measured in seconds.
 
 inet_peer_gc_maxtime - INTEGER
        Minimum interval between garbage collection passes.  This interval is
        in effect under low (or absent) memory pressure on the pool.
-       Measured in jiffies(1).
+       Measured in seconds.
 
 TCP variables: 
 
@@ -794,10 +794,6 @@ tag - INTEGER
        Allows you to write a number, which can be used as required.
        Default value is 0.
 
-(1) Jiffie: internal timeunit for the kernel. On the i386 1/100s, on the
-Alpha 1/1024s. See the HZ define in /usr/include/asm/param.h for the exact
-value on your system. 
-
 Alexey Kuznetsov.
 kuznet@ms2.inr.ac.ru
 
index 4bde53e85f3f02df27191234af82b3ba06b9f7a5..1e28e2ddb90a6e202ce65bd60778ff701afa8ee1 100644 (file)
@@ -83,9 +83,9 @@ Valid range: Limited by memory on system
 Default: 30 
 
 e. intr_type
-Specifies interrupt type. Possible values 1(INTA), 2(MSI), 3(MSI-X)
-Valid range: 1-3
-Default: 
+Specifies interrupt type. Possible values 0(INTA), 2(MSI-X)
+Valid values: 0, 2
+Default: 2
 
 5.  Performance suggestions
 General:
index aaae360312e479a547d583c8c1d172d3106fa48d..86d1c8e7b18f3c31b39dca8176acc3e9bdfdf96a 100644 (file)
@@ -1,4 +1,4 @@
   0 -> Unknown board                            (au0828)
-  1 -> Hauppauge HVR950Q                        (au0828)        [2040:7200]
+  1 -> Hauppauge HVR950Q                        (au0828)        [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
   2 -> Hauppauge HVR850                         (au0828)        [2040:7240]
   3 -> DViCO FusionHDTV USB                     (au0828)        [0fe9:d620]
index cd587eec9fa7558775571410fdcb01154f32d22a..8f0ec46a7096132683b5ba7368c239c6519f127d 100644 (file)
@@ -4431,10 +4431,10 @@ M:      johnpol@2ka.mipt.ru
 S:     Maintained
 
 W83791D HARDWARE MONITORING DRIVER
-P:     Charles Spirakis
-M:     bezaur@gmail.com
+P:     Marc Hulsman
+M:     m.hulsman@tudelft.nl
 L:     lm-sensors@lm-sensors.org
-S:     Odd Fixes
+S:     Maintained
 
 W83793 HARDWARE MONITORING DRIVER
 P:     Rudolf Marek
index 6923d669a4f6c01505d1158f868bd562e907774c..6aff5f47c21d1f13c633de4f14835688c49244db 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 26
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc8
 NAME = Rotary Wombat
 
 # *DOCUMENTATION*
index 4e1a8e2c45410746b0b8176c6356068f433a8be2..4759fe751aa1ba1b21ea99b99ae2c9487627e326 100644 (file)
@@ -13,6 +13,7 @@ NM := $(NM) -B
 LDFLAGS_vmlinux        := -static -N #-relax
 CHECKFLAGS     += -D__alpha__ -m64
 cflags-y       := -pipe -mno-fp-regs -ffixed-8 -msmall-data
+cflags-y       += $(call cc-option, -fno-jump-tables)
 
 cpuflags-$(CONFIG_ALPHA_EV4)           := -mcpu=ev4
 cpuflags-$(CONFIG_ALPHA_EV5)           := -mcpu=ev5
index c0750291b44ad54a885fd3395f0811dc254ea44e..d9980d47ab81adbcdd0bfb0d4ca80dc2a04cf22e 100644 (file)
@@ -74,6 +74,8 @@
 # define DBG(args)
 #endif
 
+DEFINE_SPINLOCK(t2_hae_lock);
+
 static volatile unsigned int t2_mcheck_any_expected;
 static volatile unsigned int t2_mcheck_last_taken;
 
index 36ab22a7ea124920f7f0cf8617deacf6906623a9..5cf45fc5134315bdc930d1a36dad08e4dc4c6dac 100644 (file)
@@ -71,6 +71,23 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378, quirk_i
 static void __init
 quirk_cypress(struct pci_dev *dev)
 {
+       /* The Notorious Cy82C693 chip.  */
+
+       /* The generic legacy mode IDE fixup in drivers/pci/probe.c
+          doesn't work correctly with the Cypress IDE controller as
+          it has non-standard register layout.  Fix that.  */
+       if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
+               dev->resource[2].start = dev->resource[3].start = 0;
+               dev->resource[2].end = dev->resource[3].end = 0;
+               dev->resource[2].flags = dev->resource[3].flags = 0;
+               if (PCI_FUNC(dev->devfn) == 2) {
+                       dev->resource[0].start = 0x170;
+                       dev->resource[0].end = 0x177;
+                       dev->resource[1].start = 0x376;
+                       dev->resource[1].end = 0x376;
+               }
+       }
+
        /* The Cypress bridge responds on the PCI bus in the address range
           0xffff0000-0xffffffff (conventional x86 BIOS ROM).  There is no
           way to turn this off.  The bridge also supports several extended
index dc57790250d2a26484bd25e2be0dca496e3217e8..c778779007fc58339abb11bc7f42f1299d5d65c1 100644 (file)
@@ -447,7 +447,7 @@ struct unaligned_stat {
 
 
 /* Macro for exception fixup code to access integer registers.  */
-#define una_reg(r)  (regs->regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
+#define una_reg(r)  (_regs[(r) >= 16 && (r) <= 18 ? (r)+19 : (r)])
 
 
 asmlinkage void
@@ -456,6 +456,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg,
 {
        long error, tmp1, tmp2, tmp3, tmp4;
        unsigned long pc = regs->pc - 4;
+       unsigned long *_regs = regs->regs;
        const struct exception_table_entry *fixup;
 
        unaligned[0].count++;
index 917325bfbd849723899d6bfaa26e21c39d566ed8..6be0c50122e8c627102fbcbe5692cc26013b0135 100644 (file)
@@ -254,7 +254,8 @@ close_cplbtab(struct cplb_tab *table)
 }
 
 /* helper function */
-static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+static void __init
+__fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
 {
        if (cplb_data[i].psize) {
                fill_cplbtab(t,
@@ -291,7 +292,8 @@ static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_en
        }
 }
 
-static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
+static void __init
+__fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
 {
        if (cplb_data[i].psize) {
                fill_cplbtab(t,
index 73647c158774e0acd31efcf3e7385dd2b104365a..07402f57c9dea2f401bb40110f92dc57e5601281 100644 (file)
@@ -60,9 +60,14 @@ static struct irq_chip bad_chip = {
 };
 
 static struct irq_desc bad_irq_desc = {
+       .status = IRQ_DISABLED,
        .chip = &bad_chip,
        .handle_irq = handle_bad_irq,
        .depth = 1,
+       .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
+#ifdef CONFIG_SMP
+       .affinity = CPU_MASK_ALL
+#endif
 };
 
 int show_interrupts(struct seq_file *p, void *v)
index 082c31dcfd998d83448d52559161805ca240be49..39752cdef6ffd342210c237f60aa7c32782cbd87 100644 (file)
@@ -558,8 +558,6 @@ static struct iosapic_rte_info * __init_refok iosapic_alloc_rte (void)
        if (!iosapic_kmalloc_ok && list_empty(&free_rte_list)) {
                rte = alloc_bootmem(sizeof(struct iosapic_rte_info) *
                                    NR_PREALLOCATE_RTE_ENTRIES);
-               if (!rte)
-                       return NULL;
                for (i = 0; i < NR_PREALLOCATE_RTE_ENTRIES; i++, rte++)
                        list_add(&rte->rte_list, &free_rte_list);
        }
index f48a809c686d899be2d431a96487e292329dc9c8..4ae15c8c2488fa8741086943ea58ee915bfbf69a 100644 (file)
@@ -578,8 +578,6 @@ setup_arch (char **cmdline_p)
        cpu_init();     /* initialize the bootstrap CPU */
        mmu_context_init();     /* initialize context_id bitmap */
 
-       check_sal_cache_flush();
-
 #ifdef CONFIG_ACPI
        acpi_boot_init();
 #endif
@@ -607,6 +605,7 @@ setup_arch (char **cmdline_p)
                ia64_mca_init();
 
        platform_setup(cmdline_p);
+       check_sal_cache_flush();
        paging_init();
 }
 
index 49d3120415eb740154a5469be144e51598775d04..e585f9a2afb936c74f9ec0ceea13beb1ef7271c4 100644 (file)
@@ -512,6 +512,8 @@ static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, si
        int cpu;
        char optstr[64];
 
+       if (count == 0 || count > sizeof(optstr))
+               return -EINVAL;
        if (copy_from_user(optstr, user, count))
                return -EFAULT;
        optstr[count - 1] = '\0';
index 1cee2f9fdf06bb0255d182ddb40bede780b88c6f..095e04db1c0e1f75e39cbd01c6419c8b890295c2 100644 (file)
@@ -273,7 +273,8 @@ endif
 initrd-  := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-))
 initrd-y := $(patsubst zImage%, zImage.initrd%, \
                $(patsubst dtbImage%, dtbImage.initrd%, \
-               $(patsubst treeImage%, treeImage.initrd%, $(image-y))))
+               $(patsubst simpleImage%, simpleImage.initrd%, \
+               $(patsubst treeImage%, treeImage.initrd%, $(image-y)))))
 initrd-y := $(filter-out $(image-y), $(initrd-y))
 targets        += $(image-y) $(initrd-y)
 
index 61dd17449ddceb06267babf5373505984f7abd9c..cf37f5ca4b71e6b30c2a3d7bb46fb17f8bf66f50 100644 (file)
@@ -136,6 +136,11 @@ static int __init add_legacy_soc_port(struct device_node *np,
        if (of_get_property(np, "clock-frequency", NULL) == NULL)
                return -1;
 
+       /* if reg-shift or offset, don't try to use it */
+       if ((of_get_property(np, "reg-shift", NULL) != NULL) ||
+               (of_get_property(np, "reg-offset", NULL) != NULL))
+               return -1;
+
        /* if rtas uses this device, don't try to use it as well */
        if (of_get_property(np, "used-by-rtas", NULL) != NULL)
                return -1;
index c21a626af676fde938922c25e110c203e892a24f..ce245a850db2b8d90d0d35dcd98a2e1fa39d97b7 100644 (file)
@@ -142,7 +142,7 @@ static void dump_one_vdso_page(struct page *pg, struct page *upg)
        printk("kpg: %p (c:%d,f:%08lx)", __va(page_to_pfn(pg) << PAGE_SHIFT),
               page_count(pg),
               pg->flags);
-       if (upg/* && pg != upg*/) {
+       if (upg && !IS_ERR(upg) /* && pg != upg*/) {
                printk(" upg: %p (c:%d,f:%08lx)", __va(page_to_pfn(upg)
                                                       << PAGE_SHIFT),
                       page_count(upg),
index 41c7fd91e99e5836cbaef5c7d6803334bc37a206..fe92e65103edad4851465f0a00b4615011c76676 100644 (file)
@@ -14,6 +14,7 @@ static struct mpc52xx_sdma __iomem *bes;
 static struct mpc52xx_xlb __iomem *xlb;
 static struct mpc52xx_gpio __iomem *gps;
 static struct mpc52xx_gpio_wkup __iomem *gpw;
+static void __iomem *pci;
 static void __iomem *sram;
 static const int sram_size = 0x4000;   /* 16 kBytes */
 static void __iomem *mbar;
@@ -50,6 +51,8 @@ static int lite5200_pm_prepare(void)
                { .type = "builtin", .compatible = "mpc5200", }, /* efika */
                {}
        };
+       u64 regaddr64 = 0;
+       const u32 *regaddr_p;
 
        /* deep sleep? let mpc52xx code handle that */
        if (lite5200_pm_target_state == PM_SUSPEND_STANDBY)
@@ -60,8 +63,12 @@ static int lite5200_pm_prepare(void)
 
        /* map registers */
        np = of_find_matching_node(NULL, immr_ids);
-       mbar = of_iomap(np, 0);
+       regaddr_p = of_get_address(np, 0, NULL, NULL);
+       if (regaddr_p)
+               regaddr64 = of_translate_address(np, regaddr_p);
        of_node_put(np);
+
+       mbar = ioremap((u32) regaddr64, 0xC000);
        if (!mbar) {
                printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__);
                return -ENOSYS;
@@ -71,6 +78,7 @@ static int lite5200_pm_prepare(void)
        pic = mbar + 0x500;
        gps = mbar + 0xb00;
        gpw = mbar + 0xc00;
+       pci = mbar + 0xd00;
        bes = mbar + 0x1200;
        xlb = mbar + 0x1f00;
        sram = mbar + 0x8000;
@@ -85,6 +93,7 @@ static struct mpc52xx_sdma sbes;
 static struct mpc52xx_xlb sxlb;
 static struct mpc52xx_gpio sgps;
 static struct mpc52xx_gpio_wkup sgpw;
+static char spci[0x200];
 
 static void lite5200_save_regs(void)
 {
@@ -94,6 +103,7 @@ static void lite5200_save_regs(void)
        _memcpy_fromio(&sxlb, xlb, sizeof(*xlb));
        _memcpy_fromio(&sgps, gps, sizeof(*gps));
        _memcpy_fromio(&sgpw, gpw, sizeof(*gpw));
+       _memcpy_fromio(spci, pci, 0x200);
 
        _memcpy_fromio(saved_sram, sram, sram_size);
 }
@@ -103,6 +113,8 @@ static void lite5200_restore_regs(void)
        int i;
        _memcpy_toio(sram, saved_sram, sram_size);
 
+       /* PCI Configuration */
+       _memcpy_toio(pci, spci, 0x200);
 
        /*
         * GPIOs. Interrupt Master Enable has higher address then other
index 8a07f417f5f479ad01a7e8d03fc21e607a57c193..bf07b6f50fa178268f9d81388a615a7a8abff32b 100644 (file)
@@ -383,6 +383,7 @@ config VMI
 config KVM_CLOCK
        bool "KVM paravirtualized clock"
        select PARAVIRT
+       select PARAVIRT_CLOCK
        depends on !(X86_VISWS || X86_VOYAGER)
        help
          Turning on this option will allow you to run a paravirtualized clock
@@ -410,6 +411,10 @@ config PARAVIRT
          over full virtualization.  However, when run without a hypervisor
          the kernel is theoretically slower and slightly larger.
 
+config PARAVIRT_CLOCK
+       bool
+       default n
+
 endif
 
 config MEMTEST_BOOTPARAM
index 5e618c3b47208ed2f301c685a5596135b30cc78f..77807d4769c99c455237a810fe0edd0f996fb31f 100644 (file)
@@ -82,6 +82,7 @@ obj-$(CONFIG_VMI)             += vmi_32.o vmiclock_32.o
 obj-$(CONFIG_KVM_GUEST)                += kvm.o
 obj-$(CONFIG_KVM_CLOCK)                += kvmclock.o
 obj-$(CONFIG_PARAVIRT)         += paravirt.o paravirt_patch_$(BITS).o
+obj-$(CONFIG_PARAVIRT_CLOCK)   += pvclock.o
 
 obj-$(CONFIG_PCSPKR_PLATFORM)  += pcspeaker.o
 
index 08a30986d4725f25ebc316b196884dd8f5aac9d7..87edf1ceb1df32c3afd62d1de44801c286922f7e 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <linux/clocksource.h>
 #include <linux/kvm_para.h>
+#include <asm/pvclock.h>
 #include <asm/arch_hooks.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
@@ -36,18 +37,9 @@ static int parse_no_kvmclock(char *arg)
 early_param("no-kvmclock", parse_no_kvmclock);
 
 /* The hypervisor will put information about time periodically here */
-static DEFINE_PER_CPU_SHARED_ALIGNED(struct kvm_vcpu_time_info, hv_clock);
-#define get_clock(cpu, field) per_cpu(hv_clock, cpu).field
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct pvclock_vcpu_time_info, hv_clock);
+static struct pvclock_wall_clock wall_clock;
 
-static inline u64 kvm_get_delta(u64 last_tsc)
-{
-       int cpu = smp_processor_id();
-       u64 delta = native_read_tsc() - last_tsc;
-       return (delta * get_clock(cpu, tsc_to_system_mul)) >> KVM_SCALE;
-}
-
-static struct kvm_wall_clock wall_clock;
-static cycle_t kvm_clock_read(void);
 /*
  * The wallclock is the time of day when we booted. Since then, some time may
  * have elapsed since the hypervisor wrote the data. So we try to account for
@@ -55,64 +47,37 @@ static cycle_t kvm_clock_read(void);
  */
 static unsigned long kvm_get_wallclock(void)
 {
-       u32 wc_sec, wc_nsec;
-       u64 delta;
+       struct pvclock_vcpu_time_info *vcpu_time;
        struct timespec ts;
-       int version, nsec;
        int low, high;
 
        low = (int)__pa(&wall_clock);
        high = ((u64)__pa(&wall_clock) >> 32);
+       native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
 
-       delta = kvm_clock_read();
+       vcpu_time = &get_cpu_var(hv_clock);
+       pvclock_read_wallclock(&wall_clock, vcpu_time, &ts);
+       put_cpu_var(hv_clock);
 
-       native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
-       do {
-               version = wall_clock.wc_version;
-               rmb();
-               wc_sec = wall_clock.wc_sec;
-               wc_nsec = wall_clock.wc_nsec;
-               rmb();
-       } while ((wall_clock.wc_version != version) || (version & 1));
-
-       delta = kvm_clock_read() - delta;
-       delta += wc_nsec;
-       nsec = do_div(delta, NSEC_PER_SEC);
-       set_normalized_timespec(&ts, wc_sec + delta, nsec);
-       /*
-        * Of all mechanisms of time adjustment I've tested, this one
-        * was the champion!
-        */
-       return ts.tv_sec + 1;
+       return ts.tv_sec;
 }
 
 static int kvm_set_wallclock(unsigned long now)
 {
-       return 0;
+       return -1;
 }
 
-/*
- * This is our read_clock function. The host puts an tsc timestamp each time
- * it updates a new time. Without the tsc adjustment, we can have a situation
- * in which a vcpu starts to run earlier (smaller system_time), but probes
- * time later (compared to another vcpu), leading to backwards time
- */
 static cycle_t kvm_clock_read(void)
 {
-       u64 last_tsc, now;
-       int cpu;
+       struct pvclock_vcpu_time_info *src;
+       cycle_t ret;
 
-       preempt_disable();
-       cpu = smp_processor_id();
-
-       last_tsc = get_clock(cpu, tsc_timestamp);
-       now = get_clock(cpu, system_time);
-
-       now += kvm_get_delta(last_tsc);
-       preempt_enable();
-
-       return now;
+       src = &get_cpu_var(hv_clock);
+       ret = pvclock_clocksource_read(src);
+       put_cpu_var(hv_clock);
+       return ret;
 }
+
 static struct clocksource kvm_clock = {
        .name = "kvm-clock",
        .read = kvm_clock_read,
@@ -123,13 +88,14 @@ static struct clocksource kvm_clock = {
        .flags = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
-static int kvm_register_clock(void)
+static int kvm_register_clock(char *txt)
 {
        int cpu = smp_processor_id();
        int low, high;
        low = (int)__pa(&per_cpu(hv_clock, cpu)) | 1;
        high = ((u64)__pa(&per_cpu(hv_clock, cpu)) >> 32);
-
+       printk(KERN_INFO "kvm-clock: cpu %d, msr %x:%x, %s\n",
+              cpu, high, low, txt);
        return native_write_msr_safe(MSR_KVM_SYSTEM_TIME, low, high);
 }
 
@@ -140,12 +106,20 @@ static void kvm_setup_secondary_clock(void)
         * Now that the first cpu already had this clocksource initialized,
         * we shouldn't fail.
         */
-       WARN_ON(kvm_register_clock());
+       WARN_ON(kvm_register_clock("secondary cpu clock"));
        /* ok, done with our trickery, call native */
        setup_secondary_APIC_clock();
 }
 #endif
 
+#ifdef CONFIG_SMP
+void __init kvm_smp_prepare_boot_cpu(void)
+{
+       WARN_ON(kvm_register_clock("primary cpu clock"));
+       native_smp_prepare_boot_cpu();
+}
+#endif
+
 /*
  * After the clock is registered, the host will keep writing to the
  * registered memory location. If the guest happens to shutdown, this memory
@@ -174,13 +148,16 @@ void __init kvmclock_init(void)
                return;
 
        if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
-               if (kvm_register_clock())
+               if (kvm_register_clock("boot clock"))
                        return;
                pv_time_ops.get_wallclock = kvm_get_wallclock;
                pv_time_ops.set_wallclock = kvm_set_wallclock;
                pv_time_ops.sched_clock = kvm_clock_read;
 #ifdef CONFIG_X86_LOCAL_APIC
                pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
+#endif
+#ifdef CONFIG_SMP
+               smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
 #endif
                machine_ops.shutdown  = kvm_shutdown;
 #ifdef CONFIG_KEXEC
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
new file mode 100644 (file)
index 0000000..05fbe9a
--- /dev/null
@@ -0,0 +1,141 @@
+/*  paravirtual clock -- common code used by kvm/xen
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <linux/kernel.h>
+#include <linux/percpu.h>
+#include <asm/pvclock.h>
+
+/*
+ * These are perodically updated
+ *    xen: magic shared_info page
+ *    kvm: gpa registered via msr
+ * and then copied here.
+ */
+struct pvclock_shadow_time {
+       u64 tsc_timestamp;     /* TSC at last update of time vals.  */
+       u64 system_timestamp;  /* Time, in nanosecs, since boot.    */
+       u32 tsc_to_nsec_mul;
+       int tsc_shift;
+       u32 version;
+};
+
+/*
+ * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
+ * yielding a 64-bit result.
+ */
+static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
+{
+       u64 product;
+#ifdef __i386__
+       u32 tmp1, tmp2;
+#endif
+
+       if (shift < 0)
+               delta >>= -shift;
+       else
+               delta <<= shift;
+
+#ifdef __i386__
+       __asm__ (
+               "mul  %5       ; "
+               "mov  %4,%%eax ; "
+               "mov  %%edx,%4 ; "
+               "mul  %5       ; "
+               "xor  %5,%5    ; "
+               "add  %4,%%eax ; "
+               "adc  %5,%%edx ; "
+               : "=A" (product), "=r" (tmp1), "=r" (tmp2)
+               : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
+#elif __x86_64__
+       __asm__ (
+               "mul %%rdx ; shrd $32,%%rdx,%%rax"
+               : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
+#else
+#error implement me!
+#endif
+
+       return product;
+}
+
+static u64 pvclock_get_nsec_offset(struct pvclock_shadow_time *shadow)
+{
+       u64 delta = native_read_tsc() - shadow->tsc_timestamp;
+       return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
+}
+
+/*
+ * Reads a consistent set of time-base values from hypervisor,
+ * into a shadow data area.
+ */
+static unsigned pvclock_get_time_values(struct pvclock_shadow_time *dst,
+                                       struct pvclock_vcpu_time_info *src)
+{
+       do {
+               dst->version = src->version;
+               rmb();          /* fetch version before data */
+               dst->tsc_timestamp     = src->tsc_timestamp;
+               dst->system_timestamp  = src->system_time;
+               dst->tsc_to_nsec_mul   = src->tsc_to_system_mul;
+               dst->tsc_shift         = src->tsc_shift;
+               rmb();          /* test version after fetching data */
+       } while ((src->version & 1) || (dst->version != src->version));
+
+       return dst->version;
+}
+
+cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
+{
+       struct pvclock_shadow_time shadow;
+       unsigned version;
+       cycle_t ret, offset;
+
+       do {
+               version = pvclock_get_time_values(&shadow, src);
+               barrier();
+               offset = pvclock_get_nsec_offset(&shadow);
+               ret = shadow.system_timestamp + offset;
+               barrier();
+       } while (version != src->version);
+
+       return ret;
+}
+
+void pvclock_read_wallclock(struct pvclock_wall_clock *wall_clock,
+                           struct pvclock_vcpu_time_info *vcpu_time,
+                           struct timespec *ts)
+{
+       u32 version;
+       u64 delta;
+       struct timespec now;
+
+       /* get wallclock at system boot */
+       do {
+               version = wall_clock->version;
+               rmb();          /* fetch version before time */
+               now.tv_sec  = wall_clock->sec;
+               now.tv_nsec = wall_clock->nsec;
+               rmb();          /* fetch time before checking version */
+       } while ((wall_clock->version & 1) || (version != wall_clock->version));
+
+       delta = pvclock_clocksource_read(vcpu_time);    /* time since system boot */
+       delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec;
+
+       now.tv_nsec = do_div(delta, NSEC_PER_SEC);
+       now.tv_sec = delta;
+
+       set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
+}
index f2f5d260874e96117ee0dbcbc3152a594fc96033..3829aa7b663f5690c7fe7efb7df279cd51b9ada7 100644 (file)
@@ -200,9 +200,12 @@ int __pit_timer_fn(struct kvm_kpit_state *ps)
 
        atomic_inc(&pt->pending);
        smp_mb__after_atomic_inc();
-       if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
-               vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
-               wake_up_interruptible(&vcpu0->wq);
+       if (vcpu0) {
+               set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
+               if (waitqueue_active(&vcpu0->wq)) {
+                       vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+                       wake_up_interruptible(&vcpu0->wq);
+               }
        }
 
        pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period);
index c297c50eba63535968f72c1596d6a969fb4eb9c9..ebc03f5ae162e2702974c122e27a580fa6556ac2 100644 (file)
@@ -940,6 +940,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
        wait_queue_head_t *q = &apic->vcpu->wq;
 
        atomic_inc(&apic->timer.pending);
+       set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
        if (waitqueue_active(q)) {
                apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
                wake_up_interruptible(q);
index ee3f53098f0c738e59bc1eb3fefe890d3e528eeb..7e7c3969f7a2d01f0f9d2d2542b046fc9d0aa157 100644 (file)
@@ -640,6 +640,7 @@ static void rmap_write_protect(struct kvm *kvm, u64 gfn)
                        rmap_remove(kvm, spte);
                        --kvm->stat.lpages;
                        set_shadow_pte(spte, shadow_trap_nonpresent_pte);
+                       spte = NULL;
                        write_protected = 1;
                }
                spte = rmap_next(kvm, rmapp, spte);
@@ -1082,10 +1083,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
                struct kvm_mmu_page *shadow;
 
                spte |= PT_WRITABLE_MASK;
-               if (user_fault) {
-                       mmu_unshadow(vcpu->kvm, gfn);
-                       goto unshadowed;
-               }
 
                shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn);
                if (shadow ||
@@ -1102,8 +1099,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
                }
        }
 
-unshadowed:
-
        if (pte_access & ACC_WRITE_MASK)
                mark_page_dirty(vcpu->kvm, gfn);
 
@@ -1580,11 +1575,13 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
                                  u64 *spte,
                                  const void *new)
 {
-       if ((sp->role.level != PT_PAGE_TABLE_LEVEL)
-           && !vcpu->arch.update_pte.largepage) {
-               ++vcpu->kvm->stat.mmu_pde_zapped;
-               return;
-       }
+       if (sp->role.level != PT_PAGE_TABLE_LEVEL) {
+               if (!vcpu->arch.update_pte.largepage ||
+                   sp->role.glevels == PT32_ROOT_LEVEL) {
+                       ++vcpu->kvm->stat.mmu_pde_zapped;
+                       return;
+               }
+        }
 
        ++vcpu->kvm->stat.mmu_pte_updated;
        if (sp->role.glevels == PT32_ROOT_LEVEL)
index 02efbe75f317d68b8f24a6bd7945eaaeffcbfe89..540e95179074e8fccedd9802afdd0d81c21dccaa 100644 (file)
@@ -566,7 +566,7 @@ static void vmx_save_host_state(struct kvm_vcpu *vcpu)
        load_transition_efer(vmx);
 }
 
-static void vmx_load_host_state(struct vcpu_vmx *vmx)
+static void __vmx_load_host_state(struct vcpu_vmx *vmx)
 {
        unsigned long flags;
 
@@ -596,6 +596,13 @@ static void vmx_load_host_state(struct vcpu_vmx *vmx)
        reload_host_efer(vmx);
 }
 
+static void vmx_load_host_state(struct vcpu_vmx *vmx)
+{
+       preempt_disable();
+       __vmx_load_host_state(vmx);
+       preempt_enable();
+}
+
 /*
  * Switches to specified vcpu, until a matching vcpu_put(), but assumes
  * vcpu mutex is already taken.
@@ -654,7 +661,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
 {
-       vmx_load_host_state(to_vmx(vcpu));
+       __vmx_load_host_state(to_vmx(vcpu));
 }
 
 static void vmx_fpu_activate(struct kvm_vcpu *vcpu)
@@ -884,11 +891,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
        switch (msr_index) {
 #ifdef CONFIG_X86_64
        case MSR_EFER:
+               vmx_load_host_state(vmx);
                ret = kvm_set_msr_common(vcpu, msr_index, data);
-               if (vmx->host_state.loaded) {
-                       reload_host_efer(vmx);
-                       load_transition_efer(vmx);
-               }
                break;
        case MSR_FS_BASE:
                vmcs_writel(GUEST_FS_BASE, data);
@@ -910,11 +914,10 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
                guest_write_tsc(data);
                break;
        default:
+               vmx_load_host_state(vmx);
                msr = find_msr_entry(vmx, msr_index);
                if (msr) {
                        msr->data = data;
-                       if (vmx->host_state.loaded)
-                               load_msrs(vmx->guest_msrs, vmx->save_nmsrs);
                        break;
                }
                ret = kvm_set_msr_common(vcpu, msr_index, data);
index 00acf1301a151663beb43151a569f2022d6e9dde..63a77caa59f11bf55a8655b857aa9c541e4168a6 100644 (file)
@@ -492,8 +492,8 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
 static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
 {
        static int version;
-       struct kvm_wall_clock wc;
-       struct timespec wc_ts;
+       struct pvclock_wall_clock wc;
+       struct timespec now, sys, boot;
 
        if (!wall_clock)
                return;
@@ -502,10 +502,19 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
 
        kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
 
-       wc_ts = current_kernel_time();
-       wc.wc_sec = wc_ts.tv_sec;
-       wc.wc_nsec = wc_ts.tv_nsec;
-       wc.wc_version = version;
+       /*
+        * The guest calculates current wall clock time by adding
+        * system time (updated by kvm_write_guest_time below) to the
+        * wall clock specified here.  guest system time equals host
+        * system time for us, thus we must fill in host boot time here.
+        */
+       now = current_kernel_time();
+       ktime_get_ts(&sys);
+       boot = ns_to_timespec(timespec_to_ns(&now) - timespec_to_ns(&sys));
+
+       wc.sec = boot.tv_sec;
+       wc.nsec = boot.tv_nsec;
+       wc.version = version;
 
        kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc));
 
@@ -513,6 +522,45 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
        kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
 }
 
+static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
+{
+       uint32_t quotient, remainder;
+
+       /* Don't try to replace with do_div(), this one calculates
+        * "(dividend << 32) / divisor" */
+       __asm__ ( "divl %4"
+                 : "=a" (quotient), "=d" (remainder)
+                 : "0" (0), "1" (dividend), "r" (divisor) );
+       return quotient;
+}
+
+static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *hv_clock)
+{
+       uint64_t nsecs = 1000000000LL;
+       int32_t  shift = 0;
+       uint64_t tps64;
+       uint32_t tps32;
+
+       tps64 = tsc_khz * 1000LL;
+       while (tps64 > nsecs*2) {
+               tps64 >>= 1;
+               shift--;
+       }
+
+       tps32 = (uint32_t)tps64;
+       while (tps32 <= (uint32_t)nsecs) {
+               tps32 <<= 1;
+               shift++;
+       }
+
+       hv_clock->tsc_shift = shift;
+       hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32);
+
+       pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n",
+                __FUNCTION__, tsc_khz, hv_clock->tsc_shift,
+                hv_clock->tsc_to_system_mul);
+}
+
 static void kvm_write_guest_time(struct kvm_vcpu *v)
 {
        struct timespec ts;
@@ -523,6 +571,11 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
        if ((!vcpu->time_page))
                return;
 
+       if (unlikely(vcpu->hv_clock_tsc_khz != tsc_khz)) {
+               kvm_set_time_scale(tsc_khz, &vcpu->hv_clock);
+               vcpu->hv_clock_tsc_khz = tsc_khz;
+       }
+
        /* Keep irq disabled to prevent changes to the clock */
        local_irq_save(flags);
        kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER,
@@ -537,14 +590,14 @@ static void kvm_write_guest_time(struct kvm_vcpu *v)
        /*
         * The interface expects us to write an even number signaling that the
         * update is finished. Since the guest won't see the intermediate
-        * state, we just write "2" at the end
+        * state, we just increase by 2 at the end.
         */
-       vcpu->hv_clock.version = 2;
+       vcpu->hv_clock.version += 2;
 
        shared_kaddr = kmap_atomic(vcpu->time_page, KM_USER0);
 
        memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
-               sizeof(vcpu->hv_clock));
+              sizeof(vcpu->hv_clock));
 
        kunmap_atomic(shared_kaddr, KM_USER0);
 
@@ -599,10 +652,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
                /* ...but clean it before doing the actual write */
                vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
 
-               vcpu->arch.hv_clock.tsc_to_system_mul =
-                                       clocksource_khz2mult(tsc_khz, 22);
-               vcpu->arch.hv_clock.tsc_shift = 22;
-
                down_read(&current->mm->mmap_sem);
                vcpu->arch.time_page =
                                gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
@@ -2759,6 +2808,8 @@ again:
        if (vcpu->requests) {
                if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
                        __kvm_migrate_timers(vcpu);
+               if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
+                       kvm_x86_ops->tlb_flush(vcpu);
                if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
                                       &vcpu->requests)) {
                        kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS;
@@ -2772,6 +2823,7 @@ again:
                }
        }
 
+       clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
        kvm_inject_pending_timer_irqs(vcpu);
 
        preempt_disable();
@@ -2781,21 +2833,13 @@ again:
 
        local_irq_disable();
 
-       if (need_resched()) {
+       if (vcpu->requests || need_resched()) {
                local_irq_enable();
                preempt_enable();
                r = 1;
                goto out;
        }
 
-       if (vcpu->requests)
-               if (test_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) {
-                       local_irq_enable();
-                       preempt_enable();
-                       r = 1;
-                       goto out;
-               }
-
        if (signal_pending(current)) {
                local_irq_enable();
                preempt_enable();
@@ -2825,9 +2869,6 @@ again:
 
        kvm_guest_enter();
 
-       if (vcpu->requests)
-               if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
-                       kvm_x86_ops->tlb_flush(vcpu);
 
        KVMTRACE_0D(VMENTRY, vcpu, entryexit);
        kvm_x86_ops->run(vcpu, kvm_run);
index 525b108411bddc01030a9825f0ebf08c9bb88755..6c388e593bc804cad3d92f653c1f9ffbb4fd9d3c 100644 (file)
@@ -5,6 +5,7 @@
 config XEN
        bool "Xen guest support"
        select PARAVIRT
+       select PARAVIRT_CLOCK
        depends on X86_32
        depends on X86_CMPXCHG && X86_TSC && X86_PAE && !(X86_VISWS || X86_VOYAGER)
        help
index 52b2e3856980ea6f26fa265b071fe4455d20104a..41e217503c96552868d7d350711aaabaeff54d24 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel_stat.h>
 #include <linux/math64.h>
 
+#include <asm/pvclock.h>
 #include <asm/xen/hypervisor.h>
 #include <asm/xen/hypercall.h>
 
 
 static cycle_t xen_clocksource_read(void);
 
-/* These are perodically updated in shared_info, and then copied here. */
-struct shadow_time_info {
-       u64 tsc_timestamp;     /* TSC at last update of time vals.  */
-       u64 system_timestamp;  /* Time, in nanosecs, since boot.    */
-       u32 tsc_to_nsec_mul;
-       int tsc_shift;
-       u32 version;
-};
-
-static DEFINE_PER_CPU(struct shadow_time_info, shadow_time);
-
 /* runstate info updated by Xen */
 static DEFINE_PER_CPU(struct vcpu_runstate_info, runstate);
 
@@ -211,7 +201,7 @@ unsigned long long xen_sched_clock(void)
 unsigned long xen_cpu_khz(void)
 {
        u64 xen_khz = 1000000ULL << 32;
-       const struct vcpu_time_info *info =
+       const struct pvclock_vcpu_time_info *info =
                &HYPERVISOR_shared_info->vcpu_info[0].time;
 
        do_div(xen_khz, info->tsc_to_system_mul);
@@ -223,121 +213,26 @@ unsigned long xen_cpu_khz(void)
        return xen_khz;
 }
 
-/*
- * Reads a consistent set of time-base values from Xen, into a shadow data
- * area.
- */
-static unsigned get_time_values_from_xen(void)
-{
-       struct vcpu_time_info   *src;
-       struct shadow_time_info *dst;
-
-       /* src is shared memory with the hypervisor, so we need to
-          make sure we get a consistent snapshot, even in the face of
-          being preempted. */
-       src = &__get_cpu_var(xen_vcpu)->time;
-       dst = &__get_cpu_var(shadow_time);
-
-       do {
-               dst->version = src->version;
-               rmb();          /* fetch version before data */
-               dst->tsc_timestamp     = src->tsc_timestamp;
-               dst->system_timestamp  = src->system_time;
-               dst->tsc_to_nsec_mul   = src->tsc_to_system_mul;
-               dst->tsc_shift         = src->tsc_shift;
-               rmb();          /* test version after fetching data */
-       } while ((src->version & 1) | (dst->version ^ src->version));
-
-       return dst->version;
-}
-
-/*
- * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction,
- * yielding a 64-bit result.
- */
-static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
-{
-       u64 product;
-#ifdef __i386__
-       u32 tmp1, tmp2;
-#endif
-
-       if (shift < 0)
-               delta >>= -shift;
-       else
-               delta <<= shift;
-
-#ifdef __i386__
-       __asm__ (
-               "mul  %5       ; "
-               "mov  %4,%%eax ; "
-               "mov  %%edx,%4 ; "
-               "mul  %5       ; "
-               "xor  %5,%5    ; "
-               "add  %4,%%eax ; "
-               "adc  %5,%%edx ; "
-               : "=A" (product), "=r" (tmp1), "=r" (tmp2)
-               : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
-#elif __x86_64__
-       __asm__ (
-               "mul %%rdx ; shrd $32,%%rdx,%%rax"
-               : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
-#else
-#error implement me!
-#endif
-
-       return product;
-}
-
-static u64 get_nsec_offset(struct shadow_time_info *shadow)
-{
-       u64 now, delta;
-       now = native_read_tsc();
-       delta = now - shadow->tsc_timestamp;
-       return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
-}
-
 static cycle_t xen_clocksource_read(void)
 {
-       struct shadow_time_info *shadow = &get_cpu_var(shadow_time);
+        struct pvclock_vcpu_time_info *src;
        cycle_t ret;
-       unsigned version;
-
-       do {
-               version = get_time_values_from_xen();
-               barrier();
-               ret = shadow->system_timestamp + get_nsec_offset(shadow);
-               barrier();
-       } while (version != __get_cpu_var(xen_vcpu)->time.version);
-
-       put_cpu_var(shadow_time);
 
+       src = &get_cpu_var(xen_vcpu)->time;
+       ret = pvclock_clocksource_read(src);
+       put_cpu_var(xen_vcpu);
        return ret;
 }
 
 static void xen_read_wallclock(struct timespec *ts)
 {
-       const struct shared_info *s = HYPERVISOR_shared_info;
-       u32 version;
-       u64 delta;
-       struct timespec now;
-
-       /* get wallclock at system boot */
-       do {
-               version = s->wc_version;
-               rmb();          /* fetch version before time */
-               now.tv_sec  = s->wc_sec;
-               now.tv_nsec = s->wc_nsec;
-               rmb();          /* fetch time before checking version */
-       } while ((s->wc_version & 1) | (version ^ s->wc_version));
+       struct shared_info *s = HYPERVISOR_shared_info;
+       struct pvclock_wall_clock *wall_clock = &(s->wc);
+        struct pvclock_vcpu_time_info *vcpu_time;
 
-       delta = xen_clocksource_read(); /* time since system boot */
-       delta += now.tv_sec * (u64)NSEC_PER_SEC + now.tv_nsec;
-
-       now.tv_nsec = do_div(delta, NSEC_PER_SEC);
-       now.tv_sec = delta;
-
-       set_normalized_timespec(ts, now.tv_sec, now.tv_nsec);
+       vcpu_time = &get_cpu_var(xen_vcpu)->time;
+       pvclock_read_wallclock(wall_clock, vcpu_time, ts);
+       put_cpu_var(xen_vcpu);
 }
 
 unsigned long xen_get_wallclock(void)
@@ -345,7 +240,6 @@ unsigned long xen_get_wallclock(void)
        struct timespec ts;
 
        xen_read_wallclock(&ts);
-
        return ts.tv_sec;
 }
 
@@ -569,8 +463,6 @@ __init void xen_time_init(void)
 {
        int cpu = smp_processor_id();
 
-       get_time_values_from_xen();
-
        clocksource_register(&xen_clocksource);
 
        if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) {
index 5b73f6a2cd86c839d36ed8c9cb83bb5659f0cc04..831883b7d6c9c5f456bb8db766ebc978b00bd907 100644 (file)
@@ -233,6 +233,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 
        device = ac->device;
        switch (event) {
+       default:
+               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                 "Unsupported event [0x%x]\n", event));
        case ACPI_AC_NOTIFY_STATUS:
        case ACPI_NOTIFY_BUS_CHECK:
        case ACPI_NOTIFY_DEVICE_CHECK:
@@ -244,11 +247,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
 #ifdef CONFIG_ACPI_SYSFS_POWER
                kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
 #endif
-               break;
-       default:
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Unsupported event [0x%x]\n", event));
-               break;
        }
 
        return;
index 26038c2a2a71bb20026a0631e890b6d57705805e..61b6c5beb2d347d32d1fe1e3ee1ff8195e5f731d 100644 (file)
@@ -377,6 +377,9 @@ static int __init bay_init(void)
 
        INIT_LIST_HEAD(&drive_bays);
 
+       if (acpi_disabled)
+               return -ENODEV;
+
        /* look for dockable drive bays */
        acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, find_bay, &bays, NULL);
index 96c542f7fded0c3abe8bfb3e07eec1a15a52ae41..bb7c51f712bd6cde630e4e8e5a771ca9d9e5fc55 100644 (file)
@@ -917,6 +917,9 @@ static int __init dock_init(void)
 
        dock_station = NULL;
 
+       if (acpi_disabled)
+               return 0;
+
        /* look for a dock station */
        acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
                            ACPI_UINT32_MAX, find_dock, &num, NULL);
index 2808dc60fd670065a94ddf4c0be90876fd3fc20a..9b227d4dc9c9bbd43b7649b66b7ee311371f7eaf 100644 (file)
@@ -333,6 +333,9 @@ static int __init acpi_rtc_init(void)
 {
        struct device *dev = get_rtc_dev();
 
+       if (acpi_disabled)
+               return 0;
+
        if (dev) {
                rtc_wake_setup();
                rtc_info.wake_on = rtc_wake_on;
index 5e5dda3a3027abfa1554a9b44c5ae636cd1e7133..d089c4519d456a796287ae9bfd77ad08d5f753f6 100644 (file)
@@ -1713,7 +1713,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
 
                status = acpi_video_bus_get_one_device(dev, video);
                if (ACPI_FAILURE(status)) {
-                       ACPI_EXCEPTION((AE_INFO, status, "Cant attach device"));
+                       ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+                                       "Cant attach device"));
                        continue;
                }
        }
index 9bf2986a2788d6bd11e26bdd459bdf9ed376fcb5..ae8494944c45dd54eb92f57f9651b86b6679f361 100644 (file)
@@ -651,9 +651,17 @@ config PATA_WINBOND_VLB
          Support for the Winbond W83759A controller on Vesa Local Bus
          systems.
 
+config HAVE_PATA_PLATFORM
+       bool
+       help
+         This is an internal configuration node for any machine that
+         uses pata-platform driver to enable the relevant driver in the
+         configuration structure without having to submit endless patches
+         to update the PATA_PLATFORM entry.
+
 config PATA_PLATFORM
        tristate "Generic platform device PATA support"
-       depends on EMBEDDED || ARCH_RPC || PPC
+       depends on EMBEDDED || ARCH_RPC || PPC || HAVE_PATA_PLATFORM
        help
          This option enables support for generic directly connected ATA
          devices commonly found on embedded systems.
index 966ab401e5234d6c0adc8c86a90250b586e8f2fb..6a4a2a25d97a6bd258f1fee4c7cad287d7ef8c0d 100644 (file)
@@ -90,6 +90,7 @@ enum {
        board_ahci_mv           = 4,
        board_ahci_sb700        = 5,
        board_ahci_mcp65        = 6,
+       board_ahci_nopmp        = 7,
 
        /* global controller registers */
        HOST_CAP                = 0x00, /* host capabilities */
@@ -401,6 +402,14 @@ static const struct ata_port_info ahci_port_info[] = {
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
+       /* board_ahci_nopmp */
+       {
+               AHCI_HFLAGS     (AHCI_HFLAG_NO_PMP),
+               .flags          = AHCI_FLAG_COMMON,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .udma_mask      = ATA_UDMA6,
+               .port_ops       = &ahci_ops,
+       },
 };
 
 static const struct pci_device_id ahci_pci_tbl[] = {
@@ -525,9 +534,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci },            /* MCP7B */
 
        /* SiS */
-       { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
-       { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
-       { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
+       { PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp },          /* SiS 966 */
+       { PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp },          /* SiS 968 */
+       { PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp },          /* SiS 968 */
 
        /* Marvell */
        { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },        /* 6145 */
@@ -653,6 +662,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
                cap &= ~HOST_CAP_PMP;
        }
 
+       if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361 &&
+           port_map != 1) {
+               dev_printk(KERN_INFO, &pdev->dev,
+                          "JMB361 has only one port, port_map 0x%x -> 0x%x\n",
+                          port_map, 1);
+               port_map = 1;
+       }
+
        /*
         * Temporary Marvell 6145 hack: PATA port presence
         * is asserted through the standard AHCI port
index 81b7ae376951a4452980cc403e0d5c847629f2a4..a90ae03f56b2e1f09793a8ddc63aca41a281b9f8 100644 (file)
@@ -1042,6 +1042,13 @@ static int piix_broken_suspend(void)
                                DMI_MATCH(DMI_PRODUCT_NAME, "Tecra M4"),
                        },
                },
+               {
+                       .ident = "TECRA M4",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M4"),
+                       },
+               },
                {
                        .ident = "TECRA M5",
                        .matches = {
index cc816ca623d322c538deffe2daa263178d8db0ed..303fc0d2b978464dbf6d927a370f4cf743862b6b 100644 (file)
@@ -4297,7 +4297,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_check_atapi_dma - Check whether ATAPI DMA can be supported
+ *     atapi_check_dma - Check whether ATAPI DMA can be supported
  *     @qc: Metadata associated with taskfile to check
  *
  *     Allow low-level driver to filter ATA PACKET commands, returning
@@ -4310,7 +4310,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
  *     RETURNS: 0 when ATAPI DMA can be used
  *               nonzero otherwise
  */
-int ata_check_atapi_dma(struct ata_queued_cmd *qc)
+int atapi_check_dma(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
index 2e6e1622dc6d0b61566a7224612d2c834b395da3..57a43649a4616bf0cdaeb9614d8489e3dbbb9758 100644 (file)
@@ -2343,8 +2343,8 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 {
        struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_device *dev = qc->dev;
-       int using_pio = (dev->flags & ATA_DFLAG_PIO);
        int nodata = (scmd->sc_data_direction == DMA_NONE);
+       int using_pio = !nodata && (dev->flags & ATA_DFLAG_PIO);
        unsigned int nbytes;
 
        memset(qc->cdb, 0, dev->cdb_len);
@@ -2362,7 +2362,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        ata_qc_set_pc_nbytes(qc);
 
        /* check whether ATAPI DMA is safe */
-       if (!using_pio && ata_check_atapi_dma(qc))
+       if (!nodata && !using_pio && atapi_check_dma(qc))
                using_pio = 1;
 
        /* Some controller variants snoop this value for Packet
@@ -2402,13 +2402,11 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        qc->tf.lbam = (nbytes & 0xFF);
        qc->tf.lbah = (nbytes >> 8);
 
-       if (using_pio || nodata) {
-               /* no data, or PIO data xfer */
-               if (nodata)
-                       qc->tf.protocol = ATAPI_PROT_NODATA;
-               else
-                       qc->tf.protocol = ATAPI_PROT_PIO;
-       } else {
+       if (nodata)
+               qc->tf.protocol = ATAPI_PROT_NODATA;
+       else if (using_pio)
+               qc->tf.protocol = ATAPI_PROT_PIO;
+       else {
                /* DMA data xfer */
                qc->tf.protocol = ATAPI_PROT_DMA;
                qc->tf.feature |= ATAPI_PKT_DMA;
index 4514283937ea4a9a4254664ac897586266809771..1cf803adbc958dbcc5f44ae1bc6efb980007ca0c 100644 (file)
@@ -106,7 +106,7 @@ extern void ata_sg_clean(struct ata_queued_cmd *qc);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
 extern void ata_qc_issue(struct ata_queued_cmd *qc);
 extern void __ata_qc_complete(struct ata_queued_cmd *qc);
-extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
+extern int atapi_check_dma(struct ata_queued_cmd *qc);
 extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
 extern void ata_dev_init(struct ata_device *dev);
 extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
index 3d39f9dfec5ae9cf8d7aaa1be3a0d935bb9cd2a5..41b4361bbf6ed86788634223ce855734f79ada89 100644 (file)
@@ -414,6 +414,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
        PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
+       PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
        PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
        PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
@@ -424,6 +425,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
        PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
        PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
index 60391e9a84db828f40577e17edcbca2d78817cbf..28092bc50146a04bf0298f48166550c8efa4320b 100644 (file)
@@ -1322,6 +1322,9 @@ static int mv_port_start(struct ata_port *ap)
                goto out_port_free_dma_mem;
        memset(pp->crpb, 0, MV_CRPB_Q_SZ);
 
+       /* 6041/6081 Rev. "C0" (and newer) are okay with async notify */
+       if (hpriv->hp_flags & MV_HP_ERRATA_60X1C0)
+               ap->flags |= ATA_FLAG_AN;
        /*
         * For GEN_I, there's no NCQ, so we only allocate a single sg_tbl.
         * For later hardware, we need one unique sg_tbl per NCQ tag.
@@ -1592,6 +1595,24 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 
        if ((qc->tf.protocol != ATA_PROT_DMA) &&
            (qc->tf.protocol != ATA_PROT_NCQ)) {
+               static int limit_warnings = 10;
+               /*
+                * Errata SATA#16, SATA#24: warn if multiple DRQs expected.
+                *
+                * Someday, we might implement special polling workarounds
+                * for these, but it all seems rather unnecessary since we
+                * normally use only DMA for commands which transfer more
+                * than a single block of data.
+                *
+                * Much of the time, this could just work regardless.
+                * So for now, just log the incident, and allow the attempt.
+                */
+               if (limit_warnings && (qc->nbytes / qc->sect_size) > 1) {
+                       --limit_warnings;
+                       ata_link_printk(qc->dev->link, KERN_WARNING, DRV_NAME
+                                       ": attempting PIO w/multiple DRQ: "
+                                       "this may fail due to h/w errata\n");
+               }
                /*
                 * We're about to send a non-EDMA capable command to the
                 * port.  Turn off EDMA so there won't be problems accessing
index 1ae64bb36771f6f4d64c55bc476f0df3cabe120f..df702642ab8fb49334ae46c0f0125df4a735376c 100644 (file)
@@ -948,7 +948,7 @@ static void intel_i9xx_setup_flush(void)
        intel_private.ifp_resource.flags = IORESOURCE_MEM;
 
        /* Setup chipset flush for 915 */
-       if (IS_I965 || IS_G33) {
+       if (IS_I965 || IS_G33 || IS_G4X) {
                intel_i965_g33_setup_chipset_flush();
        } else {
                intel_i915_setup_chipset_flush();
index b710426bab3ee3f7c726e0fbebad56acdabc32fc..c533d0c9ec616ba38aaf13211dee1bca48cc36c9 100644 (file)
@@ -76,7 +76,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
                for (i = 0; i < pages; i++) {
                        if (!entry->busaddr[i])
                                break;
-                       pci_unmap_single(dev->pdev, entry->busaddr[i],
+                       pci_unmap_page(dev->pdev, entry->busaddr[i],
                                         PAGE_SIZE, PCI_DMA_TODEVICE);
                }
 
@@ -137,10 +137,8 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
 
        for (i = 0; i < pages; i++) {
                /* we need to support large memory configurations */
-               entry->busaddr[i] = pci_map_single(dev->pdev,
-                                                  page_address(entry->
-                                                               pagelist[i]),
-                                                  PAGE_SIZE, PCI_DMA_TODEVICE);
+               entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i],
+                                                0, PAGE_SIZE, PCI_DMA_TODEVICE);
                if (entry->busaddr[i] == 0) {
                        DRM_ERROR("unable to map PCIGART pages!\n");
                        drm_ati_pcigart_cleanup(dev, gart_info);
index 3a05c6d5ebe1f9306bca6a3e11740d54b9e6e5ef..38d3c6b8276aec19755d1037378ba34f7e7ab80a 100644 (file)
@@ -628,7 +628,7 @@ struct drm_set_version {
 #define DRM_IOCTL_AGP_BIND             DRM_IOW( 0x36, struct drm_agp_binding)
 #define DRM_IOCTL_AGP_UNBIND           DRM_IOW( 0x37, struct drm_agp_binding)
 
-#define DRM_IOCTL_SG_ALLOC             DRM_IOW0x38, struct drm_scatter_gather)
+#define DRM_IOCTL_SG_ALLOC             DRM_IOWR(0x38, struct drm_scatter_gather)
 #define DRM_IOCTL_SG_FREE              DRM_IOW( 0x39, struct drm_scatter_gather)
 
 #define DRM_IOCTL_WAIT_VBLANK          DRM_IOWR(0x3a, union drm_wait_vblank)
index fc54140551a71620d747aa27466ad8f1d4101376..564138714bb5c6045755bb5db176af55a7c79bee 100644 (file)
@@ -470,17 +470,18 @@ int drm_ioctl(struct inode *inode, struct file *filp,
        if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
            (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
                ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
-       else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
+       else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
                ioctl = &drm_ioctls[nr];
-       else
+               cmd = ioctl->cmd;
+       } else
                goto err_i1;
 
+       /* Do not trust userspace, use our own definition */
        func = ioctl->func;
        /* is there a local override? */
        if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
                func = dev->driver->dma_ioctl;
 
-
        if (!func) {
                DRM_DEBUG("no function\n");
                retcode = -EINVAL;
index a6a499f97e2281980221fb65e172fb922fc12314..135bd19499fcc82f8d41e9b6216f9e70205ab814 100644 (file)
        {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
        {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
-       {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
-       {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
-       {0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
-       {0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
        {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
        {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
-       {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
-       {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
-       {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
-       {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+       {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
        {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
        {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
        {0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
        {0x8086, 0x2a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+       {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+       {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+       {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
        {0, 0, 0}
index e8f3d682e3b139331c1213a0687c1fc9a2cac40d..93aed1c38bd22cfb272f4763e3fa59b9e8d00837 100644 (file)
@@ -389,6 +389,7 @@ static int i915_resume(struct drm_device *dev)
        pci_restore_state(dev->pdev);
        if (pci_enable_device(dev->pdev))
                return -1;
+       pci_set_master(dev->pdev);
 
        pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
 
index 1b20f7c0639c24074cae6412e02ed605e51595a8..d7326d92a237c2917e48d0bf5ed2c8d017081578 100644 (file)
@@ -1112,12 +1112,19 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
                       (dev)->pci_device == 0x29A2 || \
                       (dev)->pci_device == 0x2A02 || \
                       (dev)->pci_device == 0x2A12 || \
-                      (dev)->pci_device == 0x2A42)
+                      (dev)->pci_device == 0x2A42 || \
+                      (dev)->pci_device == 0x2E02 || \
+                      (dev)->pci_device == 0x2E12 || \
+                      (dev)->pci_device == 0x2E22)
 
 #define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
 
 #define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
 
+#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
+                    (dev)->pci_device == 0x2E12 || \
+                    (dev)->pci_device == 0x2E22)
+
 #define IS_G33(dev)    ((dev)->pci_device == 0x29C2 || \
                        (dev)->pci_device == 0x29B2 ||  \
                        (dev)->pci_device == 0x29D2)
@@ -1128,7 +1135,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
 #define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
                        IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
 
-#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev))
+#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev) || IS_G4X(dev))
 
 #define PRIMARY_RINGBUFFER_SIZE         (128*1024)
 
index f7f16e7a8bf3c8d724065268052b9659c99a2d61..df036118b8b14ad1c3c1fd33ccf940e6a7fcf830 100644 (file)
@@ -62,11 +62,11 @@ static void i915_vblank_tasklet(struct drm_device *dev)
        u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
        RING_LOCALS;
 
-       if (sarea_priv->front_tiled) {
+       if (IS_I965G(dev) && sarea_priv->front_tiled) {
                cmd |= XY_SRC_COPY_BLT_DST_TILED;
                dst_pitch >>= 2;
        }
-       if (sarea_priv->back_tiled) {
+       if (IS_I965G(dev) && sarea_priv->back_tiled) {
                cmd |= XY_SRC_COPY_BLT_SRC_TILED;
                src_pitch >>= 2;
        }
index f535812e40573d69d8c057495563560ecb65f288..702df45320f7bcc897439e8b38a1f8d74200c5c4 100644 (file)
@@ -189,18 +189,12 @@ void r300_init_reg_flags(struct drm_device *dev)
        ADD_RANGE(R300_RE_CULL_CNTL, 1);
        ADD_RANGE(0x42C0, 2);
        ADD_RANGE(R300_RS_CNTL_0, 2);
-       ADD_RANGE(R300_RS_INTERP_0, 8);
-       ADD_RANGE(R300_RS_ROUTE_0, 8);
-       ADD_RANGE(0x43A4, 2);
+
+       ADD_RANGE(R300_SC_HYPERZ, 2);
        ADD_RANGE(0x43E8, 1);
-       ADD_RANGE(R300_PFS_CNTL_0, 3);
-       ADD_RANGE(R300_PFS_NODE_0, 4);
-       ADD_RANGE(R300_PFS_TEXI_0, 64);
+
        ADD_RANGE(0x46A4, 5);
-       ADD_RANGE(R300_PFS_INSTR0_0, 64);
-       ADD_RANGE(R300_PFS_INSTR1_0, 64);
-       ADD_RANGE(R300_PFS_INSTR2_0, 64);
-       ADD_RANGE(R300_PFS_INSTR3_0, 64);
+
        ADD_RANGE(R300_RE_FOG_STATE, 1);
        ADD_RANGE(R300_FOG_COLOR_R, 3);
        ADD_RANGE(R300_PP_ALPHA_TEST, 2);
@@ -215,14 +209,12 @@ void r300_init_reg_flags(struct drm_device *dev)
        ADD_RANGE(0x4E50, 9);
        ADD_RANGE(0x4E88, 1);
        ADD_RANGE(0x4EA0, 2);
-       ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3);
-       ADD_RANGE(R300_RB3D_ZSTENCIL_FORMAT, 4);
-       ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET);    /* check offset */
-       ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
-       ADD_RANGE(0x4F28, 1);
-       ADD_RANGE(0x4F30, 2);
-       ADD_RANGE(0x4F44, 1);
-       ADD_RANGE(0x4F54, 1);
+       ADD_RANGE(R300_ZB_CNTL, 3);
+       ADD_RANGE(R300_ZB_FORMAT, 4);
+       ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET);      /* check offset */
+       ADD_RANGE(R300_ZB_DEPTHPITCH, 1);
+       ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1);
+       ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13);
 
        ADD_RANGE(R300_TX_FILTER_0, 16);
        ADD_RANGE(R300_TX_FILTER1_0, 16);
@@ -235,13 +227,32 @@ void r300_init_reg_flags(struct drm_device *dev)
        ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
 
        /* Sporadic registers used as primitives are emitted */
-       ADD_RANGE(R300_RB3D_ZCACHE_CTLSTAT, 1);
+       ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1);
        ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1);
        ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
        ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
 
        if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
-               ADD_RANGE(0x4074, 16);
+               ADD_RANGE(R500_VAP_INDEX_OFFSET, 1);
+               ADD_RANGE(R500_US_CONFIG, 2);
+               ADD_RANGE(R500_US_CODE_ADDR, 3);
+               ADD_RANGE(R500_US_FC_CTRL, 1);
+               ADD_RANGE(R500_RS_IP_0, 16);
+               ADD_RANGE(R500_RS_INST_0, 16);
+               ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
+               ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
+               ADD_RANGE(R500_ZB_FIFO_SIZE, 2);
+       } else {
+               ADD_RANGE(R300_PFS_CNTL_0, 3);
+               ADD_RANGE(R300_PFS_NODE_0, 4);
+               ADD_RANGE(R300_PFS_TEXI_0, 64);
+               ADD_RANGE(R300_PFS_INSTR0_0, 64);
+               ADD_RANGE(R300_PFS_INSTR1_0, 64);
+               ADD_RANGE(R300_PFS_INSTR2_0, 64);
+               ADD_RANGE(R300_PFS_INSTR3_0, 64);
+               ADD_RANGE(R300_RS_INTERP_0, 8);
+               ADD_RANGE(R300_RS_ROUTE_0, 8);
+
        }
 }
 
@@ -707,8 +718,9 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
        BEGIN_RING(6);
        OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
        OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
-       OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0));
-       OUT_RING(R300_RB3D_ZCACHE_UNKNOWN_03);
+       OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));
+       OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE|
+                R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
        OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
        OUT_RING(0x0);
        ADVANCE_RING();
@@ -828,6 +840,54 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
        return 0;
 }
 
+/**
+ * Uploads user-supplied vertex program instructions or parameters onto
+ * the graphics card.
+ * Called by r300_do_cp_cmdbuf.
+ */
+static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv,
+                                      drm_radeon_kcmd_buffer_t *cmdbuf,
+                                      drm_r300_cmd_header_t header)
+{
+       int sz;
+       int addr;
+       int type;
+       int clamp;
+       int stride;
+       RING_LOCALS;
+
+       sz = header.r500fp.count;
+       /* address is 9 bits 0 - 8, bit 1 of flags is part of address */
+       addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo;
+
+       type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
+       clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
+
+       addr |= (type << 16);
+       addr |= (clamp << 17);
+
+       stride = type ? 4 : 6;
+
+       DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type);
+       if (!sz)
+               return 0;
+       if (sz * stride * 4 > cmdbuf->bufsz)
+               return -EINVAL;
+
+       BEGIN_RING(3 + sz * stride);
+       OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr);
+       OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1));
+       OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride);
+
+       ADVANCE_RING();
+
+       cmdbuf->buf += sz * stride * 4;
+       cmdbuf->bufsz -= sz * stride * 4;
+
+       return 0;
+}
+
+
 /**
  * Parses and validates a user-supplied command buffer and emits appropriate
  * commands on the DMA ring buffer.
@@ -963,6 +1023,19 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
                        }
                        break;
 
+               case R300_CMD_R500FP:
+                       if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
+                               DRM_ERROR("Calling r500 command on r300 card\n");
+                               ret = -EINVAL;
+                               goto cleanup;
+                       }
+                       DRM_DEBUG("R300_CMD_R500FP\n");
+                       ret = r300_emit_r500fp(dev_priv, cmdbuf, header);
+                       if (ret) {
+                               DRM_ERROR("r300_emit_r500fp failed\n");
+                               goto cleanup;
+                       }
+                       break;
                default:
                        DRM_ERROR("bad cmd_type %i at %p\n",
                                  header.header.cmd_type,
index 8f664af9c4a4f50d7ecd905b81fa39dd15dde89f..a6802f26afc4a7f482cbaf661ebc1d238ff3243d 100644 (file)
@@ -702,6 +702,27 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #              define R300_RS_ROUTE_1_UNKNOWN11         (1 << 11)
 /* END: Rasterization / Interpolators - many guesses */
 
+/* Hierarchical Z Enable */
+#define R300_SC_HYPERZ                   0x43a4
+#      define R300_SC_HYPERZ_DISABLE     (0 << 0)
+#      define R300_SC_HYPERZ_ENABLE      (1 << 0)
+#      define R300_SC_HYPERZ_MIN         (0 << 1)
+#      define R300_SC_HYPERZ_MAX         (1 << 1)
+#      define R300_SC_HYPERZ_ADJ_256     (0 << 2)
+#      define R300_SC_HYPERZ_ADJ_128     (1 << 2)
+#      define R300_SC_HYPERZ_ADJ_64      (2 << 2)
+#      define R300_SC_HYPERZ_ADJ_32      (3 << 2)
+#      define R300_SC_HYPERZ_ADJ_16      (4 << 2)
+#      define R300_SC_HYPERZ_ADJ_8       (5 << 2)
+#      define R300_SC_HYPERZ_ADJ_4       (6 << 2)
+#      define R300_SC_HYPERZ_ADJ_2       (7 << 2)
+#      define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5)
+#      define R300_SC_HYPERZ_HZ_Z0MIN    (1 << 5)
+#      define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6)
+#      define R300_SC_HYPERZ_HZ_Z0MAX    (1 << 6)
+
+#define R300_SC_EDGERULE                 0x43a8
+
 /* BEGIN: Scissors and cliprects */
 
 /* There are four clipping rectangles. Their corner coordinates are inclusive.
@@ -1346,7 +1367,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 /* Guess by Vladimir.
  * Set to 0A before 3D operations, set to 02 afterwards.
  */
-#define R300_RB3D_DSTCACHE_CTLSTAT          0x4E4C
+/*#define R300_RB3D_DSTCACHE_CTLSTAT          0x4E4C*/
 #       define R300_RB3D_DSTCACHE_UNKNOWN_02             0x00000002
 #       define R300_RB3D_DSTCACHE_UNKNOWN_0A             0x0000000A
 
@@ -1355,19 +1376,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  * for this.
  * Bit (1<<8) is the "test" bit. so plain write is 6  - vd
  */
-#define R300_RB3D_ZSTENCIL_CNTL_0                   0x4F00
-#       define R300_RB3D_Z_DISABLED_1            0x00000010
-#       define R300_RB3D_Z_DISABLED_2            0x00000014
-#       define R300_RB3D_Z_TEST                  0x00000012
-#       define R300_RB3D_Z_TEST_AND_WRITE        0x00000016
-#       define R300_RB3D_Z_WRITE_ONLY           0x00000006
-
-#       define R300_RB3D_Z_TEST                  0x00000012
-#       define R300_RB3D_Z_TEST_AND_WRITE        0x00000016
-#       define R300_RB3D_Z_WRITE_ONLY           0x00000006
-#      define R300_RB3D_STENCIL_ENABLE          0x00000001
-
-#define R300_RB3D_ZSTENCIL_CNTL_1                   0x4F04
+#define R300_ZB_CNTL                             0x4F00
+#      define R300_STENCIL_ENABLE               (1 << 0)
+#      define R300_Z_ENABLE                     (1 << 1)
+#      define R300_Z_WRITE_ENABLE               (1 << 2)
+#      define R300_Z_SIGNED_COMPARE             (1 << 3)
+#      define R300_STENCIL_FRONT_BACK           (1 << 4)
+
+#define R300_ZB_ZSTENCILCNTL                   0x4f04
        /* functions */
 #      define R300_ZS_NEVER                    0
 #      define R300_ZS_LESS                     1
@@ -1387,52 +1403,166 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #      define R300_ZS_INVERT                   5
 #      define R300_ZS_INCR_WRAP                6
 #      define R300_ZS_DECR_WRAP                7
+#      define R300_Z_FUNC_SHIFT                0
        /* front and back refer to operations done for front
           and back faces, i.e. separate stencil function support */
-#      define R300_RB3D_ZS1_DEPTH_FUNC_SHIFT           0
-#      define R300_RB3D_ZS1_FRONT_FUNC_SHIFT           3
-#      define R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT        6
-#      define R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT       9
-#      define R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT      12
-#      define R300_RB3D_ZS1_BACK_FUNC_SHIFT           15
-#      define R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT        18
-#      define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT       21
-#      define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT       24
-
-#define R300_RB3D_ZSTENCIL_CNTL_2                   0x4F08
-#      define R300_RB3D_ZS2_STENCIL_REF_SHIFT          0
-#      define R300_RB3D_ZS2_STENCIL_MASK               0xFF
-#      define R300_RB3D_ZS2_STENCIL_MASK_SHIFT         8
-#      define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT   16
+#      define R300_S_FRONT_FUNC_SHIFT          3
+#      define R300_S_FRONT_SFAIL_OP_SHIFT      6
+#      define R300_S_FRONT_ZPASS_OP_SHIFT      9
+#      define R300_S_FRONT_ZFAIL_OP_SHIFT      12
+#      define R300_S_BACK_FUNC_SHIFT           15
+#      define R300_S_BACK_SFAIL_OP_SHIFT       18
+#      define R300_S_BACK_ZPASS_OP_SHIFT       21
+#      define R300_S_BACK_ZFAIL_OP_SHIFT       24
+
+#define R300_ZB_STENCILREFMASK                        0x4f08
+#      define R300_STENCILREF_SHIFT       0
+#      define R300_STENCILREF_MASK        0x000000ff
+#      define R300_STENCILMASK_SHIFT      8
+#      define R300_STENCILMASK_MASK       0x0000ff00
+#      define R300_STENCILWRITEMASK_SHIFT 16
+#      define R300_STENCILWRITEMASK_MASK  0x00ff0000
 
 /* gap */
 
-#define R300_RB3D_ZSTENCIL_FORMAT                   0x4F10
-#      define R300_DEPTH_FORMAT_16BIT_INT_Z     (0 << 0)
-#      define R300_DEPTH_FORMAT_24BIT_INT_Z     (2 << 0)
-       /* 16 bit format or some aditional bit ? */
-#      define R300_DEPTH_FORMAT_UNK32          (32 << 0)
+#define R300_ZB_FORMAT                             0x4f10
+#      define R300_DEPTHFORMAT_16BIT_INT_Z   (0 << 0)
+#      define R300_DEPTHFORMAT_16BIT_13E3    (1 << 0)
+#      define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL   (2 << 0)
+/* reserved up to (15 << 0) */
+#      define R300_INVERT_13E3_LEADING_ONES  (0 << 4)
+#      define R300_INVERT_13E3_LEADING_ZEROS (1 << 4)
 
-#define R300_RB3D_EARLY_Z                           0x4F14
-#      define R300_EARLY_Z_DISABLE              (0 << 0)
-#      define R300_EARLY_Z_ENABLE               (1 << 0)
+#define R300_ZB_ZTOP                             0x4F14
+#      define R300_ZTOP_DISABLE                 (0 << 0)
+#      define R300_ZTOP_ENABLE                  (1 << 0)
 
 /* gap */
 
-#define R300_RB3D_ZCACHE_CTLSTAT            0x4F18 /* GUESS */
-#       define R300_RB3D_ZCACHE_UNKNOWN_01  0x1
-#       define R300_RB3D_ZCACHE_UNKNOWN_03  0x3
+#define R300_ZB_ZCACHE_CTLSTAT            0x4f18
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT      (0 << 0)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT       (0 << 1)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE            (1 << 1)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE            (0 << 31)
+#       define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY            (1 << 31)
+
+#define R300_ZB_BW_CNTL                     0x4f1c
+#      define R300_HIZ_DISABLE                              (0 << 0)
+#      define R300_HIZ_ENABLE                               (1 << 0)
+#      define R300_HIZ_MIN                                  (0 << 1)
+#      define R300_HIZ_MAX                                  (1 << 1)
+#      define R300_FAST_FILL_DISABLE                        (0 << 2)
+#      define R300_FAST_FILL_ENABLE                         (1 << 2)
+#      define R300_RD_COMP_DISABLE                          (0 << 3)
+#      define R300_RD_COMP_ENABLE                           (1 << 3)
+#      define R300_WR_COMP_DISABLE                          (0 << 4)
+#      define R300_WR_COMP_ENABLE                           (1 << 4)
+#      define R300_ZB_CB_CLEAR_RMW                          (0 << 5)
+#      define R300_ZB_CB_CLEAR_CACHE_LINEAR                 (1 << 5)
+#      define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE   (0 << 6)
+#      define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE    (1 << 6)
+
+#      define R500_ZEQUAL_OPTIMIZE_ENABLE                   (0 << 7)
+#      define R500_ZEQUAL_OPTIMIZE_DISABLE                  (1 << 7)
+#      define R500_SEQUAL_OPTIMIZE_ENABLE                   (0 << 8)
+#      define R500_SEQUAL_OPTIMIZE_DISABLE                  (1 << 8)
+
+#      define R500_BMASK_ENABLE                             (0 << 10)
+#      define R500_BMASK_DISABLE                            (1 << 10)
+#      define R500_HIZ_EQUAL_REJECT_DISABLE                 (0 << 11)
+#      define R500_HIZ_EQUAL_REJECT_ENABLE                  (1 << 11)
+#      define R500_HIZ_FP_EXP_BITS_DISABLE                  (0 << 12)
+#      define R500_HIZ_FP_EXP_BITS_1                        (1 << 12)
+#      define R500_HIZ_FP_EXP_BITS_2                        (2 << 12)
+#      define R500_HIZ_FP_EXP_BITS_3                        (3 << 12)
+#      define R500_HIZ_FP_EXP_BITS_4                        (4 << 12)
+#      define R500_HIZ_FP_EXP_BITS_5                        (5 << 12)
+#      define R500_HIZ_FP_INVERT_LEADING_ONES               (0 << 15)
+#      define R500_HIZ_FP_INVERT_LEADING_ZEROS              (1 << 15)
+#      define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE      (0 << 16)
+#      define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE     (1 << 16)
+#      define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE           (0 << 17)
+#      define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE          (1 << 17)
+#      define R500_PEQ_PACKING_DISABLE                      (0 << 18)
+#      define R500_PEQ_PACKING_ENABLE                       (1 << 18)
+#      define R500_COVERED_PTR_MASKING_DISABLE              (0 << 18)
+#      define R500_COVERED_PTR_MASKING_ENABLE               (1 << 18)
+
 
 /* gap */
 
-#define R300_RB3D_DEPTHOFFSET               0x4F20
-#define R300_RB3D_DEPTHPITCH                0x4F24
-#       define R300_DEPTHPITCH_MASK              0x00001FF8 /* GUESS */
-#       define R300_DEPTH_TILE_ENABLE            (1 << 16) /* GUESS */
-#       define R300_DEPTH_MICROTILE_ENABLE       (1 << 17) /* GUESS */
-#       define R300_DEPTH_ENDIAN_NO_SWAP         (0 << 18) /* GUESS */
-#       define R300_DEPTH_ENDIAN_WORD_SWAP       (1 << 18) /* GUESS */
-#       define R300_DEPTH_ENDIAN_DWORD_SWAP      (2 << 18) /* GUESS */
+/* Z Buffer Address Offset.
+ * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles.
+ */
+#define R300_ZB_DEPTHOFFSET               0x4f20
+
+/* Z Buffer Pitch and Endian Control */
+#define R300_ZB_DEPTHPITCH                0x4f24
+#       define R300_DEPTHPITCH_MASK              0x00003FFC
+#       define R300_DEPTHMACROTILE_DISABLE      (0 << 16)
+#       define R300_DEPTHMACROTILE_ENABLE       (1 << 16)
+#       define R300_DEPTHMICROTILE_LINEAR       (0 << 17)
+#       define R300_DEPTHMICROTILE_TILED        (1 << 17)
+#       define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17)
+#       define R300_DEPTHENDIAN_NO_SWAP         (0 << 18)
+#       define R300_DEPTHENDIAN_WORD_SWAP       (1 << 18)
+#       define R300_DEPTHENDIAN_DWORD_SWAP      (2 << 18)
+#       define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18)
+
+/* Z Buffer Clear Value */
+#define R300_ZB_DEPTHCLEARVALUE                  0x4f28
+
+#define R300_ZB_ZMASK_OFFSET                    0x4f30
+#define R300_ZB_ZMASK_PITCH                     0x4f34
+#define R300_ZB_ZMASK_WRINDEX                   0x4f38
+#define R300_ZB_ZMASK_DWORD                     0x4f3c
+#define R300_ZB_ZMASK_RDINDEX                   0x4f40
+
+/* Hierarchical Z Memory Offset */
+#define R300_ZB_HIZ_OFFSET                       0x4f44
+
+/* Hierarchical Z Write Index */
+#define R300_ZB_HIZ_WRINDEX                      0x4f48
+
+/* Hierarchical Z Data */
+#define R300_ZB_HIZ_DWORD                        0x4f4c
+
+/* Hierarchical Z Read Index */
+#define R300_ZB_HIZ_RDINDEX                      0x4f50
+
+/* Hierarchical Z Pitch */
+#define R300_ZB_HIZ_PITCH                        0x4f54
+
+/* Z Buffer Z Pass Counter Data */
+#define R300_ZB_ZPASS_DATA                       0x4f58
+
+/* Z Buffer Z Pass Counter Address */
+#define R300_ZB_ZPASS_ADDR                       0x4f5c
+
+/* Depth buffer X and Y coordinate offset */
+#define R300_ZB_DEPTHXY_OFFSET                   0x4f60
+#      define R300_DEPTHX_OFFSET_SHIFT  1
+#      define R300_DEPTHX_OFFSET_MASK   0x000007FE
+#      define R300_DEPTHY_OFFSET_SHIFT  17
+#      define R300_DEPTHY_OFFSET_MASK   0x07FE0000
+
+/* Sets the fifo sizes */
+#define R500_ZB_FIFO_SIZE                        0x4fd0
+#      define R500_OP_FIFO_SIZE_FULL   (0 << 0)
+#      define R500_OP_FIFO_SIZE_HALF   (1 << 0)
+#      define R500_OP_FIFO_SIZE_QUATER (2 << 0)
+#      define R500_OP_FIFO_SIZE_EIGTHS (4 << 0)
+
+/* Stencil Reference Value and Mask for backfacing quads */
+/* R300_ZB_STENCILREFMASK handles front face */
+#define R500_ZB_STENCILREFMASK_BF                0x4fd4
+#      define R500_STENCILREF_SHIFT       0
+#      define R500_STENCILREF_MASK        0x000000ff
+#      define R500_STENCILMASK_SHIFT      8
+#      define R500_STENCILMASK_MASK       0x0000ff00
+#      define R500_STENCILWRITEMASK_SHIFT 16
+#      define R500_STENCILWRITEMASK_MASK  0x00ff0000
 
 /* BEGIN: Vertex program instruction set */
 
@@ -1623,4 +1753,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 #define R300_CP_CMD_BITBLT_MULTI       0xC0009B00
 
+#define R500_VAP_INDEX_OFFSET          0x208c
+
+#define R500_GA_US_VECTOR_INDEX         0x4250
+#define R500_GA_US_VECTOR_DATA          0x4254
+
+#define R500_RS_IP_0                    0x4074
+#define R500_RS_INST_0                  0x4320
+
+#define R500_US_CONFIG                  0x4600
+
+#define R500_US_FC_CTRL                        0x4624
+#define R500_US_CODE_ADDR              0x4630
+
+#define R500_RB3D_COLOR_CLEAR_VALUE_AR  0x46c0
+#define R500_RB3D_CONSTANT_COLOR_AR     0x4ef8
+
 #endif /* _R300_REG_H */
index f6f6c92bf7710ad4c60892dc165eabaf50693219..e53158f0ecb5c9ebf074bbe241df3f60986e0987 100644 (file)
@@ -2,6 +2,7 @@
 /*
  * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
  * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
+ * Copyright 2007 Advanced Micro Devices, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
 #include "radeon_drv.h"
 #include "r300_reg.h"
 
+#include "radeon_microcode.h"
+
 #define RADEON_FIFO_DEBUG      0
 
 static int radeon_do_cleanup_cp(struct drm_device * dev);
 
-/* CP microcode (from ATI) */
-static const u32 R200_cp_microcode[][2] = {
-       {0x21007000, 0000000000},
-       {0x20007000, 0000000000},
-       {0x000000ab, 0x00000004},
-       {0x000000af, 0x00000004},
-       {0x66544a49, 0000000000},
-       {0x49494174, 0000000000},
-       {0x54517d83, 0000000000},
-       {0x498d8b64, 0000000000},
-       {0x49494949, 0000000000},
-       {0x49da493c, 0000000000},
-       {0x49989898, 0000000000},
-       {0xd34949d5, 0000000000},
-       {0x9dc90e11, 0000000000},
-       {0xce9b9b9b, 0000000000},
-       {0x000f0000, 0x00000016},
-       {0x352e232c, 0000000000},
-       {0x00000013, 0x00000004},
-       {0x000f0000, 0x00000016},
-       {0x352e272c, 0000000000},
-       {0x000f0001, 0x00000016},
-       {0x3239362f, 0000000000},
-       {0x000077ef, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x00000020, 0x0000001a},
-       {0x00004000, 0x0000001e},
-       {0x00061000, 0x00000002},
-       {0x00000020, 0x0000001a},
-       {0x00004000, 0x0000001e},
-       {0x00061000, 0x00000002},
-       {0x00000020, 0x0000001a},
-       {0x00004000, 0x0000001e},
-       {0x00000016, 0x00000004},
-       {0x0003802a, 0x00000002},
-       {0x040067e0, 0x00000002},
-       {0x00000016, 0x00000004},
-       {0x000077e0, 0x00000002},
-       {0x00065000, 0x00000002},
-       {0x000037e1, 0x00000002},
-       {0x040067e1, 0x00000006},
-       {0x000077e0, 0x00000002},
-       {0x000077e1, 0x00000002},
-       {0x000077e1, 0x00000006},
-       {0xffffffff, 0000000000},
-       {0x10000000, 0000000000},
-       {0x0003802a, 0x00000002},
-       {0x040067e0, 0x00000006},
-       {0x00007675, 0x00000002},
-       {0x00007676, 0x00000002},
-       {0x00007677, 0x00000002},
-       {0x00007678, 0x00000006},
-       {0x0003802b, 0x00000002},
-       {0x04002676, 0x00000002},
-       {0x00007677, 0x00000002},
-       {0x00007678, 0x00000006},
-       {0x0000002e, 0x00000018},
-       {0x0000002e, 0x00000018},
-       {0000000000, 0x00000006},
-       {0x0000002f, 0x00000018},
-       {0x0000002f, 0x00000018},
-       {0000000000, 0x00000006},
-       {0x01605000, 0x00000002},
-       {0x00065000, 0x00000002},
-       {0x00098000, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x64c0603d, 0x00000004},
-       {0x00080000, 0x00000016},
-       {0000000000, 0000000000},
-       {0x0400251d, 0x00000002},
-       {0x00007580, 0x00000002},
-       {0x00067581, 0x00000002},
-       {0x04002580, 0x00000002},
-       {0x00067581, 0x00000002},
-       {0x00000046, 0x00000004},
-       {0x00005000, 0000000000},
-       {0x00061000, 0x00000002},
-       {0x0000750e, 0x00000002},
-       {0x00019000, 0x00000002},
-       {0x00011055, 0x00000014},
-       {0x00000055, 0x00000012},
-       {0x0400250f, 0x00000002},
-       {0x0000504a, 0x00000004},
-       {0x00007565, 0x00000002},
-       {0x00007566, 0x00000002},
-       {0x00000051, 0x00000004},
-       {0x01e655b4, 0x00000002},
-       {0x4401b0dc, 0x00000002},
-       {0x01c110dc, 0x00000002},
-       {0x2666705d, 0x00000018},
-       {0x040c2565, 0x00000002},
-       {0x0000005d, 0x00000018},
-       {0x04002564, 0x00000002},
-       {0x00007566, 0x00000002},
-       {0x00000054, 0x00000004},
-       {0x00401060, 0x00000008},
-       {0x00101000, 0x00000002},
-       {0x000d80ff, 0x00000002},
-       {0x00800063, 0x00000008},
-       {0x000f9000, 0x00000002},
-       {0x000e00ff, 0x00000002},
-       {0000000000, 0x00000006},
-       {0x00000080, 0x00000018},
-       {0x00000054, 0x00000004},
-       {0x00007576, 0x00000002},
-       {0x00065000, 0x00000002},
-       {0x00009000, 0x00000002},
-       {0x00041000, 0x00000002},
-       {0x0c00350e, 0x00000002},
-       {0x00049000, 0x00000002},
-       {0x00051000, 0x00000002},
-       {0x01e785f8, 0x00000002},
-       {0x00200000, 0x00000002},
-       {0x00600073, 0x0000000c},
-       {0x00007563, 0x00000002},
-       {0x006075f0, 0x00000021},
-       {0x20007068, 0x00000004},
-       {0x00005068, 0x00000004},
-       {0x00007576, 0x00000002},
-       {0x00007577, 0x00000002},
-       {0x0000750e, 0x00000002},
-       {0x0000750f, 0x00000002},
-       {0x00a05000, 0x00000002},
-       {0x00600076, 0x0000000c},
-       {0x006075f0, 0x00000021},
-       {0x000075f8, 0x00000002},
-       {0x00000076, 0x00000004},
-       {0x000a750e, 0x00000002},
-       {0x0020750f, 0x00000002},
-       {0x00600079, 0x00000004},
-       {0x00007570, 0x00000002},
-       {0x00007571, 0x00000002},
-       {0x00007572, 0x00000006},
-       {0x00005000, 0x00000002},
-       {0x00a05000, 0x00000002},
-       {0x00007568, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x00000084, 0x0000000c},
-       {0x00058000, 0x00000002},
-       {0x0c607562, 0x00000002},
-       {0x00000086, 0x00000004},
-       {0x00600085, 0x00000004},
-       {0x400070dd, 0000000000},
-       {0x000380dd, 0x00000002},
-       {0x00000093, 0x0000001c},
-       {0x00065095, 0x00000018},
-       {0x040025bb, 0x00000002},
-       {0x00061096, 0x00000018},
-       {0x040075bc, 0000000000},
-       {0x000075bb, 0x00000002},
-       {0x000075bc, 0000000000},
-       {0x00090000, 0x00000006},
-       {0x00090000, 0x00000002},
-       {0x000d8002, 0x00000006},
-       {0x00005000, 0x00000002},
-       {0x00007821, 0x00000002},
-       {0x00007800, 0000000000},
-       {0x00007821, 0x00000002},
-       {0x00007800, 0000000000},
-       {0x01665000, 0x00000002},
-       {0x000a0000, 0x00000002},
-       {0x000671cc, 0x00000002},
-       {0x0286f1cd, 0x00000002},
-       {0x000000a3, 0x00000010},
-       {0x21007000, 0000000000},
-       {0x000000aa, 0x0000001c},
-       {0x00065000, 0x00000002},
-       {0x000a0000, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x000b0000, 0x00000002},
-       {0x38067000, 0x00000002},
-       {0x000a00a6, 0x00000004},
-       {0x20007000, 0000000000},
-       {0x01200000, 0x00000002},
-       {0x20077000, 0x00000002},
-       {0x01200000, 0x00000002},
-       {0x20007000, 0000000000},
-       {0x00061000, 0x00000002},
-       {0x0120751b, 0x00000002},
-       {0x8040750a, 0x00000002},
-       {0x8040750b, 0x00000002},
-       {0x00110000, 0x00000002},
-       {0x000380dd, 0x00000002},
-       {0x000000bd, 0x0000001c},
-       {0x00061096, 0x00000018},
-       {0x844075bd, 0x00000002},
-       {0x00061095, 0x00000018},
-       {0x840075bb, 0x00000002},
-       {0x00061096, 0x00000018},
-       {0x844075bc, 0x00000002},
-       {0x000000c0, 0x00000004},
-       {0x804075bd, 0x00000002},
-       {0x800075bb, 0x00000002},
-       {0x804075bc, 0x00000002},
-       {0x00108000, 0x00000002},
-       {0x01400000, 0x00000002},
-       {0x006000c4, 0x0000000c},
-       {0x20c07000, 0x00000020},
-       {0x000000c6, 0x00000012},
-       {0x00800000, 0x00000006},
-       {0x0080751d, 0x00000006},
-       {0x000025bb, 0x00000002},
-       {0x000040c0, 0x00000004},
-       {0x0000775c, 0x00000002},
-       {0x00a05000, 0x00000002},
-       {0x00661000, 0x00000002},
-       {0x0460275d, 0x00000020},
-       {0x00004000, 0000000000},
-       {0x00007999, 0x00000002},
-       {0x00a05000, 0x00000002},
-       {0x00661000, 0x00000002},
-       {0x0460299b, 0x00000020},
-       {0x00004000, 0000000000},
-       {0x01e00830, 0x00000002},
-       {0x21007000, 0000000000},
-       {0x00005000, 0x00000002},
-       {0x00038042, 0x00000002},
-       {0x040025e0, 0x00000002},
-       {0x000075e1, 0000000000},
-       {0x00000001, 0000000000},
-       {0x000380d9, 0x00000002},
-       {0x04007394, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-};
-
-static const u32 radeon_cp_microcode[][2] = {
-       {0x21007000, 0000000000},
-       {0x20007000, 0000000000},
-       {0x000000b4, 0x00000004},
-       {0x000000b8, 0x00000004},
-       {0x6f5b4d4c, 0000000000},
-       {0x4c4c427f, 0000000000},
-       {0x5b568a92, 0000000000},
-       {0x4ca09c6d, 0000000000},
-       {0xad4c4c4c, 0000000000},
-       {0x4ce1af3d, 0000000000},
-       {0xd8afafaf, 0000000000},
-       {0xd64c4cdc, 0000000000},
-       {0x4cd10d10, 0000000000},
-       {0x000f0000, 0x00000016},
-       {0x362f242d, 0000000000},
-       {0x00000012, 0x00000004},
-       {0x000f0000, 0x00000016},
-       {0x362f282d, 0000000000},
-       {0x000380e7, 0x00000002},
-       {0x04002c97, 0x00000002},
-       {0x000f0001, 0x00000016},
-       {0x333a3730, 0000000000},
-       {0x000077ef, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x00000021, 0x0000001a},
-       {0x00004000, 0x0000001e},
-       {0x00061000, 0x00000002},
-       {0x00000021, 0x0000001a},
-       {0x00004000, 0x0000001e},
-       {0x00061000, 0x00000002},
-       {0x00000021, 0x0000001a},
-       {0x00004000, 0x0000001e},
-       {0x00000017, 0x00000004},
-       {0x0003802b, 0x00000002},
-       {0x040067e0, 0x00000002},
-       {0x00000017, 0x00000004},
-       {0x000077e0, 0x00000002},
-       {0x00065000, 0x00000002},
-       {0x000037e1, 0x00000002},
-       {0x040067e1, 0x00000006},
-       {0x000077e0, 0x00000002},
-       {0x000077e1, 0x00000002},
-       {0x000077e1, 0x00000006},
-       {0xffffffff, 0000000000},
-       {0x10000000, 0000000000},
-       {0x0003802b, 0x00000002},
-       {0x040067e0, 0x00000006},
-       {0x00007675, 0x00000002},
-       {0x00007676, 0x00000002},
-       {0x00007677, 0x00000002},
-       {0x00007678, 0x00000006},
-       {0x0003802c, 0x00000002},
-       {0x04002676, 0x00000002},
-       {0x00007677, 0x00000002},
-       {0x00007678, 0x00000006},
-       {0x0000002f, 0x00000018},
-       {0x0000002f, 0x00000018},
-       {0000000000, 0x00000006},
-       {0x00000030, 0x00000018},
-       {0x00000030, 0x00000018},
-       {0000000000, 0x00000006},
-       {0x01605000, 0x00000002},
-       {0x00065000, 0x00000002},
-       {0x00098000, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x64c0603e, 0x00000004},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x00080000, 0x00000016},
-       {0000000000, 0000000000},
-       {0x0400251d, 0x00000002},
-       {0x00007580, 0x00000002},
-       {0x00067581, 0x00000002},
-       {0x04002580, 0x00000002},
-       {0x00067581, 0x00000002},
-       {0x00000049, 0x00000004},
-       {0x00005000, 0000000000},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x0000750e, 0x00000002},
-       {0x00019000, 0x00000002},
-       {0x00011055, 0x00000014},
-       {0x00000055, 0x00000012},
-       {0x0400250f, 0x00000002},
-       {0x0000504f, 0x00000004},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x00007565, 0x00000002},
-       {0x00007566, 0x00000002},
-       {0x00000058, 0x00000004},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x01e655b4, 0x00000002},
-       {0x4401b0e4, 0x00000002},
-       {0x01c110e4, 0x00000002},
-       {0x26667066, 0x00000018},
-       {0x040c2565, 0x00000002},
-       {0x00000066, 0x00000018},
-       {0x04002564, 0x00000002},
-       {0x00007566, 0x00000002},
-       {0x0000005d, 0x00000004},
-       {0x00401069, 0x00000008},
-       {0x00101000, 0x00000002},
-       {0x000d80ff, 0x00000002},
-       {0x0080006c, 0x00000008},
-       {0x000f9000, 0x00000002},
-       {0x000e00ff, 0x00000002},
-       {0000000000, 0x00000006},
-       {0x0000008f, 0x00000018},
-       {0x0000005b, 0x00000004},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x00007576, 0x00000002},
-       {0x00065000, 0x00000002},
-       {0x00009000, 0x00000002},
-       {0x00041000, 0x00000002},
-       {0x0c00350e, 0x00000002},
-       {0x00049000, 0x00000002},
-       {0x00051000, 0x00000002},
-       {0x01e785f8, 0x00000002},
-       {0x00200000, 0x00000002},
-       {0x0060007e, 0x0000000c},
-       {0x00007563, 0x00000002},
-       {0x006075f0, 0x00000021},
-       {0x20007073, 0x00000004},
-       {0x00005073, 0x00000004},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x00007576, 0x00000002},
-       {0x00007577, 0x00000002},
-       {0x0000750e, 0x00000002},
-       {0x0000750f, 0x00000002},
-       {0x00a05000, 0x00000002},
-       {0x00600083, 0x0000000c},
-       {0x006075f0, 0x00000021},
-       {0x000075f8, 0x00000002},
-       {0x00000083, 0x00000004},
-       {0x000a750e, 0x00000002},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x0020750f, 0x00000002},
-       {0x00600086, 0x00000004},
-       {0x00007570, 0x00000002},
-       {0x00007571, 0x00000002},
-       {0x00007572, 0x00000006},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x00005000, 0x00000002},
-       {0x00a05000, 0x00000002},
-       {0x00007568, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x00000095, 0x0000000c},
-       {0x00058000, 0x00000002},
-       {0x0c607562, 0x00000002},
-       {0x00000097, 0x00000004},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x00600096, 0x00000004},
-       {0x400070e5, 0000000000},
-       {0x000380e6, 0x00000002},
-       {0x040025c5, 0x00000002},
-       {0x000380e5, 0x00000002},
-       {0x000000a8, 0x0000001c},
-       {0x000650aa, 0x00000018},
-       {0x040025bb, 0x00000002},
-       {0x000610ab, 0x00000018},
-       {0x040075bc, 0000000000},
-       {0x000075bb, 0x00000002},
-       {0x000075bc, 0000000000},
-       {0x00090000, 0x00000006},
-       {0x00090000, 0x00000002},
-       {0x000d8002, 0x00000006},
-       {0x00007832, 0x00000002},
-       {0x00005000, 0x00000002},
-       {0x000380e7, 0x00000002},
-       {0x04002c97, 0x00000002},
-       {0x00007820, 0x00000002},
-       {0x00007821, 0x00000002},
-       {0x00007800, 0000000000},
-       {0x01200000, 0x00000002},
-       {0x20077000, 0x00000002},
-       {0x01200000, 0x00000002},
-       {0x20007000, 0x00000002},
-       {0x00061000, 0x00000002},
-       {0x0120751b, 0x00000002},
-       {0x8040750a, 0x00000002},
-       {0x8040750b, 0x00000002},
-       {0x00110000, 0x00000002},
-       {0x000380e5, 0x00000002},
-       {0x000000c6, 0x0000001c},
-       {0x000610ab, 0x00000018},
-       {0x844075bd, 0x00000002},
-       {0x000610aa, 0x00000018},
-       {0x840075bb, 0x00000002},
-       {0x000610ab, 0x00000018},
-       {0x844075bc, 0x00000002},
-       {0x000000c9, 0x00000004},
-       {0x804075bd, 0x00000002},
-       {0x800075bb, 0x00000002},
-       {0x804075bc, 0x00000002},
-       {0x00108000, 0x00000002},
-       {0x01400000, 0x00000002},
-       {0x006000cd, 0x0000000c},
-       {0x20c07000, 0x00000020},
-       {0x000000cf, 0x00000012},
-       {0x00800000, 0x00000006},
-       {0x0080751d, 0x00000006},
-       {0000000000, 0000000000},
-       {0x0000775c, 0x00000002},
-       {0x00a05000, 0x00000002},
-       {0x00661000, 0x00000002},
-       {0x0460275d, 0x00000020},
-       {0x00004000, 0000000000},
-       {0x01e00830, 0x00000002},
-       {0x21007000, 0000000000},
-       {0x6464614d, 0000000000},
-       {0x69687420, 0000000000},
-       {0x00000073, 0000000000},
-       {0000000000, 0000000000},
-       {0x00005000, 0x00000002},
-       {0x000380d0, 0x00000002},
-       {0x040025e0, 0x00000002},
-       {0x000075e1, 0000000000},
-       {0x00000001, 0000000000},
-       {0x000380e0, 0x00000002},
-       {0x04002394, 0x00000002},
-       {0x00005000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0x00000008, 0000000000},
-       {0x00000004, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-};
-
-static const u32 R300_cp_microcode[][2] = {
-       {0x4200e000, 0000000000},
-       {0x4000e000, 0000000000},
-       {0x000000af, 0x00000008},
-       {0x000000b3, 0x00000008},
-       {0x6c5a504f, 0000000000},
-       {0x4f4f497a, 0000000000},
-       {0x5a578288, 0000000000},
-       {0x4f91906a, 0000000000},
-       {0x4f4f4f4f, 0000000000},
-       {0x4fe24f44, 0000000000},
-       {0x4f9c9c9c, 0000000000},
-       {0xdc4f4fde, 0000000000},
-       {0xa1cd4f4f, 0000000000},
-       {0xd29d9d9d, 0000000000},
-       {0x4f0f9fd7, 0000000000},
-       {0x000ca000, 0x00000004},
-       {0x000d0012, 0x00000038},
-       {0x0000e8b4, 0x00000004},
-       {0x000d0014, 0x00000038},
-       {0x0000e8b6, 0x00000004},
-       {0x000d0016, 0x00000038},
-       {0x0000e854, 0x00000004},
-       {0x000d0018, 0x00000038},
-       {0x0000e855, 0x00000004},
-       {0x000d001a, 0x00000038},
-       {0x0000e856, 0x00000004},
-       {0x000d001c, 0x00000038},
-       {0x0000e857, 0x00000004},
-       {0x000d001e, 0x00000038},
-       {0x0000e824, 0x00000004},
-       {0x000d0020, 0x00000038},
-       {0x0000e825, 0x00000004},
-       {0x000d0022, 0x00000038},
-       {0x0000e830, 0x00000004},
-       {0x000d0024, 0x00000038},
-       {0x0000f0c0, 0x00000004},
-       {0x000d0026, 0x00000038},
-       {0x0000f0c1, 0x00000004},
-       {0x000d0028, 0x00000038},
-       {0x0000f041, 0x00000004},
-       {0x000d002a, 0x00000038},
-       {0x0000f184, 0x00000004},
-       {0x000d002c, 0x00000038},
-       {0x0000f185, 0x00000004},
-       {0x000d002e, 0x00000038},
-       {0x0000f186, 0x00000004},
-       {0x000d0030, 0x00000038},
-       {0x0000f187, 0x00000004},
-       {0x000d0032, 0x00000038},
-       {0x0000f180, 0x00000004},
-       {0x000d0034, 0x00000038},
-       {0x0000f393, 0x00000004},
-       {0x000d0036, 0x00000038},
-       {0x0000f38a, 0x00000004},
-       {0x000d0038, 0x00000038},
-       {0x0000f38e, 0x00000004},
-       {0x0000e821, 0x00000004},
-       {0x0140a000, 0x00000004},
-       {0x00000043, 0x00000018},
-       {0x00cce800, 0x00000004},
-       {0x001b0001, 0x00000004},
-       {0x08004800, 0x00000004},
-       {0x001b0001, 0x00000004},
-       {0x08004800, 0x00000004},
-       {0x001b0001, 0x00000004},
-       {0x08004800, 0x00000004},
-       {0x0000003a, 0x00000008},
-       {0x0000a000, 0000000000},
-       {0x02c0a000, 0x00000004},
-       {0x000ca000, 0x00000004},
-       {0x00130000, 0x00000004},
-       {0x000c2000, 0x00000004},
-       {0xc980c045, 0x00000008},
-       {0x2000451d, 0x00000004},
-       {0x0000e580, 0x00000004},
-       {0x000ce581, 0x00000004},
-       {0x08004580, 0x00000004},
-       {0x000ce581, 0x00000004},
-       {0x0000004c, 0x00000008},
-       {0x0000a000, 0000000000},
-       {0x000c2000, 0x00000004},
-       {0x0000e50e, 0x00000004},
-       {0x00032000, 0x00000004},
-       {0x00022056, 0x00000028},
-       {0x00000056, 0x00000024},
-       {0x0800450f, 0x00000004},
-       {0x0000a050, 0x00000008},
-       {0x0000e565, 0x00000004},
-       {0x0000e566, 0x00000004},
-       {0x00000057, 0x00000008},
-       {0x03cca5b4, 0x00000004},
-       {0x05432000, 0x00000004},
-       {0x00022000, 0x00000004},
-       {0x4ccce063, 0x00000030},
-       {0x08274565, 0x00000004},
-       {0x00000063, 0x00000030},
-       {0x08004564, 0x00000004},
-       {0x0000e566, 0x00000004},
-       {0x0000005a, 0x00000008},
-       {0x00802066, 0x00000010},
-       {0x00202000, 0x00000004},
-       {0x001b00ff, 0x00000004},
-       {0x01000069, 0x00000010},
-       {0x001f2000, 0x00000004},
-       {0x001c00ff, 0x00000004},
-       {0000000000, 0x0000000c},
-       {0x00000085, 0x00000030},
-       {0x0000005a, 0x00000008},
-       {0x0000e576, 0x00000004},
-       {0x000ca000, 0x00000004},
-       {0x00012000, 0x00000004},
-       {0x00082000, 0x00000004},
-       {0x1800650e, 0x00000004},
-       {0x00092000, 0x00000004},
-       {0x000a2000, 0x00000004},
-       {0x000f0000, 0x00000004},
-       {0x00400000, 0x00000004},
-       {0x00000079, 0x00000018},
-       {0x0000e563, 0x00000004},
-       {0x00c0e5f9, 0x000000c2},
-       {0x0000006e, 0x00000008},
-       {0x0000a06e, 0x00000008},
-       {0x0000e576, 0x00000004},
-       {0x0000e577, 0x00000004},
-       {0x0000e50e, 0x00000004},
-       {0x0000e50f, 0x00000004},
-       {0x0140a000, 0x00000004},
-       {0x0000007c, 0x00000018},
-       {0x00c0e5f9, 0x000000c2},
-       {0x0000007c, 0x00000008},
-       {0x0014e50e, 0x00000004},
-       {0x0040e50f, 0x00000004},
-       {0x00c0007f, 0x00000008},
-       {0x0000e570, 0x00000004},
-       {0x0000e571, 0x00000004},
-       {0x0000e572, 0x0000000c},
-       {0x0000a000, 0x00000004},
-       {0x0140a000, 0x00000004},
-       {0x0000e568, 0x00000004},
-       {0x000c2000, 0x00000004},
-       {0x00000089, 0x00000018},
-       {0x000b0000, 0x00000004},
-       {0x18c0e562, 0x00000004},
-       {0x0000008b, 0x00000008},
-       {0x00c0008a, 0x00000008},
-       {0x000700e4, 0x00000004},
-       {0x00000097, 0x00000038},
-       {0x000ca099, 0x00000030},
-       {0x080045bb, 0x00000004},
-       {0x000c209a, 0x00000030},
-       {0x0800e5bc, 0000000000},
-       {0x0000e5bb, 0x00000004},
-       {0x0000e5bc, 0000000000},
-       {0x00120000, 0x0000000c},
-       {0x00120000, 0x00000004},
-       {0x001b0002, 0x0000000c},
-       {0x0000a000, 0x00000004},
-       {0x0000e821, 0x00000004},
-       {0x0000e800, 0000000000},
-       {0x0000e821, 0x00000004},
-       {0x0000e82e, 0000000000},
-       {0x02cca000, 0x00000004},
-       {0x00140000, 0x00000004},
-       {0x000ce1cc, 0x00000004},
-       {0x050de1cd, 0x00000004},
-       {0x000000a7, 0x00000020},
-       {0x4200e000, 0000000000},
-       {0x000000ae, 0x00000038},
-       {0x000ca000, 0x00000004},
-       {0x00140000, 0x00000004},
-       {0x000c2000, 0x00000004},
-       {0x00160000, 0x00000004},
-       {0x700ce000, 0x00000004},
-       {0x001400aa, 0x00000008},
-       {0x4000e000, 0000000000},
-       {0x02400000, 0x00000004},
-       {0x400ee000, 0x00000004},
-       {0x02400000, 0x00000004},
-       {0x4000e000, 0000000000},
-       {0x000c2000, 0x00000004},
-       {0x0240e51b, 0x00000004},
-       {0x0080e50a, 0x00000005},
-       {0x0080e50b, 0x00000005},
-       {0x00220000, 0x00000004},
-       {0x000700e4, 0x00000004},
-       {0x000000c1, 0x00000038},
-       {0x000c209a, 0x00000030},
-       {0x0880e5bd, 0x00000005},
-       {0x000c2099, 0x00000030},
-       {0x0800e5bb, 0x00000005},
-       {0x000c209a, 0x00000030},
-       {0x0880e5bc, 0x00000005},
-       {0x000000c4, 0x00000008},
-       {0x0080e5bd, 0x00000005},
-       {0x0000e5bb, 0x00000005},
-       {0x0080e5bc, 0x00000005},
-       {0x00210000, 0x00000004},
-       {0x02800000, 0x00000004},
-       {0x00c000c8, 0x00000018},
-       {0x4180e000, 0x00000040},
-       {0x000000ca, 0x00000024},
-       {0x01000000, 0x0000000c},
-       {0x0100e51d, 0x0000000c},
-       {0x000045bb, 0x00000004},
-       {0x000080c4, 0x00000008},
-       {0x0000f3ce, 0x00000004},
-       {0x0140a000, 0x00000004},
-       {0x00cc2000, 0x00000004},
-       {0x08c053cf, 0x00000040},
-       {0x00008000, 0000000000},
-       {0x0000f3d2, 0x00000004},
-       {0x0140a000, 0x00000004},
-       {0x00cc2000, 0x00000004},
-       {0x08c053d3, 0x00000040},
-       {0x00008000, 0000000000},
-       {0x0000f39d, 0x00000004},
-       {0x0140a000, 0x00000004},
-       {0x00cc2000, 0x00000004},
-       {0x08c0539e, 0x00000040},
-       {0x00008000, 0000000000},
-       {0x03c00830, 0x00000004},
-       {0x4200e000, 0000000000},
-       {0x0000a000, 0x00000004},
-       {0x200045e0, 0x00000004},
-       {0x0000e5e1, 0000000000},
-       {0x00000001, 0000000000},
-       {0x000700e1, 0x00000004},
-       {0x0800e394, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-       {0000000000, 0000000000},
-};
-
-static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
 {
        u32 ret;
        RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
@@ -825,21 +50,41 @@ static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
        return ret;
 }
 
+static u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+       u32 ret;
+       RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff);
+       ret = RADEON_READ(RS480_NB_MC_DATA);
+       RADEON_WRITE(RS480_NB_MC_INDEX, 0xff);
+       return ret;
+}
+
 static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
 {
+       u32 ret;
        RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
-       return RADEON_READ(RS690_MC_DATA);
+       ret = RADEON_READ(RS690_MC_DATA);
+       RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
+       return ret;
+}
+
+static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+               return RS690_READ_MCIND(dev_priv, addr);
+       else
+               return RS480_READ_MCIND(dev_priv, addr);
 }
 
 u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
 {
 
        if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
-               return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
+               return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
        else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
                return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
        else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
-               return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
+               return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
        else
                return RADEON_READ(RADEON_MC_FB_LOCATION);
 }
@@ -847,11 +92,11 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
 static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
 {
        if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
-               RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
+               R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
        else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
                RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
        else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
-               RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
+               R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
        else
                RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
 }
@@ -859,15 +104,39 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
 static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
 {
        if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
-               RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
+               R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
        else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
                RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
        else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
-               RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
+               R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
        else
                RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
 }
 
+static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
+{
+       u32 agp_base_hi = upper_32_bits(agp_base);
+       u32 agp_base_lo = agp_base & 0xffffffff;
+
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
+               R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
+               R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
+       } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
+               RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
+               RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
+       } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
+               R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
+               R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
+       } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480) {
+               RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
+               RADEON_WRITE(RS480_AGP_BASE_2, 0);
+       } else {
+               RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
+               if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200)
+                       RADEON_WRITE(RADEON_AGP_BASE_2, agp_base_hi);
+       }
+}
+
 static int RADEON_READ_PLL(struct drm_device * dev, int addr)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -882,15 +151,6 @@ static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
        return RADEON_READ(RADEON_PCIE_DATA);
 }
 
-static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
-{
-       u32 ret;
-       RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f);
-       ret = RADEON_READ(RADEON_IGPGART_DATA);
-       RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f);
-       return ret;
-}
-
 #if RADEON_FIFO_DEBUG
 static void radeon_status(drm_radeon_private_t * dev_priv)
 {
@@ -925,16 +185,36 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
 
        dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
 
-       tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT);
-       tmp |= RADEON_RB3D_DC_FLUSH_ALL;
-       RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {
+               tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT);
+               tmp |= RADEON_RB3D_DC_FLUSH_ALL;
+               RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);
 
-       for (i = 0; i < dev_priv->usec_timeout; i++) {
-               if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
-                     & RADEON_RB3D_DC_BUSY)) {
-                       return 0;
+               for (i = 0; i < dev_priv->usec_timeout; i++) {
+                       if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
+                             & RADEON_RB3D_DC_BUSY)) {
+                               return 0;
+                       }
+                       DRM_UDELAY(1);
+               }
+       } else {
+               /* 3D */
+               tmp = RADEON_READ(R300_RB3D_DSTCACHE_CTLSTAT);
+               tmp |= RADEON_RB3D_DC_FLUSH_ALL;
+               RADEON_WRITE(R300_RB3D_DSTCACHE_CTLSTAT, tmp);
+
+               /* 2D */
+               tmp = RADEON_READ(R300_DSTCACHE_CTLSTAT);
+               tmp |= RADEON_RB3D_DC_FLUSH_ALL;
+               RADEON_WRITE(R300_DSTCACHE_CTLSTAT, tmp);
+
+               for (i = 0; i < dev_priv->usec_timeout; i++) {
+                       if (!(RADEON_READ(R300_DSTCACHE_CTLSTAT)
+                         & RADEON_RB3D_DC_BUSY)) {
+                               return 0;
+                       }
+                       DRM_UDELAY(1);
                }
-               DRM_UDELAY(1);
        }
 
 #if RADEON_FIFO_DEBUG
@@ -991,6 +271,50 @@ 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)
+{
+       uint32_t gb_tile_config, gb_pipe_sel = 0;
+
+       /* RS4xx/RS6xx/R4xx/R5xx */
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
+               gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
+               dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+       } else {
+               /* R3xx */
+               if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
+                   ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
+                       dev_priv->num_gb_pipes = 2;
+               } else {
+                       /* R3Vxx */
+                       dev_priv->num_gb_pipes = 1;
+               }
+       }
+       DRM_INFO("Num pipes: %d\n", dev_priv->num_gb_pipes);
+
+       gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/);
+
+       switch (dev_priv->num_gb_pipes) {
+       case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+       case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+       case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+       default:
+       case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
+       }
+
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
+               RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+               RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
+       }
+       RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
+       radeon_do_wait_for_idle(dev_priv);
+       RADEON_WRITE(R300_DST_PIPE_CONFIG, RADEON_READ(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
+       RADEON_WRITE(R300_RB2D_DSTCACHE_MODE, (RADEON_READ(R300_RB2D_DSTCACHE_MODE) |
+                                              R300_DC_AUTOFLUSH_ENABLE |
+                                              R300_DC_DC_DISABLE_IGNORE_PE));
+
+
+}
+
 /* ================================================================
  * CP control, initialization
  */
@@ -1004,8 +328,22 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
        radeon_do_wait_for_idle(dev_priv);
 
        RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
-
-       if (dev_priv->microcode_version == UCODE_R200) {
+       if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) ||
+           ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) ||
+           ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) ||
+           ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) ||
+           ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) {
+               DRM_INFO("Loading R100 Microcode\n");
+               for (i = 0; i < 256; i++) {
+                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+                                    R100_cp_microcode[i][1]);
+                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+                                    R100_cp_microcode[i][0]);
+               }
+       } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) {
                DRM_INFO("Loading R200 Microcode\n");
                for (i = 0; i < 256; i++) {
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
@@ -1013,7 +351,11 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
                                     R200_cp_microcode[i][0]);
                }
-       } else if (dev_priv->microcode_version == UCODE_R300) {
+       } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
                DRM_INFO("Loading R300 Microcode\n");
                for (i = 0; i < 256; i++) {
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
@@ -1021,12 +363,35 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
                                     R300_cp_microcode[i][0]);
                }
-       } else {
+       } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) {
+               DRM_INFO("Loading R400 Microcode\n");
                for (i = 0; i < 256; i++) {
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
-                                    radeon_cp_microcode[i][1]);
+                                    R420_cp_microcode[i][1]);
                        RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
-                                    radeon_cp_microcode[i][0]);
+                                    R420_cp_microcode[i][0]);
+               }
+       } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
+               DRM_INFO("Loading RS690 Microcode\n");
+               for (i = 0; i < 256; i++) {
+                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+                                    RS690_cp_microcode[i][1]);
+                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+                                    RS690_cp_microcode[i][0]);
+               }
+       } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R580) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) ||
+                  ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) {
+               DRM_INFO("Loading R500 Microcode\n");
+               for (i = 0; i < 256; i++) {
+                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+                                    R520_cp_microcode[i][1]);
+                       RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+                                    R520_cp_microcode[i][0]);
                }
        }
 }
@@ -1121,12 +486,13 @@ static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
 static int radeon_do_engine_reset(struct drm_device * dev)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
-       u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+       u32 clock_cntl_index = 0, mclk_cntl = 0, rbbm_soft_reset;
        DRM_DEBUG("\n");
 
        radeon_do_pixcache_flush(dev_priv);
 
-       if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
+               /* may need something similar for newer chips */
                clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
                mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
 
@@ -1137,33 +503,39 @@ static int radeon_do_engine_reset(struct drm_device * dev)
                                                    RADEON_FORCEON_YCLKB |
                                                    RADEON_FORCEON_MC |
                                                    RADEON_FORCEON_AIC));
+       }
 
-               rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
-
-               RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
-                                                     RADEON_SOFT_RESET_CP |
-                                                     RADEON_SOFT_RESET_HI |
-                                                     RADEON_SOFT_RESET_SE |
-                                                     RADEON_SOFT_RESET_RE |
-                                                     RADEON_SOFT_RESET_PP |
-                                                     RADEON_SOFT_RESET_E2 |
-                                                     RADEON_SOFT_RESET_RB));
-               RADEON_READ(RADEON_RBBM_SOFT_RESET);
-               RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
-                                                     ~(RADEON_SOFT_RESET_CP |
-                                                       RADEON_SOFT_RESET_HI |
-                                                       RADEON_SOFT_RESET_SE |
-                                                       RADEON_SOFT_RESET_RE |
-                                                       RADEON_SOFT_RESET_PP |
-                                                       RADEON_SOFT_RESET_E2 |
-                                                       RADEON_SOFT_RESET_RB)));
-               RADEON_READ(RADEON_RBBM_SOFT_RESET);
-
+       rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+       RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
+                                             RADEON_SOFT_RESET_CP |
+                                             RADEON_SOFT_RESET_HI |
+                                             RADEON_SOFT_RESET_SE |
+                                             RADEON_SOFT_RESET_RE |
+                                             RADEON_SOFT_RESET_PP |
+                                             RADEON_SOFT_RESET_E2 |
+                                             RADEON_SOFT_RESET_RB));
+       RADEON_READ(RADEON_RBBM_SOFT_RESET);
+       RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
+                                             ~(RADEON_SOFT_RESET_CP |
+                                               RADEON_SOFT_RESET_HI |
+                                               RADEON_SOFT_RESET_SE |
+                                               RADEON_SOFT_RESET_RE |
+                                               RADEON_SOFT_RESET_PP |
+                                               RADEON_SOFT_RESET_E2 |
+                                               RADEON_SOFT_RESET_RB)));
+       RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
                RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
                RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
                RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
        }
 
+       /* setup the raster pipes */
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
+           radeon_init_pipes(dev_priv);
+
        /* Reset the CP ring */
        radeon_do_cp_reset(dev_priv);
 
@@ -1194,7 +566,8 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
 
 #if __OS_HAS_AGP
        if (dev_priv->flags & RADEON_IS_AGP) {
-               RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
+               radeon_write_agp_base(dev_priv, dev->agp->base);
+
                radeon_write_agp_location(dev_priv,
                             (((dev_priv->gart_vm_start - 1 +
                                dev_priv->gart_size) & 0xffff0000) |
@@ -1338,103 +711,71 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
 
 /* Enable or disable IGP GART on the chip */
 static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
-{
-       u32 temp, tmp;
-
-       tmp = RADEON_READ(RADEON_AIC_CNTL);
-       if (on) {
-               DRM_DEBUG("programming igpgart %08X %08lX %08X\n",
-                        dev_priv->gart_vm_start,
-                        (long)dev_priv->gart_info.bus_addr,
-                        dev_priv->gart_size);
-
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000);
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1);
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800);
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR,
-                                    dev_priv->gart_info.bus_addr);
-
-               temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39);
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp);
-
-               RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
-               dev_priv->gart_size = 32*1024*1024;
-               radeon_write_agp_location(dev_priv,
-                            (((dev_priv->gart_vm_start - 1 +
-                              dev_priv->gart_size) & 0xffff0000) |
-                            (dev_priv->gart_vm_start >> 16)));
-
-               temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE);
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp);
-
-               RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1);
-               RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
-               RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0);
-       }
-}
-
-/* Enable or disable RS690 GART on the chip */
-static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on)
 {
        u32 temp;
 
        if (on) {
-               DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n",
+               DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
                          dev_priv->gart_vm_start,
                          (long)dev_priv->gart_info.bus_addr,
                          dev_priv->gart_size);
 
-               temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL);
-               RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000);
+               temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL);
+               if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+                       IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN |
+                                                            RS690_BLOCK_GFX_D3_EN));
+               else
+                       IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN);
 
-               RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
-                                 RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
+               IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
+                                                              RS480_VA_SIZE_32MB));
 
-               temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID);
-               RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800);
+               temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID);
+               IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN |
+                                                       RS480_TLB_ENABLE |
+                                                       RS480_GTW_LAC_EN |
+                                                       RS480_1LEVEL_GART));
 
-               RS690_WRITE_MCIND(RS690_MC_GART_BASE,
-                                 dev_priv->gart_info.bus_addr);
+               temp = dev_priv->gart_info.bus_addr & 0xfffff000;
+               temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4;
+               IGP_WRITE_MCIND(RS480_GART_BASE, temp);
 
-               temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL);
-               RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000);
+               temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL);
+               IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) |
+                                                     RS480_REQ_TYPE_SNOOP_DIS));
 
-               RS690_WRITE_MCIND(RS690_MC_AGP_BASE,
-                                 (unsigned int)dev_priv->gart_vm_start);
+               radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start);
 
                dev_priv->gart_size = 32*1024*1024;
                temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
                         0xffff0000) | (dev_priv->gart_vm_start >> 16));
 
-               RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp);
+               radeon_write_agp_location(dev_priv, temp);
 
-               temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE);
-               RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
-                                 RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
+               temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE);
+               IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
+                                                              RS480_VA_SIZE_32MB));
 
                do {
-                       temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
-                       if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
-                           RS690_MC_GART_CLEAR_DONE)
+                       temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
+                       if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
                                break;
                        DRM_UDELAY(1);
                } while (1);
 
-               RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
-                                 RS690_MC_GART_CC_CLEAR);
+               IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL,
+                               RS480_GART_CACHE_INVALIDATE);
+
                do {
-                       temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
-                       if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
-                                  RS690_MC_GART_CLEAR_DONE)
+                       temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
+                       if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
                                break;
                        DRM_UDELAY(1);
                } while (1);
 
-               RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
-                                 RS690_MC_GART_CC_NO_CHANGE);
+               IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0);
        } else {
-               RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS);
+               IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
        }
 }
 
@@ -1472,12 +813,8 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
 {
        u32 tmp;
 
-       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
-               radeon_set_rs690gart(dev_priv, on);
-               return;
-       }
-
-       if (dev_priv->flags & RADEON_IS_IGPGART) {
+       if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+           (dev_priv->flags & RADEON_IS_IGPGART)) {
                radeon_set_igpgart(dev_priv, on);
                return;
        }
@@ -1951,6 +1288,7 @@ static int radeon_do_resume_cp(struct drm_device * dev)
        radeon_cp_init_ring_buffer(dev, dev_priv);
 
        radeon_do_engine_reset(dev);
+       radeon_enable_interrupt(dev);
 
        DRM_DEBUG("radeon_do_resume_cp() complete\n");
 
index aab82e121e07935a4f169f1bb36a43d1eba1479e..73ff51f12311ea967a1e8497967aa0c20e95336c 100644 (file)
@@ -240,6 +240,7 @@ typedef union {
 #      define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN    0x8
 
 #define R300_CMD_SCRATCH               8
+#define R300_CMD_R500FP                 9
 
 typedef union {
        unsigned int u;
@@ -268,6 +269,9 @@ typedef union {
        struct {
                unsigned char cmd_type, reg, n_bufs, flags;
        } scratch;
+       struct {
+               unsigned char cmd_type, count, adrlo, adrhi_flags;
+       } r500fp;
 } drm_r300_cmd_header_t;
 
 #define RADEON_FRONT                   0x1
@@ -278,6 +282,9 @@ typedef union {
 #define RADEON_USE_HIERZ               0x40000000
 #define RADEON_USE_COMP_ZBUF           0x20000000
 
+#define R500FP_CONSTANT_TYPE  (1 << 1)
+#define R500FP_CONSTANT_CLAMP (1 << 2)
+
 /* Primitive types
  */
 #define RADEON_POINTS                  0x1
@@ -669,6 +676,7 @@ typedef struct drm_radeon_indirect {
 #define RADEON_PARAM_CARD_TYPE             12
 #define RADEON_PARAM_VBLANK_CRTC           13   /* VBLANK CRTC */
 #define RADEON_PARAM_FB_LOCATION           14   /* FB location */
+#define RADEON_PARAM_NUM_GB_PIPES          15   /* num GB pipes */
 
 typedef struct drm_radeon_getparam {
        int param;
index 173ae620223a052238a0a212711e25290bff4f0c..3f0eca957aa7cfff93640a7db1bedab8f02016b3 100644 (file)
@@ -38,7 +38,7 @@
 
 #define DRIVER_NAME            "radeon"
 #define DRIVER_DESC            "ATI Radeon"
-#define DRIVER_DATE            "20060524"
+#define DRIVER_DATE            "20080528"
 
 /* Interface history:
  *
  * 1.26- Add support for variable size PCI(E) gart aperture
  * 1.27- Add support for IGP GART
  * 1.28- Add support for VBL on CRTC2
+ * 1.29- R500 3D cmd buffer support
  */
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           28
+#define DRIVER_MINOR           29
 #define DRIVER_PATCHLEVEL      0
 
 /*
@@ -122,7 +123,7 @@ enum radeon_family {
        CHIP_RV380,
        CHIP_R420,
        CHIP_RV410,
-       CHIP_RS400,
+       CHIP_RS480,
        CHIP_RS690,
        CHIP_RV515,
        CHIP_R520,
@@ -294,6 +295,7 @@ typedef struct drm_radeon_private {
        int vblank_crtc;
        uint32_t irq_enable_reg;
        int irq_enabled;
+       uint32_t r500_disp_irq_reg;
 
        struct radeon_surface surfaces[RADEON_MAX_SURFACES];
        struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
@@ -307,6 +309,8 @@ typedef struct drm_radeon_private {
        /* starting from here on, data is preserved accross an open */
        uint32_t flags;         /* see radeon_chip_flags */
        unsigned long fb_aper_offset;
+
+       int num_gb_pipes;
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
@@ -382,6 +386,7 @@ extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
 extern void radeon_driver_irq_preinstall(struct drm_device * dev);
 extern void radeon_driver_irq_postinstall(struct drm_device * dev);
 extern void radeon_driver_irq_uninstall(struct drm_device * dev);
+extern void radeon_enable_interrupt(struct drm_device *dev);
 extern int radeon_vblank_crtc_get(struct drm_device *dev);
 extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
 
@@ -444,13 +449,13 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 #define RADEON_PCIE_DATA                0x0034
 #define RADEON_PCIE_TX_GART_CNTL       0x10
 #      define RADEON_PCIE_TX_GART_EN           (1 << 0)
-#      define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1)
-#      define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO  (1<<1)
-#      define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD   (3<<1)
-#      define RADEON_PCIE_TX_GART_MODE_32_128_CACHE    (0<<3)
-#      define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE   (1<<3)
-#      define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN      (1<<5)
-#      define RADEON_PCIE_TX_GART_INVALIDATE_TLB       (1<<8)
+#      define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0 << 1)
+#      define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO  (1 << 1)
+#      define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD   (3 << 1)
+#      define RADEON_PCIE_TX_GART_MODE_32_128_CACHE    (0 << 3)
+#      define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE   (1 << 3)
+#      define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN      (1 << 5)
+#      define RADEON_PCIE_TX_GART_INVALIDATE_TLB       (1 << 8)
 #define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11
 #define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12
 #define RADEON_PCIE_TX_GART_BASE       0x13
@@ -459,14 +464,9 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 #define RADEON_PCIE_TX_GART_END_LO     0x16
 #define RADEON_PCIE_TX_GART_END_HI     0x17
 
-#define RADEON_IGPGART_INDEX            0x168
-#define RADEON_IGPGART_DATA             0x16c
-#define RADEON_IGPGART_UNK_18           0x18
-#define RADEON_IGPGART_CTRL             0x2b
-#define RADEON_IGPGART_BASE_ADDR        0x2c
-#define RADEON_IGPGART_FLUSH            0x2e
-#define RADEON_IGPGART_ENABLE           0x38
-#define RADEON_IGPGART_UNK_39           0x39
+#define RS480_NB_MC_INDEX               0x168
+#      define RS480_NB_MC_IND_WR_EN    (1 << 8)
+#define RS480_NB_MC_DATA                0x16c
 
 #define RS690_MC_INDEX                  0x78
 #   define RS690_MC_INDEX_MASK          0x1ff
@@ -474,45 +474,91 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 #   define RS690_MC_INDEX_WR_ACK        0x7f
 #define RS690_MC_DATA                   0x7c
 
-#define RS690_MC_MISC_CNTL              0x18
-#define RS690_MC_GART_FEATURE_ID        0x2b
-#define RS690_MC_GART_BASE              0x2c
-#define RS690_MC_GART_CACHE_CNTL       0x2e
-#   define RS690_MC_GART_CC_NO_CHANGE   0x0
-#   define RS690_MC_GART_CC_CLEAR       0x1
-#   define RS690_MC_GART_CLEAR_STATUS   (1 << 1)
-#       define RS690_MC_GART_CLEAR_DONE     (0 << 1)
-#       define RS690_MC_GART_CLEAR_PENDING  (1 << 1)
-#define RS690_MC_AGP_SIZE               0x38
-#   define RS690_MC_GART_DIS            0x0
-#   define RS690_MC_GART_EN             0x1
-#   define RS690_MC_AGP_SIZE_32MB       (0 << 1)
-#   define RS690_MC_AGP_SIZE_64MB       (1 << 1)
-#   define RS690_MC_AGP_SIZE_128MB      (2 << 1)
-#   define RS690_MC_AGP_SIZE_256MB      (3 << 1)
-#   define RS690_MC_AGP_SIZE_512MB      (4 << 1)
-#   define RS690_MC_AGP_SIZE_1GB        (5 << 1)
-#   define RS690_MC_AGP_SIZE_2GB        (6 << 1)
-#define RS690_MC_AGP_MODE_CONTROL       0x39
+/* MC indirect registers */
+#define RS480_MC_MISC_CNTL              0x18
+#      define RS480_DISABLE_GTW        (1 << 1)
+/* switch between MCIND GART and MM GART registers. 0 = mmgart, 1 = mcind gart */
+#      define RS480_GART_INDEX_REG_EN  (1 << 12)
+#      define RS690_BLOCK_GFX_D3_EN    (1 << 14)
+#define RS480_K8_FB_LOCATION            0x1e
+#define RS480_GART_FEATURE_ID           0x2b
+#      define RS480_HANG_EN            (1 << 11)
+#      define RS480_TLB_ENABLE         (1 << 18)
+#      define RS480_P2P_ENABLE         (1 << 19)
+#      define RS480_GTW_LAC_EN         (1 << 25)
+#      define RS480_2LEVEL_GART        (0 << 30)
+#      define RS480_1LEVEL_GART        (1 << 30)
+#      define RS480_PDC_EN             (1 << 31)
+#define RS480_GART_BASE                 0x2c
+#define RS480_GART_CACHE_CNTRL          0x2e
+#      define RS480_GART_CACHE_INVALIDATE (1 << 0) /* wait for it to clear */
+#define RS480_AGP_ADDRESS_SPACE_SIZE    0x38
+#      define RS480_GART_EN            (1 << 0)
+#      define RS480_VA_SIZE_32MB       (0 << 1)
+#      define RS480_VA_SIZE_64MB       (1 << 1)
+#      define RS480_VA_SIZE_128MB      (2 << 1)
+#      define RS480_VA_SIZE_256MB      (3 << 1)
+#      define RS480_VA_SIZE_512MB      (4 << 1)
+#      define RS480_VA_SIZE_1GB        (5 << 1)
+#      define RS480_VA_SIZE_2GB        (6 << 1)
+#define RS480_AGP_MODE_CNTL             0x39
+#      define RS480_POST_GART_Q_SIZE   (1 << 18)
+#      define RS480_NONGART_SNOOP      (1 << 19)
+#      define RS480_AGP_RD_BUF_SIZE    (1 << 20)
+#      define RS480_REQ_TYPE_SNOOP_SHIFT 22
+#      define RS480_REQ_TYPE_SNOOP_MASK  0x3
+#      define RS480_REQ_TYPE_SNOOP_DIS (1 << 24)
+#define RS480_MC_MISC_UMA_CNTL          0x5f
+#define RS480_MC_MCLK_CNTL              0x7a
+#define RS480_MC_UMA_DUALCH_CNTL        0x86
+
 #define RS690_MC_FB_LOCATION            0x100
 #define RS690_MC_AGP_LOCATION           0x101
 #define RS690_MC_AGP_BASE               0x102
+#define RS690_MC_AGP_BASE_2             0x103
 
 #define R520_MC_IND_INDEX 0x70
-#define R520_MC_IND_WR_EN (1<<24)
+#define R520_MC_IND_WR_EN (1 << 24)
 #define R520_MC_IND_DATA  0x74
 
 #define RV515_MC_FB_LOCATION 0x01
 #define RV515_MC_AGP_LOCATION 0x02
+#define RV515_MC_AGP_BASE     0x03
+#define RV515_MC_AGP_BASE_2   0x04
 
 #define R520_MC_FB_LOCATION 0x04
 #define R520_MC_AGP_LOCATION 0x05
+#define R520_MC_AGP_BASE     0x06
+#define R520_MC_AGP_BASE_2   0x07
 
 #define RADEON_MPP_TB_CONFIG           0x01c0
 #define RADEON_MEM_CNTL                        0x0140
 #define RADEON_MEM_SDRAM_MODE_REG      0x0158
+#define RADEON_AGP_BASE_2              0x015c /* r200+ only */
+#define RS480_AGP_BASE_2               0x0164
 #define RADEON_AGP_BASE                        0x0170
 
+/* pipe config regs */
+#define R400_GB_PIPE_SELECT             0x402c
+#define R500_DYN_SCLK_PWMEM_PIPE        0x000d /* PLL */
+#define R500_SU_REG_DEST                0x42c8
+#define R300_GB_TILE_CONFIG             0x4018
+#       define R300_ENABLE_TILING       (1 << 0)
+#       define R300_PIPE_COUNT_RV350    (0 << 1)
+#       define R300_PIPE_COUNT_R300     (3 << 1)
+#       define R300_PIPE_COUNT_R420_3P  (6 << 1)
+#       define R300_PIPE_COUNT_R420     (7 << 1)
+#       define R300_TILE_SIZE_8         (0 << 4)
+#       define R300_TILE_SIZE_16        (1 << 4)
+#       define R300_TILE_SIZE_32        (2 << 4)
+#       define R300_SUBPIXEL_1_12       (0 << 16)
+#       define R300_SUBPIXEL_1_16       (1 << 16)
+#define R300_DST_PIPE_CONFIG            0x170c
+#       define R300_PIPE_AUTO_CONFIG    (1 << 31)
+#define R300_RB2D_DSTCACHE_MODE         0x3428
+#       define R300_DC_AUTOFLUSH_ENABLE (1 << 8)
+#       define R300_DC_DC_DISABLE_IGNORE_PE (1 << 17)
+
 #define RADEON_RB3D_COLOROFFSET                0x1c40
 #define RADEON_RB3D_COLORPITCH         0x1c48
 
@@ -616,11 +662,12 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 #define RADEON_PP_TXFILTER_1           0x1c6c
 #define RADEON_PP_TXFILTER_2           0x1c84
 
-#define RADEON_RB2D_DSTCACHE_CTLSTAT   0x342c
-#      define RADEON_RB2D_DC_FLUSH             (3 << 0)
-#      define RADEON_RB2D_DC_FREE              (3 << 2)
-#      define RADEON_RB2D_DC_FLUSH_ALL         0xf
-#      define RADEON_RB2D_DC_BUSY              (1 << 31)
+#define R300_RB2D_DSTCACHE_CTLSTAT     0x342c /* use R300_DSTCACHE_CTLSTAT */
+#define R300_DSTCACHE_CTLSTAT          0x1714
+#      define R300_RB2D_DC_FLUSH               (3 << 0)
+#      define R300_RB2D_DC_FREE                (3 << 2)
+#      define R300_RB2D_DC_FLUSH_ALL           0xf
+#      define R300_RB2D_DC_BUSY                (1 << 31)
 #define RADEON_RB3D_CNTL               0x1c3c
 #      define RADEON_ALPHA_BLEND_ENABLE        (1 << 0)
 #      define RADEON_PLANE_MASK_ENABLE         (1 << 1)
@@ -643,11 +690,18 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 #      define RADEON_RB3D_ZC_FREE              (1 << 2)
 #      define RADEON_RB3D_ZC_FLUSH_ALL         0x5
 #      define RADEON_RB3D_ZC_BUSY              (1 << 31)
+#define R300_ZB_ZCACHE_CTLSTAT                  0x4f18
+#      define R300_ZC_FLUSH                    (1 << 0)
+#      define R300_ZC_FREE                     (1 << 1)
+#      define R300_ZC_FLUSH_ALL                0x3
+#      define R300_ZC_BUSY                     (1 << 31)
 #define RADEON_RB3D_DSTCACHE_CTLSTAT   0x325c
 #      define RADEON_RB3D_DC_FLUSH             (3 << 0)
 #      define RADEON_RB3D_DC_FREE              (3 << 2)
 #      define RADEON_RB3D_DC_FLUSH_ALL         0xf
 #      define RADEON_RB3D_DC_BUSY              (1 << 31)
+#define R300_RB3D_DSTCACHE_CTLSTAT              0x4e4c
+#      define R300_RB3D_DC_FINISH              (1 << 4)
 #define RADEON_RB3D_ZSTENCILCNTL       0x1c2c
 #      define RADEON_Z_TEST_MASK               (7 << 4)
 #      define RADEON_Z_TEST_ALWAYS             (7 << 4)
@@ -1057,6 +1111,31 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 
 #define R200_VAP_PVS_CNTL_1               0x22D0
 
+#define R500_D1CRTC_STATUS 0x609c
+#define R500_D2CRTC_STATUS 0x689c
+#define R500_CRTC_V_BLANK (1<<0)
+
+#define R500_D1CRTC_FRAME_COUNT 0x60a4
+#define R500_D2CRTC_FRAME_COUNT 0x68a4
+
+#define R500_D1MODE_V_COUNTER 0x6530
+#define R500_D2MODE_V_COUNTER 0x6d30
+
+#define R500_D1MODE_VBLANK_STATUS 0x6534
+#define R500_D2MODE_VBLANK_STATUS 0x6d34
+#define R500_VBLANK_OCCURED (1<<0)
+#define R500_VBLANK_ACK     (1<<4)
+#define R500_VBLANK_STAT    (1<<12)
+#define R500_VBLANK_INT     (1<<16)
+
+#define R500_DxMODE_INT_MASK 0x6540
+#define R500_D1MODE_INT_MASK (1<<0)
+#define R500_D2MODE_INT_MASK (1<<8)
+
+#define R500_DISP_INTERRUPT_STATUS 0x7edc
+#define R500_D1_VBLANK_INTERRUPT (1 << 4)
+#define R500_D2_VBLANK_INTERRUPT (1 << 5)
+
 /* Constants */
 #define RADEON_MAX_USEC_TIMEOUT                100000  /* 100 ms */
 
@@ -1078,42 +1157,50 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
 #define RADEON_READ8(reg)      DRM_READ8(  dev_priv->mmio, (reg) )
 #define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
 
-#define RADEON_WRITE_PLL( addr, val )                                  \
+#define RADEON_WRITE_PLL(addr, val)                                    \
 do {                                                                   \
-       RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX,                         \
+       RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX,                          \
                       ((addr) & 0x1f) | RADEON_PLL_WR_EN );            \
-       RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) );                  \
+       RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val));                    \
 } while (0)
 
-#define RADEON_WRITE_IGPGART( addr, val )                              \
+#define RADEON_WRITE_PCIE(addr, val)                                   \
 do {                                                                   \
-       RADEON_WRITE( RADEON_IGPGART_INDEX,                             \
-                       ((addr) & 0x7f) | (1 << 8));                    \
-       RADEON_WRITE( RADEON_IGPGART_DATA, (val) );                     \
-       RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f );                     \
+       RADEON_WRITE8(RADEON_PCIE_INDEX,                                \
+                       ((addr) & 0xff));                               \
+       RADEON_WRITE(RADEON_PCIE_DATA, (val));                  \
 } while (0)
 
-#define RADEON_WRITE_PCIE( addr, val )                                 \
-do {                                                                   \
-       RADEON_WRITE8( RADEON_PCIE_INDEX,                               \
-                       ((addr) & 0xff));                               \
-       RADEON_WRITE( RADEON_PCIE_DATA, (val) );                        \
+#define R500_WRITE_MCIND(addr, val)                                    \
+do {                                                           \
+       RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff));    \
+       RADEON_WRITE(R520_MC_IND_DATA, (val));                  \
+       RADEON_WRITE(R520_MC_IND_INDEX, 0);     \
 } while (0)
 
-#define RADEON_WRITE_MCIND( addr, val )                                        \
-       do {                                                            \
-               RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff));    \
-               RADEON_WRITE(R520_MC_IND_DATA, (val));                  \
-               RADEON_WRITE(R520_MC_IND_INDEX, 0);     \
-       } while (0)
+#define RS480_WRITE_MCIND(addr, val)                           \
+do {                                                                   \
+       RADEON_WRITE(RS480_NB_MC_INDEX,                         \
+                       ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN);       \
+       RADEON_WRITE(RS480_NB_MC_DATA, (val));                  \
+       RADEON_WRITE(RS480_NB_MC_INDEX, 0xff);                  \
+} while (0)
 
-#define RS690_WRITE_MCIND( addr, val )                                 \
+#define RS690_WRITE_MCIND(addr, val)                                   \
 do {                                                           \
        RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK));    \
        RADEON_WRITE(RS690_MC_DATA, val);                       \
        RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);    \
 } while (0)
 
+#define IGP_WRITE_MCIND(addr, val)                             \
+do {                                                                   \
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)       \
+               RS690_WRITE_MCIND(addr, val);                           \
+       else                                                            \
+               RS480_WRITE_MCIND(addr, val);                           \
+} while (0)
+
 #define CP_PACKET0( reg, n )                                           \
        (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
 #define CP_PACKET0_TABLE( reg, n )                                     \
@@ -1154,23 +1241,43 @@ do {                                                            \
 } while (0)
 
 #define RADEON_FLUSH_CACHE() do {                                      \
-       OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) );      \
-       OUT_RING( RADEON_RB3D_DC_FLUSH );                               \
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {     \
+               OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0));  \
+               OUT_RING(RADEON_RB3D_DC_FLUSH);                         \
+       } else {                                                        \
+               OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));    \
+               OUT_RING(RADEON_RB3D_DC_FLUSH);                         \
+       }                                                               \
 } while (0)
 
 #define RADEON_PURGE_CACHE() do {                                      \
-       OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) );      \
-       OUT_RING( RADEON_RB3D_DC_FLUSH_ALL );                           \
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {     \
+               OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0));  \
+               OUT_RING(RADEON_RB3D_DC_FLUSH_ALL);                     \
+       } else {                                                        \
+               OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));    \
+               OUT_RING(RADEON_RB3D_DC_FLUSH_ALL);                     \
+       }                                                               \
 } while (0)
 
 #define RADEON_FLUSH_ZCACHE() do {                                     \
-       OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) );        \
-       OUT_RING( RADEON_RB3D_ZC_FLUSH );                               \
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {     \
+               OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));    \
+               OUT_RING(RADEON_RB3D_ZC_FLUSH);                         \
+       } else {                                                        \
+               OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));        \
+               OUT_RING(R300_ZC_FLUSH);                                \
+       }                                                               \
 } while (0)
 
 #define RADEON_PURGE_ZCACHE() do {                                     \
-       OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) );        \
-       OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL );                           \
+       if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {     \
+               OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));    \
+               OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL);                     \
+       } else {                                                        \
+               OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));    \
+               OUT_RING(R300_ZC_FLUSH_ALL);                            \
+       }                                                               \
 } while (0)
 
 /* ================================================================
index 009af3814b6f12ec4dcf34aff23cffff79e0d5db..ee40d197deb7e8f2f7d6568e4c3b51e376c81ca7 100644 (file)
@@ -234,7 +234,7 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
        return radeon_wait_irq(dev, irqwait->irq_seq);
 }
 
-static void radeon_enable_interrupt(struct drm_device *dev)
+void radeon_enable_interrupt(struct drm_device *dev)
 {
        drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
 
diff --git a/drivers/char/drm/radeon_microcode.h b/drivers/char/drm/radeon_microcode.h
new file mode 100644 (file)
index 0000000..a348c9e
--- /dev/null
@@ -0,0 +1,1844 @@
+/*
+ * Copyright 2007 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 RADEON_MICROCODE_H
+#define RADEON_MICROCODE_H
+
+/* production radeon ucode r1xx-r6xx */
+static const u32 R100_cp_microcode[][2] = {
+    { 0x21007000, 0000000000 },
+    { 0x20007000, 0000000000 },
+    { 0x000000b4, 0x00000004 },
+    { 0x000000b8, 0x00000004 },
+    { 0x6f5b4d4c, 0000000000 },
+    { 0x4c4c427f, 0000000000 },
+    { 0x5b568a92, 0000000000 },
+    { 0x4ca09c6d, 0000000000 },
+    { 0xad4c4c4c, 0000000000 },
+    { 0x4ce1af3d, 0000000000 },
+    { 0xd8afafaf, 0000000000 },
+    { 0xd64c4cdc, 0000000000 },
+    { 0x4cd10d10, 0000000000 },
+    { 0x000f0000, 0x00000016 },
+    { 0x362f242d, 0000000000 },
+    { 0x00000012, 0x00000004 },
+    { 0x000f0000, 0x00000016 },
+    { 0x362f282d, 0000000000 },
+    { 0x000380e7, 0x00000002 },
+    { 0x04002c97, 0x00000002 },
+    { 0x000f0001, 0x00000016 },
+    { 0x333a3730, 0000000000 },
+    { 0x000077ef, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x00000021, 0x0000001a },
+    { 0x00004000, 0x0000001e },
+    { 0x00061000, 0x00000002 },
+    { 0x00000021, 0x0000001a },
+    { 0x00004000, 0x0000001e },
+    { 0x00061000, 0x00000002 },
+    { 0x00000021, 0x0000001a },
+    { 0x00004000, 0x0000001e },
+    { 0x00000017, 0x00000004 },
+    { 0x0003802b, 0x00000002 },
+    { 0x040067e0, 0x00000002 },
+    { 0x00000017, 0x00000004 },
+    { 0x000077e0, 0x00000002 },
+    { 0x00065000, 0x00000002 },
+    { 0x000037e1, 0x00000002 },
+    { 0x040067e1, 0x00000006 },
+    { 0x000077e0, 0x00000002 },
+    { 0x000077e1, 0x00000002 },
+    { 0x000077e1, 0x00000006 },
+    { 0xffffffff, 0000000000 },
+    { 0x10000000, 0000000000 },
+    { 0x0003802b, 0x00000002 },
+    { 0x040067e0, 0x00000006 },
+    { 0x00007675, 0x00000002 },
+    { 0x00007676, 0x00000002 },
+    { 0x00007677, 0x00000002 },
+    { 0x00007678, 0x00000006 },
+    { 0x0003802c, 0x00000002 },
+    { 0x04002676, 0x00000002 },
+    { 0x00007677, 0x00000002 },
+    { 0x00007678, 0x00000006 },
+    { 0x0000002f, 0x00000018 },
+    { 0x0000002f, 0x00000018 },
+    { 0000000000, 0x00000006 },
+    { 0x00000030, 0x00000018 },
+    { 0x00000030, 0x00000018 },
+    { 0000000000, 0x00000006 },
+    { 0x01605000, 0x00000002 },
+    { 0x00065000, 0x00000002 },
+    { 0x00098000, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x64c0603e, 0x00000004 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x00080000, 0x00000016 },
+    { 0000000000, 0000000000 },
+    { 0x0400251d, 0x00000002 },
+    { 0x00007580, 0x00000002 },
+    { 0x00067581, 0x00000002 },
+    { 0x04002580, 0x00000002 },
+    { 0x00067581, 0x00000002 },
+    { 0x00000049, 0x00000004 },
+    { 0x00005000, 0000000000 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x0000750e, 0x00000002 },
+    { 0x00019000, 0x00000002 },
+    { 0x00011055, 0x00000014 },
+    { 0x00000055, 0x00000012 },
+    { 0x0400250f, 0x00000002 },
+    { 0x0000504f, 0x00000004 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x00007565, 0x00000002 },
+    { 0x00007566, 0x00000002 },
+    { 0x00000058, 0x00000004 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x01e655b4, 0x00000002 },
+    { 0x4401b0e4, 0x00000002 },
+    { 0x01c110e4, 0x00000002 },
+    { 0x26667066, 0x00000018 },
+    { 0x040c2565, 0x00000002 },
+    { 0x00000066, 0x00000018 },
+    { 0x04002564, 0x00000002 },
+    { 0x00007566, 0x00000002 },
+    { 0x0000005d, 0x00000004 },
+    { 0x00401069, 0x00000008 },
+    { 0x00101000, 0x00000002 },
+    { 0x000d80ff, 0x00000002 },
+    { 0x0080006c, 0x00000008 },
+    { 0x000f9000, 0x00000002 },
+    { 0x000e00ff, 0x00000002 },
+    { 0000000000, 0x00000006 },
+    { 0x0000008f, 0x00000018 },
+    { 0x0000005b, 0x00000004 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x00007576, 0x00000002 },
+    { 0x00065000, 0x00000002 },
+    { 0x00009000, 0x00000002 },
+    { 0x00041000, 0x00000002 },
+    { 0x0c00350e, 0x00000002 },
+    { 0x00049000, 0x00000002 },
+    { 0x00051000, 0x00000002 },
+    { 0x01e785f8, 0x00000002 },
+    { 0x00200000, 0x00000002 },
+    { 0x0060007e, 0x0000000c },
+    { 0x00007563, 0x00000002 },
+    { 0x006075f0, 0x00000021 },
+    { 0x20007073, 0x00000004 },
+    { 0x00005073, 0x00000004 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x00007576, 0x00000002 },
+    { 0x00007577, 0x00000002 },
+    { 0x0000750e, 0x00000002 },
+    { 0x0000750f, 0x00000002 },
+    { 0x00a05000, 0x00000002 },
+    { 0x00600083, 0x0000000c },
+    { 0x006075f0, 0x00000021 },
+    { 0x000075f8, 0x00000002 },
+    { 0x00000083, 0x00000004 },
+    { 0x000a750e, 0x00000002 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x0020750f, 0x00000002 },
+    { 0x00600086, 0x00000004 },
+    { 0x00007570, 0x00000002 },
+    { 0x00007571, 0x00000002 },
+    { 0x00007572, 0x00000006 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x00005000, 0x00000002 },
+    { 0x00a05000, 0x00000002 },
+    { 0x00007568, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x00000095, 0x0000000c },
+    { 0x00058000, 0x00000002 },
+    { 0x0c607562, 0x00000002 },
+    { 0x00000097, 0x00000004 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x00600096, 0x00000004 },
+    { 0x400070e5, 0000000000 },
+    { 0x000380e6, 0x00000002 },
+    { 0x040025c5, 0x00000002 },
+    { 0x000380e5, 0x00000002 },
+    { 0x000000a8, 0x0000001c },
+    { 0x000650aa, 0x00000018 },
+    { 0x040025bb, 0x00000002 },
+    { 0x000610ab, 0x00000018 },
+    { 0x040075bc, 0000000000 },
+    { 0x000075bb, 0x00000002 },
+    { 0x000075bc, 0000000000 },
+    { 0x00090000, 0x00000006 },
+    { 0x00090000, 0x00000002 },
+    { 0x000d8002, 0x00000006 },
+    { 0x00007832, 0x00000002 },
+    { 0x00005000, 0x00000002 },
+    { 0x000380e7, 0x00000002 },
+    { 0x04002c97, 0x00000002 },
+    { 0x00007820, 0x00000002 },
+    { 0x00007821, 0x00000002 },
+    { 0x00007800, 0000000000 },
+    { 0x01200000, 0x00000002 },
+    { 0x20077000, 0x00000002 },
+    { 0x01200000, 0x00000002 },
+    { 0x20007000, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x0120751b, 0x00000002 },
+    { 0x8040750a, 0x00000002 },
+    { 0x8040750b, 0x00000002 },
+    { 0x00110000, 0x00000002 },
+    { 0x000380e5, 0x00000002 },
+    { 0x000000c6, 0x0000001c },
+    { 0x000610ab, 0x00000018 },
+    { 0x844075bd, 0x00000002 },
+    { 0x000610aa, 0x00000018 },
+    { 0x840075bb, 0x00000002 },
+    { 0x000610ab, 0x00000018 },
+    { 0x844075bc, 0x00000002 },
+    { 0x000000c9, 0x00000004 },
+    { 0x804075bd, 0x00000002 },
+    { 0x800075bb, 0x00000002 },
+    { 0x804075bc, 0x00000002 },
+    { 0x00108000, 0x00000002 },
+    { 0x01400000, 0x00000002 },
+    { 0x006000cd, 0x0000000c },
+    { 0x20c07000, 0x00000020 },
+    { 0x000000cf, 0x00000012 },
+    { 0x00800000, 0x00000006 },
+    { 0x0080751d, 0x00000006 },
+    { 0000000000, 0000000000 },
+    { 0x0000775c, 0x00000002 },
+    { 0x00a05000, 0x00000002 },
+    { 0x00661000, 0x00000002 },
+    { 0x0460275d, 0x00000020 },
+    { 0x00004000, 0000000000 },
+    { 0x01e00830, 0x00000002 },
+    { 0x21007000, 0000000000 },
+    { 0x6464614d, 0000000000 },
+    { 0x69687420, 0000000000 },
+    { 0x00000073, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x00005000, 0x00000002 },
+    { 0x000380d0, 0x00000002 },
+    { 0x040025e0, 0x00000002 },
+    { 0x000075e1, 0000000000 },
+    { 0x00000001, 0000000000 },
+    { 0x000380e0, 0x00000002 },
+    { 0x04002394, 0x00000002 },
+    { 0x00005000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x00000008, 0000000000 },
+    { 0x00000004, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+};
+
+static const u32 R200_cp_microcode[][2] = {
+    { 0x21007000, 0000000000 },
+    { 0x20007000, 0000000000 },
+    { 0x000000bf, 0x00000004 },
+    { 0x000000c3, 0x00000004 },
+    { 0x7a685e5d, 0000000000 },
+    { 0x5d5d5588, 0000000000 },
+    { 0x68659197, 0000000000 },
+    { 0x5da19f78, 0000000000 },
+    { 0x5d5d5d5d, 0000000000 },
+    { 0x5dee5d50, 0000000000 },
+    { 0xf2acacac, 0000000000 },
+    { 0xe75df9e9, 0000000000 },
+    { 0xb1dd0e11, 0000000000 },
+    { 0xe2afafaf, 0000000000 },
+    { 0x000f0000, 0x00000016 },
+    { 0x452f232d, 0000000000 },
+    { 0x00000013, 0x00000004 },
+    { 0x000f0000, 0x00000016 },
+    { 0x452f272d, 0000000000 },
+    { 0x000f0001, 0x00000016 },
+    { 0x3e4d4a37, 0000000000 },
+    { 0x000077ef, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x00000020, 0x0000001a },
+    { 0x00004000, 0x0000001e },
+    { 0x00061000, 0x00000002 },
+    { 0x00000020, 0x0000001a },
+    { 0x00004000, 0x0000001e },
+    { 0x00061000, 0x00000002 },
+    { 0x00000020, 0x0000001a },
+    { 0x00004000, 0x0000001e },
+    { 0x00000016, 0x00000004 },
+    { 0x0003802a, 0x00000002 },
+    { 0x040067e0, 0x00000002 },
+    { 0x00000016, 0x00000004 },
+    { 0x000077e0, 0x00000002 },
+    { 0x00065000, 0x00000002 },
+    { 0x000037e1, 0x00000002 },
+    { 0x040067e1, 0x00000006 },
+    { 0x000077e0, 0x00000002 },
+    { 0x000077e1, 0x00000002 },
+    { 0x000077e1, 0x00000006 },
+    { 0xffffffff, 0000000000 },
+    { 0x10000000, 0000000000 },
+    { 0x07f007f0, 0000000000 },
+    { 0x0003802a, 0x00000002 },
+    { 0x040067e0, 0x00000006 },
+    { 0x0003802c, 0x00000002 },
+    { 0x04002741, 0x00000002 },
+    { 0x04002741, 0x00000002 },
+    { 0x04002743, 0x00000002 },
+    { 0x00007675, 0x00000002 },
+    { 0x00007676, 0x00000002 },
+    { 0x00007677, 0x00000002 },
+    { 0x00007678, 0x00000006 },
+    { 0x0003802c, 0x00000002 },
+    { 0x04002741, 0x00000002 },
+    { 0x04002741, 0x00000002 },
+    { 0x04002743, 0x00000002 },
+    { 0x00007676, 0x00000002 },
+    { 0x00007677, 0x00000002 },
+    { 0x00007678, 0x00000006 },
+    { 0x0003802b, 0x00000002 },
+    { 0x04002676, 0x00000002 },
+    { 0x00007677, 0x00000002 },
+    { 0x0003802c, 0x00000002 },
+    { 0x04002741, 0x00000002 },
+    { 0x04002743, 0x00000002 },
+    { 0x00007678, 0x00000006 },
+    { 0x0003802c, 0x00000002 },
+    { 0x04002741, 0x00000002 },
+    { 0x04002741, 0x00000002 },
+    { 0x04002743, 0x00000002 },
+    { 0x00007678, 0x00000006 },
+    { 0x0000002f, 0x00000018 },
+    { 0x0000002f, 0x00000018 },
+    { 0000000000, 0x00000006 },
+    { 0x00000037, 0x00000018 },
+    { 0x00000037, 0x00000018 },
+    { 0000000000, 0x00000006 },
+    { 0x01605000, 0x00000002 },
+    { 0x00065000, 0x00000002 },
+    { 0x00098000, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x64c06051, 0x00000004 },
+    { 0x00080000, 0x00000016 },
+    { 0000000000, 0000000000 },
+    { 0x0400251d, 0x00000002 },
+    { 0x00007580, 0x00000002 },
+    { 0x00067581, 0x00000002 },
+    { 0x04002580, 0x00000002 },
+    { 0x00067581, 0x00000002 },
+    { 0x0000005a, 0x00000004 },
+    { 0x00005000, 0000000000 },
+    { 0x00061000, 0x00000002 },
+    { 0x0000750e, 0x00000002 },
+    { 0x00019000, 0x00000002 },
+    { 0x00011064, 0x00000014 },
+    { 0x00000064, 0x00000012 },
+    { 0x0400250f, 0x00000002 },
+    { 0x0000505e, 0x00000004 },
+    { 0x00007565, 0x00000002 },
+    { 0x00007566, 0x00000002 },
+    { 0x00000065, 0x00000004 },
+    { 0x01e655b4, 0x00000002 },
+    { 0x4401b0f0, 0x00000002 },
+    { 0x01c110f0, 0x00000002 },
+    { 0x26667071, 0x00000018 },
+    { 0x040c2565, 0x00000002 },
+    { 0x00000071, 0x00000018 },
+    { 0x04002564, 0x00000002 },
+    { 0x00007566, 0x00000002 },
+    { 0x00000068, 0x00000004 },
+    { 0x00401074, 0x00000008 },
+    { 0x00101000, 0x00000002 },
+    { 0x000d80ff, 0x00000002 },
+    { 0x00800077, 0x00000008 },
+    { 0x000f9000, 0x00000002 },
+    { 0x000e00ff, 0x00000002 },
+    { 0000000000, 0x00000006 },
+    { 0x00000094, 0x00000018 },
+    { 0x00000068, 0x00000004 },
+    { 0x00007576, 0x00000002 },
+    { 0x00065000, 0x00000002 },
+    { 0x00009000, 0x00000002 },
+    { 0x00041000, 0x00000002 },
+    { 0x0c00350e, 0x00000002 },
+    { 0x00049000, 0x00000002 },
+    { 0x00051000, 0x00000002 },
+    { 0x01e785f8, 0x00000002 },
+    { 0x00200000, 0x00000002 },
+    { 0x00600087, 0x0000000c },
+    { 0x00007563, 0x00000002 },
+    { 0x006075f0, 0x00000021 },
+    { 0x2000707c, 0x00000004 },
+    { 0x0000507c, 0x00000004 },
+    { 0x00007576, 0x00000002 },
+    { 0x00007577, 0x00000002 },
+    { 0x0000750e, 0x00000002 },
+    { 0x0000750f, 0x00000002 },
+    { 0x00a05000, 0x00000002 },
+    { 0x0060008a, 0x0000000c },
+    { 0x006075f0, 0x00000021 },
+    { 0x000075f8, 0x00000002 },
+    { 0x0000008a, 0x00000004 },
+    { 0x000a750e, 0x00000002 },
+    { 0x0020750f, 0x00000002 },
+    { 0x0060008d, 0x00000004 },
+    { 0x00007570, 0x00000002 },
+    { 0x00007571, 0x00000002 },
+    { 0x00007572, 0x00000006 },
+    { 0x00005000, 0x00000002 },
+    { 0x00a05000, 0x00000002 },
+    { 0x00007568, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x00000098, 0x0000000c },
+    { 0x00058000, 0x00000002 },
+    { 0x0c607562, 0x00000002 },
+    { 0x0000009a, 0x00000004 },
+    { 0x00600099, 0x00000004 },
+    { 0x400070f1, 0000000000 },
+    { 0x000380f1, 0x00000002 },
+    { 0x000000a7, 0x0000001c },
+    { 0x000650a9, 0x00000018 },
+    { 0x040025bb, 0x00000002 },
+    { 0x000610aa, 0x00000018 },
+    { 0x040075bc, 0000000000 },
+    { 0x000075bb, 0x00000002 },
+    { 0x000075bc, 0000000000 },
+    { 0x00090000, 0x00000006 },
+    { 0x00090000, 0x00000002 },
+    { 0x000d8002, 0x00000006 },
+    { 0x00005000, 0x00000002 },
+    { 0x00007821, 0x00000002 },
+    { 0x00007800, 0000000000 },
+    { 0x00007821, 0x00000002 },
+    { 0x00007800, 0000000000 },
+    { 0x01665000, 0x00000002 },
+    { 0x000a0000, 0x00000002 },
+    { 0x000671cc, 0x00000002 },
+    { 0x0286f1cd, 0x00000002 },
+    { 0x000000b7, 0x00000010 },
+    { 0x21007000, 0000000000 },
+    { 0x000000be, 0x0000001c },
+    { 0x00065000, 0x00000002 },
+    { 0x000a0000, 0x00000002 },
+    { 0x00061000, 0x00000002 },
+    { 0x000b0000, 0x00000002 },
+    { 0x38067000, 0x00000002 },
+    { 0x000a00ba, 0x00000004 },
+    { 0x20007000, 0000000000 },
+    { 0x01200000, 0x00000002 },
+    { 0x20077000, 0x00000002 },
+    { 0x01200000, 0x00000002 },
+    { 0x20007000, 0000000000 },
+    { 0x00061000, 0x00000002 },
+    { 0x0120751b, 0x00000002 },
+    { 0x8040750a, 0x00000002 },
+    { 0x8040750b, 0x00000002 },
+    { 0x00110000, 0x00000002 },
+    { 0x000380f1, 0x00000002 },
+    { 0x000000d1, 0x0000001c },
+    { 0x000610aa, 0x00000018 },
+    { 0x844075bd, 0x00000002 },
+    { 0x000610a9, 0x00000018 },
+    { 0x840075bb, 0x00000002 },
+    { 0x000610aa, 0x00000018 },
+    { 0x844075bc, 0x00000002 },
+    { 0x000000d4, 0x00000004 },
+    { 0x804075bd, 0x00000002 },
+    { 0x800075bb, 0x00000002 },
+    { 0x804075bc, 0x00000002 },
+    { 0x00108000, 0x00000002 },
+    { 0x01400000, 0x00000002 },
+    { 0x006000d8, 0x0000000c },
+    { 0x20c07000, 0x00000020 },
+    { 0x000000da, 0x00000012 },
+    { 0x00800000, 0x00000006 },
+    { 0x0080751d, 0x00000006 },
+    { 0x000025bb, 0x00000002 },
+    { 0x000040d4, 0x00000004 },
+    { 0x0000775c, 0x00000002 },
+    { 0x00a05000, 0x00000002 },
+    { 0x00661000, 0x00000002 },
+    { 0x0460275d, 0x00000020 },
+    { 0x00004000, 0000000000 },
+    { 0x00007999, 0x00000002 },
+    { 0x00a05000, 0x00000002 },
+    { 0x00661000, 0x00000002 },
+    { 0x0460299b, 0x00000020 },
+    { 0x00004000, 0000000000 },
+    { 0x01e00830, 0x00000002 },
+    { 0x21007000, 0000000000 },
+    { 0x00005000, 0x00000002 },
+    { 0x00038056, 0x00000002 },
+    { 0x040025e0, 0x00000002 },
+    { 0x000075e1, 0000000000 },
+    { 0x00000001, 0000000000 },
+    { 0x000380ed, 0x00000002 },
+    { 0x04007394, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x000078c4, 0x00000002 },
+    { 0x000078c5, 0x00000002 },
+    { 0x000078c6, 0x00000002 },
+    { 0x00007924, 0x00000002 },
+    { 0x00007925, 0x00000002 },
+    { 0x00007926, 0x00000002 },
+    { 0x000000f2, 0x00000004 },
+    { 0x00007924, 0x00000002 },
+    { 0x00007925, 0x00000002 },
+    { 0x00007926, 0x00000002 },
+    { 0x000000f9, 0x00000004 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+};
+
+static const u32 R300_cp_microcode[][2] = {
+    { 0x4200e000, 0000000000 },
+    { 0x4000e000, 0000000000 },
+    { 0x000000ae, 0x00000008 },
+    { 0x000000b2, 0x00000008 },
+    { 0x67554b4a, 0000000000 },
+    { 0x4a4a4475, 0000000000 },
+    { 0x55527d83, 0000000000 },
+    { 0x4a8c8b65, 0000000000 },
+    { 0x4aef4af6, 0000000000 },
+    { 0x4ae14a4a, 0000000000 },
+    { 0xe4979797, 0000000000 },
+    { 0xdb4aebdd, 0000000000 },
+    { 0x9ccc4a4a, 0000000000 },
+    { 0xd1989898, 0000000000 },
+    { 0x4a0f9ad6, 0000000000 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000d0012, 0x00000038 },
+    { 0x0000e8b4, 0x00000004 },
+    { 0x000d0014, 0x00000038 },
+    { 0x0000e8b6, 0x00000004 },
+    { 0x000d0016, 0x00000038 },
+    { 0x0000e854, 0x00000004 },
+    { 0x000d0018, 0x00000038 },
+    { 0x0000e855, 0x00000004 },
+    { 0x000d001a, 0x00000038 },
+    { 0x0000e856, 0x00000004 },
+    { 0x000d001c, 0x00000038 },
+    { 0x0000e857, 0x00000004 },
+    { 0x000d001e, 0x00000038 },
+    { 0x0000e824, 0x00000004 },
+    { 0x000d0020, 0x00000038 },
+    { 0x0000e825, 0x00000004 },
+    { 0x000d0022, 0x00000038 },
+    { 0x0000e830, 0x00000004 },
+    { 0x000d0024, 0x00000038 },
+    { 0x0000f0c0, 0x00000004 },
+    { 0x000d0026, 0x00000038 },
+    { 0x0000f0c1, 0x00000004 },
+    { 0x000d0028, 0x00000038 },
+    { 0x0000f041, 0x00000004 },
+    { 0x000d002a, 0x00000038 },
+    { 0x0000f184, 0x00000004 },
+    { 0x000d002c, 0x00000038 },
+    { 0x0000f185, 0x00000004 },
+    { 0x000d002e, 0x00000038 },
+    { 0x0000f186, 0x00000004 },
+    { 0x000d0030, 0x00000038 },
+    { 0x0000f187, 0x00000004 },
+    { 0x000d0032, 0x00000038 },
+    { 0x0000f180, 0x00000004 },
+    { 0x000d0034, 0x00000038 },
+    { 0x0000f393, 0x00000004 },
+    { 0x000d0036, 0x00000038 },
+    { 0x0000f38a, 0x00000004 },
+    { 0x000d0038, 0x00000038 },
+    { 0x0000f38e, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000043, 0x00000018 },
+    { 0x00cce800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x0000003a, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x2000451d, 0x00000004 },
+    { 0x0000e580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x08004580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x00000047, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x00032000, 0x00000004 },
+    { 0x00022051, 0x00000028 },
+    { 0x00000051, 0x00000024 },
+    { 0x0800450f, 0x00000004 },
+    { 0x0000a04b, 0x00000008 },
+    { 0x0000e565, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000052, 0x00000008 },
+    { 0x03cca5b4, 0x00000004 },
+    { 0x05432000, 0x00000004 },
+    { 0x00022000, 0x00000004 },
+    { 0x4ccce05e, 0x00000030 },
+    { 0x08274565, 0x00000004 },
+    { 0x0000005e, 0x00000030 },
+    { 0x08004564, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000055, 0x00000008 },
+    { 0x00802061, 0x00000010 },
+    { 0x00202000, 0x00000004 },
+    { 0x001b00ff, 0x00000004 },
+    { 0x01000064, 0x00000010 },
+    { 0x001f2000, 0x00000004 },
+    { 0x001c00ff, 0x00000004 },
+    { 0000000000, 0x0000000c },
+    { 0x00000080, 0x00000030 },
+    { 0x00000055, 0x00000008 },
+    { 0x0000e576, 0x00000004 },
+    { 0x000ca000, 0x00000004 },
+    { 0x00012000, 0x00000004 },
+    { 0x00082000, 0x00000004 },
+    { 0x1800650e, 0x00000004 },
+    { 0x00092000, 0x00000004 },
+    { 0x000a2000, 0x00000004 },
+    { 0x000f0000, 0x00000004 },
+    { 0x00400000, 0x00000004 },
+    { 0x00000074, 0x00000018 },
+    { 0x0000e563, 0x00000004 },
+    { 0x00c0e5f9, 0x000000c2 },
+    { 0x00000069, 0x00000008 },
+    { 0x0000a069, 0x00000008 },
+    { 0x0000e576, 0x00000004 },
+    { 0x0000e577, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x0000e50f, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000077, 0x00000018 },
+    { 0x00c0e5f9, 0x000000c2 },
+    { 0x00000077, 0x00000008 },
+    { 0x0014e50e, 0x00000004 },
+    { 0x0040e50f, 0x00000004 },
+    { 0x00c0007a, 0x00000008 },
+    { 0x0000e570, 0x00000004 },
+    { 0x0000e571, 0x00000004 },
+    { 0x0000e572, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x0000e568, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00000084, 0x00000018 },
+    { 0x000b0000, 0x00000004 },
+    { 0x18c0e562, 0x00000004 },
+    { 0x00000086, 0x00000008 },
+    { 0x00c00085, 0x00000008 },
+    { 0x000700e3, 0x00000004 },
+    { 0x00000092, 0x00000038 },
+    { 0x000ca094, 0x00000030 },
+    { 0x080045bb, 0x00000004 },
+    { 0x000c2095, 0x00000030 },
+    { 0x0800e5bc, 0000000000 },
+    { 0x0000e5bb, 0x00000004 },
+    { 0x0000e5bc, 0000000000 },
+    { 0x00120000, 0x0000000c },
+    { 0x00120000, 0x00000004 },
+    { 0x001b0002, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e800, 0000000000 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e82e, 0000000000 },
+    { 0x02cca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000ce1cc, 0x00000004 },
+    { 0x050de1cd, 0x00000004 },
+    { 0x00400000, 0x00000004 },
+    { 0x000000a4, 0x00000018 },
+    { 0x00c0a000, 0x00000004 },
+    { 0x000000a1, 0x00000008 },
+    { 0x000000a6, 0x00000020 },
+    { 0x4200e000, 0000000000 },
+    { 0x000000ad, 0x00000038 },
+    { 0x000ca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00160000, 0x00000004 },
+    { 0x700ce000, 0x00000004 },
+    { 0x001400a9, 0x00000008 },
+    { 0x4000e000, 0000000000 },
+    { 0x02400000, 0x00000004 },
+    { 0x400ee000, 0x00000004 },
+    { 0x02400000, 0x00000004 },
+    { 0x4000e000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0240e51b, 0x00000004 },
+    { 0x0080e50a, 0x00000005 },
+    { 0x0080e50b, 0x00000005 },
+    { 0x00220000, 0x00000004 },
+    { 0x000700e3, 0x00000004 },
+    { 0x000000c0, 0x00000038 },
+    { 0x000c2095, 0x00000030 },
+    { 0x0880e5bd, 0x00000005 },
+    { 0x000c2094, 0x00000030 },
+    { 0x0800e5bb, 0x00000005 },
+    { 0x000c2095, 0x00000030 },
+    { 0x0880e5bc, 0x00000005 },
+    { 0x000000c3, 0x00000008 },
+    { 0x0080e5bd, 0x00000005 },
+    { 0x0000e5bb, 0x00000005 },
+    { 0x0080e5bc, 0x00000005 },
+    { 0x00210000, 0x00000004 },
+    { 0x02800000, 0x00000004 },
+    { 0x00c000c7, 0x00000018 },
+    { 0x4180e000, 0x00000040 },
+    { 0x000000c9, 0x00000024 },
+    { 0x01000000, 0x0000000c },
+    { 0x0100e51d, 0x0000000c },
+    { 0x000045bb, 0x00000004 },
+    { 0x000080c3, 0x00000008 },
+    { 0x0000f3ce, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053cf, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f3d2, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053d3, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f39d, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c0539e, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x03c00830, 0x00000004 },
+    { 0x4200e000, 0000000000 },
+    { 0x0000a000, 0x00000004 },
+    { 0x200045e0, 0x00000004 },
+    { 0x0000e5e1, 0000000000 },
+    { 0x00000001, 0000000000 },
+    { 0x000700e0, 0x00000004 },
+    { 0x0800e394, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x0000e8c4, 0x00000004 },
+    { 0x0000e8c5, 0x00000004 },
+    { 0x0000e8c6, 0x00000004 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000e4, 0x00000008 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000eb, 0x00000008 },
+    { 0x02c02000, 0x00000004 },
+    { 0x00060000, 0x00000004 },
+    { 0x000000f3, 0x00000034 },
+    { 0x000000f0, 0x00000008 },
+    { 0x00008000, 0x00000004 },
+    { 0xc000e000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x001d0018, 0x00000004 },
+    { 0x001a0001, 0x00000004 },
+    { 0x000000fb, 0x00000034 },
+    { 0x0000004a, 0x00000008 },
+    { 0x0500a04a, 0x00000008 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+};
+
+static const u32 R420_cp_microcode[][2] = {
+    { 0x4200e000, 0000000000 },
+    { 0x4000e000, 0000000000 },
+    { 0x00000099, 0x00000008 },
+    { 0x0000009d, 0x00000008 },
+    { 0x4a554b4a, 0000000000 },
+    { 0x4a4a4467, 0000000000 },
+    { 0x55526f75, 0000000000 },
+    { 0x4a7e7d65, 0000000000 },
+    { 0xd9d3dff6, 0000000000 },
+    { 0x4ac54a4a, 0000000000 },
+    { 0xc8828282, 0000000000 },
+    { 0xbf4acfc1, 0000000000 },
+    { 0x87b04a4a, 0000000000 },
+    { 0xb5838383, 0000000000 },
+    { 0x4a0f85ba, 0000000000 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000d0012, 0x00000038 },
+    { 0x0000e8b4, 0x00000004 },
+    { 0x000d0014, 0x00000038 },
+    { 0x0000e8b6, 0x00000004 },
+    { 0x000d0016, 0x00000038 },
+    { 0x0000e854, 0x00000004 },
+    { 0x000d0018, 0x00000038 },
+    { 0x0000e855, 0x00000004 },
+    { 0x000d001a, 0x00000038 },
+    { 0x0000e856, 0x00000004 },
+    { 0x000d001c, 0x00000038 },
+    { 0x0000e857, 0x00000004 },
+    { 0x000d001e, 0x00000038 },
+    { 0x0000e824, 0x00000004 },
+    { 0x000d0020, 0x00000038 },
+    { 0x0000e825, 0x00000004 },
+    { 0x000d0022, 0x00000038 },
+    { 0x0000e830, 0x00000004 },
+    { 0x000d0024, 0x00000038 },
+    { 0x0000f0c0, 0x00000004 },
+    { 0x000d0026, 0x00000038 },
+    { 0x0000f0c1, 0x00000004 },
+    { 0x000d0028, 0x00000038 },
+    { 0x0000f041, 0x00000004 },
+    { 0x000d002a, 0x00000038 },
+    { 0x0000f184, 0x00000004 },
+    { 0x000d002c, 0x00000038 },
+    { 0x0000f185, 0x00000004 },
+    { 0x000d002e, 0x00000038 },
+    { 0x0000f186, 0x00000004 },
+    { 0x000d0030, 0x00000038 },
+    { 0x0000f187, 0x00000004 },
+    { 0x000d0032, 0x00000038 },
+    { 0x0000f180, 0x00000004 },
+    { 0x000d0034, 0x00000038 },
+    { 0x0000f393, 0x00000004 },
+    { 0x000d0036, 0x00000038 },
+    { 0x0000f38a, 0x00000004 },
+    { 0x000d0038, 0x00000038 },
+    { 0x0000f38e, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000043, 0x00000018 },
+    { 0x00cce800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x0000003a, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x2000451d, 0x00000004 },
+    { 0x0000e580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x08004580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x00000047, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x00032000, 0x00000004 },
+    { 0x00022051, 0x00000028 },
+    { 0x00000051, 0x00000024 },
+    { 0x0800450f, 0x00000004 },
+    { 0x0000a04b, 0x00000008 },
+    { 0x0000e565, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000052, 0x00000008 },
+    { 0x03cca5b4, 0x00000004 },
+    { 0x05432000, 0x00000004 },
+    { 0x00022000, 0x00000004 },
+    { 0x4ccce05e, 0x00000030 },
+    { 0x08274565, 0x00000004 },
+    { 0x0000005e, 0x00000030 },
+    { 0x08004564, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000055, 0x00000008 },
+    { 0x00802061, 0x00000010 },
+    { 0x00202000, 0x00000004 },
+    { 0x001b00ff, 0x00000004 },
+    { 0x01000064, 0x00000010 },
+    { 0x001f2000, 0x00000004 },
+    { 0x001c00ff, 0x00000004 },
+    { 0000000000, 0x0000000c },
+    { 0x00000072, 0x00000030 },
+    { 0x00000055, 0x00000008 },
+    { 0x0000e576, 0x00000004 },
+    { 0x0000e577, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x0000e50f, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000069, 0x00000018 },
+    { 0x00c0e5f9, 0x000000c2 },
+    { 0x00000069, 0x00000008 },
+    { 0x0014e50e, 0x00000004 },
+    { 0x0040e50f, 0x00000004 },
+    { 0x00c0006c, 0x00000008 },
+    { 0x0000e570, 0x00000004 },
+    { 0x0000e571, 0x00000004 },
+    { 0x0000e572, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x0000e568, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00000076, 0x00000018 },
+    { 0x000b0000, 0x00000004 },
+    { 0x18c0e562, 0x00000004 },
+    { 0x00000078, 0x00000008 },
+    { 0x00c00077, 0x00000008 },
+    { 0x000700c7, 0x00000004 },
+    { 0x00000080, 0x00000038 },
+    { 0x0000e5bb, 0x00000004 },
+    { 0x0000e5bc, 0000000000 },
+    { 0x0000a000, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e800, 0000000000 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e82e, 0000000000 },
+    { 0x02cca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000ce1cc, 0x00000004 },
+    { 0x050de1cd, 0x00000004 },
+    { 0x00400000, 0x00000004 },
+    { 0x0000008f, 0x00000018 },
+    { 0x00c0a000, 0x00000004 },
+    { 0x0000008c, 0x00000008 },
+    { 0x00000091, 0x00000020 },
+    { 0x4200e000, 0000000000 },
+    { 0x00000098, 0x00000038 },
+    { 0x000ca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00160000, 0x00000004 },
+    { 0x700ce000, 0x00000004 },
+    { 0x00140094, 0x00000008 },
+    { 0x4000e000, 0000000000 },
+    { 0x02400000, 0x00000004 },
+    { 0x400ee000, 0x00000004 },
+    { 0x02400000, 0x00000004 },
+    { 0x4000e000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0240e51b, 0x00000004 },
+    { 0x0080e50a, 0x00000005 },
+    { 0x0080e50b, 0x00000005 },
+    { 0x00220000, 0x00000004 },
+    { 0x000700c7, 0x00000004 },
+    { 0x000000a4, 0x00000038 },
+    { 0x0080e5bd, 0x00000005 },
+    { 0x0000e5bb, 0x00000005 },
+    { 0x0080e5bc, 0x00000005 },
+    { 0x00210000, 0x00000004 },
+    { 0x02800000, 0x00000004 },
+    { 0x00c000ab, 0x00000018 },
+    { 0x4180e000, 0x00000040 },
+    { 0x000000ad, 0x00000024 },
+    { 0x01000000, 0x0000000c },
+    { 0x0100e51d, 0x0000000c },
+    { 0x000045bb, 0x00000004 },
+    { 0x000080a7, 0x00000008 },
+    { 0x0000f3ce, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053cf, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f3d2, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053d3, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f39d, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c0539e, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x03c00830, 0x00000004 },
+    { 0x4200e000, 0000000000 },
+    { 0x0000a000, 0x00000004 },
+    { 0x200045e0, 0x00000004 },
+    { 0x0000e5e1, 0000000000 },
+    { 0x00000001, 0000000000 },
+    { 0x000700c4, 0x00000004 },
+    { 0x0800e394, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x0000e8c4, 0x00000004 },
+    { 0x0000e8c5, 0x00000004 },
+    { 0x0000e8c6, 0x00000004 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000c8, 0x00000008 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000cf, 0x00000008 },
+    { 0x02c02000, 0x00000004 },
+    { 0x00060000, 0x00000004 },
+    { 0x000000d7, 0x00000034 },
+    { 0x000000d4, 0x00000008 },
+    { 0x00008000, 0x00000004 },
+    { 0xc000e000, 0000000000 },
+    { 0x0000e1cc, 0x00000004 },
+    { 0x0500e1cd, 0x00000004 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000000de, 0x00000034 },
+    { 0x000000da, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x0019e1cc, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x0500a000, 0x00000004 },
+    { 0x080041cd, 0x00000004 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000000fb, 0x00000034 },
+    { 0x0000004a, 0x00000008 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x001d0018, 0x00000004 },
+    { 0x001a0001, 0x00000004 },
+    { 0x000000fb, 0x00000034 },
+    { 0x0000004a, 0x00000008 },
+    { 0x0500a04a, 0x00000008 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+};
+
+static const u32 RS600_cp_microcode[][2] = {
+    { 0x4200e000, 0000000000 },
+    { 0x4000e000, 0000000000 },
+    { 0x000000a0, 0x00000008 },
+    { 0x000000a4, 0x00000008 },
+    { 0x4a554b4a, 0000000000 },
+    { 0x4a4a4467, 0000000000 },
+    { 0x55526f75, 0000000000 },
+    { 0x4a7e7d65, 0000000000 },
+    { 0x4ae74af6, 0000000000 },
+    { 0x4ad34a4a, 0000000000 },
+    { 0xd6898989, 0000000000 },
+    { 0xcd4addcf, 0000000000 },
+    { 0x8ebe4ae2, 0000000000 },
+    { 0xc38a8a8a, 0000000000 },
+    { 0x4a0f8cc8, 0000000000 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000d0012, 0x00000038 },
+    { 0x0000e8b4, 0x00000004 },
+    { 0x000d0014, 0x00000038 },
+    { 0x0000e8b6, 0x00000004 },
+    { 0x000d0016, 0x00000038 },
+    { 0x0000e854, 0x00000004 },
+    { 0x000d0018, 0x00000038 },
+    { 0x0000e855, 0x00000004 },
+    { 0x000d001a, 0x00000038 },
+    { 0x0000e856, 0x00000004 },
+    { 0x000d001c, 0x00000038 },
+    { 0x0000e857, 0x00000004 },
+    { 0x000d001e, 0x00000038 },
+    { 0x0000e824, 0x00000004 },
+    { 0x000d0020, 0x00000038 },
+    { 0x0000e825, 0x00000004 },
+    { 0x000d0022, 0x00000038 },
+    { 0x0000e830, 0x00000004 },
+    { 0x000d0024, 0x00000038 },
+    { 0x0000f0c0, 0x00000004 },
+    { 0x000d0026, 0x00000038 },
+    { 0x0000f0c1, 0x00000004 },
+    { 0x000d0028, 0x00000038 },
+    { 0x0000f041, 0x00000004 },
+    { 0x000d002a, 0x00000038 },
+    { 0x0000f184, 0x00000004 },
+    { 0x000d002c, 0x00000038 },
+    { 0x0000f185, 0x00000004 },
+    { 0x000d002e, 0x00000038 },
+    { 0x0000f186, 0x00000004 },
+    { 0x000d0030, 0x00000038 },
+    { 0x0000f187, 0x00000004 },
+    { 0x000d0032, 0x00000038 },
+    { 0x0000f180, 0x00000004 },
+    { 0x000d0034, 0x00000038 },
+    { 0x0000f393, 0x00000004 },
+    { 0x000d0036, 0x00000038 },
+    { 0x0000f38a, 0x00000004 },
+    { 0x000d0038, 0x00000038 },
+    { 0x0000f38e, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000043, 0x00000018 },
+    { 0x00cce800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x0000003a, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x2000451d, 0x00000004 },
+    { 0x0000e580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x08004580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x00000047, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x00032000, 0x00000004 },
+    { 0x00022051, 0x00000028 },
+    { 0x00000051, 0x00000024 },
+    { 0x0800450f, 0x00000004 },
+    { 0x0000a04b, 0x00000008 },
+    { 0x0000e565, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000052, 0x00000008 },
+    { 0x03cca5b4, 0x00000004 },
+    { 0x05432000, 0x00000004 },
+    { 0x00022000, 0x00000004 },
+    { 0x4ccce05e, 0x00000030 },
+    { 0x08274565, 0x00000004 },
+    { 0x0000005e, 0x00000030 },
+    { 0x08004564, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000055, 0x00000008 },
+    { 0x00802061, 0x00000010 },
+    { 0x00202000, 0x00000004 },
+    { 0x001b00ff, 0x00000004 },
+    { 0x01000064, 0x00000010 },
+    { 0x001f2000, 0x00000004 },
+    { 0x001c00ff, 0x00000004 },
+    { 0000000000, 0x0000000c },
+    { 0x00000072, 0x00000030 },
+    { 0x00000055, 0x00000008 },
+    { 0x0000e576, 0x00000004 },
+    { 0x0000e577, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x0000e50f, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000069, 0x00000018 },
+    { 0x00c0e5f9, 0x000000c2 },
+    { 0x00000069, 0x00000008 },
+    { 0x0014e50e, 0x00000004 },
+    { 0x0040e50f, 0x00000004 },
+    { 0x00c0006c, 0x00000008 },
+    { 0x0000e570, 0x00000004 },
+    { 0x0000e571, 0x00000004 },
+    { 0x0000e572, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x0000e568, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00000076, 0x00000018 },
+    { 0x000b0000, 0x00000004 },
+    { 0x18c0e562, 0x00000004 },
+    { 0x00000078, 0x00000008 },
+    { 0x00c00077, 0x00000008 },
+    { 0x000700d5, 0x00000004 },
+    { 0x00000084, 0x00000038 },
+    { 0x000ca086, 0x00000030 },
+    { 0x080045bb, 0x00000004 },
+    { 0x000c2087, 0x00000030 },
+    { 0x0800e5bc, 0000000000 },
+    { 0x0000e5bb, 0x00000004 },
+    { 0x0000e5bc, 0000000000 },
+    { 0x00120000, 0x0000000c },
+    { 0x00120000, 0x00000004 },
+    { 0x001b0002, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e800, 0000000000 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e82e, 0000000000 },
+    { 0x02cca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000ce1cc, 0x00000004 },
+    { 0x050de1cd, 0x00000004 },
+    { 0x00400000, 0x00000004 },
+    { 0x00000096, 0x00000018 },
+    { 0x00c0a000, 0x00000004 },
+    { 0x00000093, 0x00000008 },
+    { 0x00000098, 0x00000020 },
+    { 0x4200e000, 0000000000 },
+    { 0x0000009f, 0x00000038 },
+    { 0x000ca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00160000, 0x00000004 },
+    { 0x700ce000, 0x00000004 },
+    { 0x0014009b, 0x00000008 },
+    { 0x4000e000, 0000000000 },
+    { 0x02400000, 0x00000004 },
+    { 0x400ee000, 0x00000004 },
+    { 0x02400000, 0x00000004 },
+    { 0x4000e000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0240e51b, 0x00000004 },
+    { 0x0080e50a, 0x00000005 },
+    { 0x0080e50b, 0x00000005 },
+    { 0x00220000, 0x00000004 },
+    { 0x000700d5, 0x00000004 },
+    { 0x000000b2, 0x00000038 },
+    { 0x000c2087, 0x00000030 },
+    { 0x0880e5bd, 0x00000005 },
+    { 0x000c2086, 0x00000030 },
+    { 0x0800e5bb, 0x00000005 },
+    { 0x000c2087, 0x00000030 },
+    { 0x0880e5bc, 0x00000005 },
+    { 0x000000b5, 0x00000008 },
+    { 0x0080e5bd, 0x00000005 },
+    { 0x0000e5bb, 0x00000005 },
+    { 0x0080e5bc, 0x00000005 },
+    { 0x00210000, 0x00000004 },
+    { 0x02800000, 0x00000004 },
+    { 0x00c000b9, 0x00000018 },
+    { 0x4180e000, 0x00000040 },
+    { 0x000000bb, 0x00000024 },
+    { 0x01000000, 0x0000000c },
+    { 0x0100e51d, 0x0000000c },
+    { 0x000045bb, 0x00000004 },
+    { 0x000080b5, 0x00000008 },
+    { 0x0000f3ce, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053cf, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f3d2, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053d3, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f39d, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c0539e, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x03c00830, 0x00000004 },
+    { 0x4200e000, 0000000000 },
+    { 0x0000a000, 0x00000004 },
+    { 0x200045e0, 0x00000004 },
+    { 0x0000e5e1, 0000000000 },
+    { 0x00000001, 0000000000 },
+    { 0x000700d2, 0x00000004 },
+    { 0x0800e394, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x0000e8c4, 0x00000004 },
+    { 0x0000e8c5, 0x00000004 },
+    { 0x0000e8c6, 0x00000004 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000d6, 0x00000008 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000dd, 0x00000008 },
+    { 0x00e00116, 0000000000 },
+    { 0x000700e1, 0x00000004 },
+    { 0x0800401c, 0x00000004 },
+    { 0x200050e7, 0x00000004 },
+    { 0x0000e01d, 0x00000004 },
+    { 0x000000e4, 0x00000008 },
+    { 0x02c02000, 0x00000004 },
+    { 0x00060000, 0x00000004 },
+    { 0x000000eb, 0x00000034 },
+    { 0x000000e8, 0x00000008 },
+    { 0x00008000, 0x00000004 },
+    { 0xc000e000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x001d0018, 0x00000004 },
+    { 0x001a0001, 0x00000004 },
+    { 0x000000fb, 0x00000034 },
+    { 0x0000004a, 0x00000008 },
+    { 0x0500a04a, 0x00000008 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+};
+
+static const u32 RS690_cp_microcode[][2] = {
+    { 0x000000dd, 0x00000008 },
+    { 0x000000df, 0x00000008 },
+    { 0x000000a0, 0x00000008 },
+    { 0x000000a4, 0x00000008 },
+    { 0x4a554b4a, 0000000000 },
+    { 0x4a4a4467, 0000000000 },
+    { 0x55526f75, 0000000000 },
+    { 0x4a7e7d65, 0000000000 },
+    { 0x4ad74af6, 0000000000 },
+    { 0x4ac94a4a, 0000000000 },
+    { 0xcc898989, 0000000000 },
+    { 0xc34ad3c5, 0000000000 },
+    { 0x8e4a4a4a, 0000000000 },
+    { 0x4a8a8a8a, 0000000000 },
+    { 0x4a0f8c4a, 0000000000 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000d0012, 0x00000038 },
+    { 0x0000e8b4, 0x00000004 },
+    { 0x000d0014, 0x00000038 },
+    { 0x0000e8b6, 0x00000004 },
+    { 0x000d0016, 0x00000038 },
+    { 0x0000e854, 0x00000004 },
+    { 0x000d0018, 0x00000038 },
+    { 0x0000e855, 0x00000004 },
+    { 0x000d001a, 0x00000038 },
+    { 0x0000e856, 0x00000004 },
+    { 0x000d001c, 0x00000038 },
+    { 0x0000e857, 0x00000004 },
+    { 0x000d001e, 0x00000038 },
+    { 0x0000e824, 0x00000004 },
+    { 0x000d0020, 0x00000038 },
+    { 0x0000e825, 0x00000004 },
+    { 0x000d0022, 0x00000038 },
+    { 0x0000e830, 0x00000004 },
+    { 0x000d0024, 0x00000038 },
+    { 0x0000f0c0, 0x00000004 },
+    { 0x000d0026, 0x00000038 },
+    { 0x0000f0c1, 0x00000004 },
+    { 0x000d0028, 0x00000038 },
+    { 0x0000f041, 0x00000004 },
+    { 0x000d002a, 0x00000038 },
+    { 0x0000f184, 0x00000004 },
+    { 0x000d002c, 0x00000038 },
+    { 0x0000f185, 0x00000004 },
+    { 0x000d002e, 0x00000038 },
+    { 0x0000f186, 0x00000004 },
+    { 0x000d0030, 0x00000038 },
+    { 0x0000f187, 0x00000004 },
+    { 0x000d0032, 0x00000038 },
+    { 0x0000f180, 0x00000004 },
+    { 0x000d0034, 0x00000038 },
+    { 0x0000f393, 0x00000004 },
+    { 0x000d0036, 0x00000038 },
+    { 0x0000f38a, 0x00000004 },
+    { 0x000d0038, 0x00000038 },
+    { 0x0000f38e, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000043, 0x00000018 },
+    { 0x00cce800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x0000003a, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x2000451d, 0x00000004 },
+    { 0x0000e580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x08004580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x00000047, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x00032000, 0x00000004 },
+    { 0x00022051, 0x00000028 },
+    { 0x00000051, 0x00000024 },
+    { 0x0800450f, 0x00000004 },
+    { 0x0000a04b, 0x00000008 },
+    { 0x0000e565, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000052, 0x00000008 },
+    { 0x03cca5b4, 0x00000004 },
+    { 0x05432000, 0x00000004 },
+    { 0x00022000, 0x00000004 },
+    { 0x4ccce05e, 0x00000030 },
+    { 0x08274565, 0x00000004 },
+    { 0x0000005e, 0x00000030 },
+    { 0x08004564, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000055, 0x00000008 },
+    { 0x00802061, 0x00000010 },
+    { 0x00202000, 0x00000004 },
+    { 0x001b00ff, 0x00000004 },
+    { 0x01000064, 0x00000010 },
+    { 0x001f2000, 0x00000004 },
+    { 0x001c00ff, 0x00000004 },
+    { 0000000000, 0x0000000c },
+    { 0x00000072, 0x00000030 },
+    { 0x00000055, 0x00000008 },
+    { 0x0000e576, 0x00000004 },
+    { 0x0000e577, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x0000e50f, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000069, 0x00000018 },
+    { 0x00c0e5f9, 0x000000c2 },
+    { 0x00000069, 0x00000008 },
+    { 0x0014e50e, 0x00000004 },
+    { 0x0040e50f, 0x00000004 },
+    { 0x00c0006c, 0x00000008 },
+    { 0x0000e570, 0x00000004 },
+    { 0x0000e571, 0x00000004 },
+    { 0x0000e572, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x0000e568, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00000076, 0x00000018 },
+    { 0x000b0000, 0x00000004 },
+    { 0x18c0e562, 0x00000004 },
+    { 0x00000078, 0x00000008 },
+    { 0x00c00077, 0x00000008 },
+    { 0x000700cb, 0x00000004 },
+    { 0x00000084, 0x00000038 },
+    { 0x000ca086, 0x00000030 },
+    { 0x080045bb, 0x00000004 },
+    { 0x000c2087, 0x00000030 },
+    { 0x0800e5bc, 0000000000 },
+    { 0x0000e5bb, 0x00000004 },
+    { 0x0000e5bc, 0000000000 },
+    { 0x00120000, 0x0000000c },
+    { 0x00120000, 0x00000004 },
+    { 0x001b0002, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e800, 0000000000 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e82e, 0000000000 },
+    { 0x02cca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000ce1cc, 0x00000004 },
+    { 0x050de1cd, 0x00000004 },
+    { 0x00400000, 0x00000004 },
+    { 0x00000096, 0x00000018 },
+    { 0x00c0a000, 0x00000004 },
+    { 0x00000093, 0x00000008 },
+    { 0x00000098, 0x00000020 },
+    { 0x4200e000, 0000000000 },
+    { 0x0000009f, 0x00000038 },
+    { 0x000ca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00160000, 0x00000004 },
+    { 0x700ce000, 0x00000004 },
+    { 0x0014009b, 0x00000008 },
+    { 0x4000e000, 0000000000 },
+    { 0x02400000, 0x00000004 },
+    { 0x400ee000, 0x00000004 },
+    { 0x02400000, 0x00000004 },
+    { 0x4000e000, 0000000000 },
+    { 0x00100000, 0x0000002c },
+    { 0x00004000, 0000000000 },
+    { 0x080045c8, 0x00000004 },
+    { 0x00240005, 0x00000004 },
+    { 0x08004d0b, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0240e51b, 0x00000004 },
+    { 0x0080e50a, 0x00000005 },
+    { 0x0080e50b, 0x00000005 },
+    { 0x00220000, 0x00000004 },
+    { 0x000700cb, 0x00000004 },
+    { 0x000000b7, 0x00000038 },
+    { 0x000c2087, 0x00000030 },
+    { 0x0880e5bd, 0x00000005 },
+    { 0x000c2086, 0x00000030 },
+    { 0x0800e5bb, 0x00000005 },
+    { 0x000c2087, 0x00000030 },
+    { 0x0880e5bc, 0x00000005 },
+    { 0x000000ba, 0x00000008 },
+    { 0x0080e5bd, 0x00000005 },
+    { 0x0000e5bb, 0x00000005 },
+    { 0x0080e5bc, 0x00000005 },
+    { 0x00210000, 0x00000004 },
+    { 0x02800000, 0x00000004 },
+    { 0x00c000be, 0x00000018 },
+    { 0x4180e000, 0x00000040 },
+    { 0x000000c0, 0x00000024 },
+    { 0x01000000, 0x0000000c },
+    { 0x0100e51d, 0x0000000c },
+    { 0x000045bb, 0x00000004 },
+    { 0x000080ba, 0x00000008 },
+    { 0x03c00830, 0x00000004 },
+    { 0x4200e000, 0000000000 },
+    { 0x0000a000, 0x00000004 },
+    { 0x200045e0, 0x00000004 },
+    { 0x0000e5e1, 0000000000 },
+    { 0x00000001, 0000000000 },
+    { 0x000700c8, 0x00000004 },
+    { 0x0800e394, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x0000e8c4, 0x00000004 },
+    { 0x0000e8c5, 0x00000004 },
+    { 0x0000e8c6, 0x00000004 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000cc, 0x00000008 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000d3, 0x00000008 },
+    { 0x02c02000, 0x00000004 },
+    { 0x00060000, 0x00000004 },
+    { 0x000000db, 0x00000034 },
+    { 0x000000d8, 0x00000008 },
+    { 0x00008000, 0x00000004 },
+    { 0xc000e000, 0000000000 },
+    { 0x000000e1, 0x00000030 },
+    { 0x4200e000, 0000000000 },
+    { 0x000000e1, 0x00000030 },
+    { 0x4000e000, 0000000000 },
+    { 0x0025001b, 0x00000004 },
+    { 0x00230000, 0x00000004 },
+    { 0x00250005, 0x00000004 },
+    { 0x000000e6, 0x00000034 },
+    { 0000000000, 0x0000000c },
+    { 0x00244000, 0x00000004 },
+    { 0x080045c8, 0x00000004 },
+    { 0x00240005, 0x00000004 },
+    { 0x08004d0b, 0x0000000c },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x001d0018, 0x00000004 },
+    { 0x001a0001, 0x00000004 },
+    { 0x000000fb, 0x00000034 },
+    { 0x0000004a, 0x00000008 },
+    { 0x0500a04a, 0x00000008 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+};
+
+static const u32 R520_cp_microcode[][2] = {
+    { 0x4200e000, 0000000000 },
+    { 0x4000e000, 0000000000 },
+    { 0x00000099, 0x00000008 },
+    { 0x0000009d, 0x00000008 },
+    { 0x4a554b4a, 0000000000 },
+    { 0x4a4a4467, 0000000000 },
+    { 0x55526f75, 0000000000 },
+    { 0x4a7e7d65, 0000000000 },
+    { 0xe0dae6f6, 0000000000 },
+    { 0x4ac54a4a, 0000000000 },
+    { 0xc8828282, 0000000000 },
+    { 0xbf4acfc1, 0000000000 },
+    { 0x87b04ad5, 0000000000 },
+    { 0xb5838383, 0000000000 },
+    { 0x4a0f85ba, 0000000000 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000d0012, 0x00000038 },
+    { 0x0000e8b4, 0x00000004 },
+    { 0x000d0014, 0x00000038 },
+    { 0x0000e8b6, 0x00000004 },
+    { 0x000d0016, 0x00000038 },
+    { 0x0000e854, 0x00000004 },
+    { 0x000d0018, 0x00000038 },
+    { 0x0000e855, 0x00000004 },
+    { 0x000d001a, 0x00000038 },
+    { 0x0000e856, 0x00000004 },
+    { 0x000d001c, 0x00000038 },
+    { 0x0000e857, 0x00000004 },
+    { 0x000d001e, 0x00000038 },
+    { 0x0000e824, 0x00000004 },
+    { 0x000d0020, 0x00000038 },
+    { 0x0000e825, 0x00000004 },
+    { 0x000d0022, 0x00000038 },
+    { 0x0000e830, 0x00000004 },
+    { 0x000d0024, 0x00000038 },
+    { 0x0000f0c0, 0x00000004 },
+    { 0x000d0026, 0x00000038 },
+    { 0x0000f0c1, 0x00000004 },
+    { 0x000d0028, 0x00000038 },
+    { 0x0000e000, 0x00000004 },
+    { 0x000d002a, 0x00000038 },
+    { 0x0000e000, 0x00000004 },
+    { 0x000d002c, 0x00000038 },
+    { 0x0000e000, 0x00000004 },
+    { 0x000d002e, 0x00000038 },
+    { 0x0000e000, 0x00000004 },
+    { 0x000d0030, 0x00000038 },
+    { 0x0000e000, 0x00000004 },
+    { 0x000d0032, 0x00000038 },
+    { 0x0000f180, 0x00000004 },
+    { 0x000d0034, 0x00000038 },
+    { 0x0000f393, 0x00000004 },
+    { 0x000d0036, 0x00000038 },
+    { 0x0000f38a, 0x00000004 },
+    { 0x000d0038, 0x00000038 },
+    { 0x0000f38e, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000043, 0x00000018 },
+    { 0x00cce800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x08004800, 0x00000004 },
+    { 0x0000003a, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x2000451d, 0x00000004 },
+    { 0x0000e580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x08004580, 0x00000004 },
+    { 0x000ce581, 0x00000004 },
+    { 0x00000047, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x00032000, 0x00000004 },
+    { 0x00022051, 0x00000028 },
+    { 0x00000051, 0x00000024 },
+    { 0x0800450f, 0x00000004 },
+    { 0x0000a04b, 0x00000008 },
+    { 0x0000e565, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000052, 0x00000008 },
+    { 0x03cca5b4, 0x00000004 },
+    { 0x05432000, 0x00000004 },
+    { 0x00022000, 0x00000004 },
+    { 0x4ccce05e, 0x00000030 },
+    { 0x08274565, 0x00000004 },
+    { 0x0000005e, 0x00000030 },
+    { 0x08004564, 0x00000004 },
+    { 0x0000e566, 0x00000004 },
+    { 0x00000055, 0x00000008 },
+    { 0x00802061, 0x00000010 },
+    { 0x00202000, 0x00000004 },
+    { 0x001b00ff, 0x00000004 },
+    { 0x01000064, 0x00000010 },
+    { 0x001f2000, 0x00000004 },
+    { 0x001c00ff, 0x00000004 },
+    { 0000000000, 0x0000000c },
+    { 0x00000072, 0x00000030 },
+    { 0x00000055, 0x00000008 },
+    { 0x0000e576, 0x00000004 },
+    { 0x0000e577, 0x00000004 },
+    { 0x0000e50e, 0x00000004 },
+    { 0x0000e50f, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00000069, 0x00000018 },
+    { 0x00c0e5f9, 0x000000c2 },
+    { 0x00000069, 0x00000008 },
+    { 0x0014e50e, 0x00000004 },
+    { 0x0040e50f, 0x00000004 },
+    { 0x00c0006c, 0x00000008 },
+    { 0x0000e570, 0x00000004 },
+    { 0x0000e571, 0x00000004 },
+    { 0x0000e572, 0x0000000c },
+    { 0x0000a000, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x0000e568, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00000076, 0x00000018 },
+    { 0x000b0000, 0x00000004 },
+    { 0x18c0e562, 0x00000004 },
+    { 0x00000078, 0x00000008 },
+    { 0x00c00077, 0x00000008 },
+    { 0x000700c7, 0x00000004 },
+    { 0x00000080, 0x00000038 },
+    { 0x0000e5bb, 0x00000004 },
+    { 0x0000e5bc, 0000000000 },
+    { 0x0000a000, 0x00000004 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e800, 0000000000 },
+    { 0x0000e821, 0x00000004 },
+    { 0x0000e82e, 0000000000 },
+    { 0x02cca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000ce1cc, 0x00000004 },
+    { 0x050de1cd, 0x00000004 },
+    { 0x00400000, 0x00000004 },
+    { 0x0000008f, 0x00000018 },
+    { 0x00c0a000, 0x00000004 },
+    { 0x0000008c, 0x00000008 },
+    { 0x00000091, 0x00000020 },
+    { 0x4200e000, 0000000000 },
+    { 0x00000098, 0x00000038 },
+    { 0x000ca000, 0x00000004 },
+    { 0x00140000, 0x00000004 },
+    { 0x000c2000, 0x00000004 },
+    { 0x00160000, 0x00000004 },
+    { 0x700ce000, 0x00000004 },
+    { 0x00140094, 0x00000008 },
+    { 0x4000e000, 0000000000 },
+    { 0x02400000, 0x00000004 },
+    { 0x400ee000, 0x00000004 },
+    { 0x02400000, 0x00000004 },
+    { 0x4000e000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x0240e51b, 0x00000004 },
+    { 0x0080e50a, 0x00000005 },
+    { 0x0080e50b, 0x00000005 },
+    { 0x00220000, 0x00000004 },
+    { 0x000700c7, 0x00000004 },
+    { 0x000000a4, 0x00000038 },
+    { 0x0080e5bd, 0x00000005 },
+    { 0x0000e5bb, 0x00000005 },
+    { 0x0080e5bc, 0x00000005 },
+    { 0x00210000, 0x00000004 },
+    { 0x02800000, 0x00000004 },
+    { 0x00c000ab, 0x00000018 },
+    { 0x4180e000, 0x00000040 },
+    { 0x000000ad, 0x00000024 },
+    { 0x01000000, 0x0000000c },
+    { 0x0100e51d, 0x0000000c },
+    { 0x000045bb, 0x00000004 },
+    { 0x000080a7, 0x00000008 },
+    { 0x0000f3ce, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053cf, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f3d2, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c053d3, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x0000f39d, 0x00000004 },
+    { 0x0140a000, 0x00000004 },
+    { 0x00cc2000, 0x00000004 },
+    { 0x08c0539e, 0x00000040 },
+    { 0x00008000, 0000000000 },
+    { 0x03c00830, 0x00000004 },
+    { 0x4200e000, 0000000000 },
+    { 0x0000a000, 0x00000004 },
+    { 0x200045e0, 0x00000004 },
+    { 0x0000e5e1, 0000000000 },
+    { 0x00000001, 0000000000 },
+    { 0x000700c4, 0x00000004 },
+    { 0x0800e394, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x0000e8c4, 0x00000004 },
+    { 0x0000e8c5, 0x00000004 },
+    { 0x0000e8c6, 0x00000004 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000c8, 0x00000008 },
+    { 0x0000e928, 0x00000004 },
+    { 0x0000e929, 0x00000004 },
+    { 0x0000e92a, 0x00000004 },
+    { 0x000000cf, 0x00000008 },
+    { 0xdeadbeef, 0000000000 },
+    { 0x00000116, 0000000000 },
+    { 0x000700d3, 0x00000004 },
+    { 0x080050e7, 0x00000004 },
+    { 0x000700d4, 0x00000004 },
+    { 0x0800401c, 0x00000004 },
+    { 0x0000e01d, 0000000000 },
+    { 0x02c02000, 0x00000004 },
+    { 0x00060000, 0x00000004 },
+    { 0x000000de, 0x00000034 },
+    { 0x000000db, 0x00000008 },
+    { 0x00008000, 0x00000004 },
+    { 0xc000e000, 0000000000 },
+    { 0x0000e1cc, 0x00000004 },
+    { 0x0500e1cd, 0x00000004 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000000e5, 0x00000034 },
+    { 0x000000e1, 0x00000008 },
+    { 0x0000a000, 0000000000 },
+    { 0x0019e1cc, 0x00000004 },
+    { 0x001b0001, 0x00000004 },
+    { 0x0500a000, 0x00000004 },
+    { 0x080041cd, 0x00000004 },
+    { 0x000ca000, 0x00000004 },
+    { 0x000000fb, 0x00000034 },
+    { 0x0000004a, 0x00000008 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0x000c2000, 0x00000004 },
+    { 0x001d0018, 0x00000004 },
+    { 0x001a0001, 0x00000004 },
+    { 0x000000fb, 0x00000034 },
+    { 0x0000004a, 0x00000008 },
+    { 0x0500a04a, 0x00000008 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+    { 0000000000, 0000000000 },
+};
+
+
+#endif
index 6f75512f591e1b3792025f38491da2e7e3e043ae..11c146b49211de3581cbc2daaab9815af885cec9 100644 (file)
@@ -1662,7 +1662,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
        u32 height;
        int i;
        u32 texpitch, microtile;
-       u32 offset;
+       u32 offset, byte_offset;
        RING_LOCALS;
 
        if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
@@ -1727,6 +1727,13 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
        } else
                microtile = 0;
 
+       /* this might fail for zero-sized uploads - are those illegal? */
+       if (!radeon_check_offset(dev_priv, tex->offset + image->height *
+                               blit_width - 1)) {
+               DRM_ERROR("Invalid final destination offset\n");
+               return -EINVAL;
+       }
+
        DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
 
        do {
@@ -1840,6 +1847,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
                }
 
 #undef RADEON_COPY_MT
+               byte_offset = (image->y & ~2047) * blit_width;
                buf->file_priv = file_priv;
                buf->used = size;
                offset = dev_priv->gart_buffers_offset + buf->offset;
@@ -1854,9 +1862,9 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
                         RADEON_DP_SRC_SOURCE_MEMORY |
                         RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
                OUT_RING((spitch << 22) | (offset >> 10));
-               OUT_RING((texpitch << 22) | (tex->offset >> 10));
+               OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10)));
                OUT_RING(0);
-               OUT_RING((image->x << 16) | image->y);
+               OUT_RING((image->x << 16) | (image->y % 2048));
                OUT_RING((image->width << 16) | height);
                RADEON_WAIT_UNTIL_2D_IDLE();
                ADVANCE_RING();
@@ -3037,6 +3045,9 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
        case RADEON_PARAM_FB_LOCATION:
                value = radeon_read_fb_location(dev_priv);
                break;
+       case RADEON_PARAM_NUM_GB_PIPES:
+               value = dev_priv->num_gb_pipes;
+               break;
        default:
                DRM_DEBUG("Invalid parameter %d\n", param->param);
                return -EINVAL;
index b1a757a5ee271c9c4a4dc5a4b2fc18c35c7fb491..8f81139d61949b4f4300baaacb69e56e473a8a69 100644 (file)
@@ -981,16 +981,9 @@ EXPORT_SYMBOL_GPL(tty_perform_flush);
 int n_tty_ioctl(struct tty_struct *tty, struct file *file,
                       unsigned int cmd, unsigned long arg)
 {
-       struct tty_struct *real_tty;
        unsigned long flags;
        int retval;
 
-       if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
-           tty->driver->subtype == PTY_TYPE_MASTER)
-               real_tty = tty->link;
-       else
-               real_tty = tty;
-
        switch (cmd) {
        case TCXONC:
                retval = tty_check_change(tty);
index 85e2ba7fcfbab1b4533079da8bd812f22203952d..bf4830082a135e126d9f35f1a72a7bf5b18fbecf 100644 (file)
@@ -27,6 +27,8 @@
 #include <linux/moduleparam.h>
 #include <linux/connector.h>
 #include <linux/mutex.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
 
 #include <net/sock.h>
 
@@ -403,6 +405,40 @@ static void cn_callback(void *data)
        mutex_unlock(&notify_lock);
 }
 
+static int cn_proc_show(struct seq_file *m, void *v)
+{
+       struct cn_queue_dev *dev = cdev.cbdev;
+       struct cn_callback_entry *cbq;
+
+       seq_printf(m, "Name            ID\n");
+
+       spin_lock_bh(&dev->queue_lock);
+
+       list_for_each_entry(cbq, &dev->queue_list, callback_entry) {
+               seq_printf(m, "%-15s %u:%u\n",
+                          cbq->id.name,
+                          cbq->id.id.idx,
+                          cbq->id.id.val);
+       }
+
+       spin_unlock_bh(&dev->queue_lock);
+
+       return 0;
+}
+
+static int cn_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, cn_proc_show, NULL);
+}
+
+static const struct file_operations cn_file_ops = {
+       .owner   = THIS_MODULE,
+       .open    = cn_proc_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = single_release
+};
+
 static int __devinit cn_init(void)
 {
        struct cn_dev *dev = &cdev;
@@ -434,6 +470,8 @@ static int __devinit cn_init(void)
                return -EINVAL;
        }
 
+       proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops);
+
        return 0;
 }
 
@@ -443,6 +481,8 @@ static void __devexit cn_fini(void)
 
        cn_already_initialized = 0;
 
+       proc_net_remove(&init_net, "connector");
+
        cn_del_callback(&dev->id);
        cn_queue_free_dev(dev->cbdev);
        netlink_kernel_release(dev->nls);
index fb4d391810b61fe440b24b91080c434dba2df282..76f26710fc16393bbecb80310924789798d2f718 100644 (file)
@@ -1,28 +1,26 @@
-comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
+comment "A new alternative FireWire stack is available with EXPERIMENTAL=y"
        depends on EXPERIMENTAL=n
 
+comment "Enable only one of the two stacks, unless you know what you are doing"
+       depends on EXPERIMENTAL
+
 config FIREWIRE
-       tristate "IEEE 1394 (FireWire) support - alternative stack, EXPERIMENTAL"
+       tristate "New FireWire stack, EXPERIMENTAL"
        depends on EXPERIMENTAL
        select CRC_ITU_T
        help
          This is the "Juju" FireWire stack, a new alternative implementation
          designed for robustness and simplicity.  You can build either this
-         stack, or the classic stack (the ieee1394 driver, ohci1394 etc.)
-         or both.  Please read http://wiki.linux1394.org/JujuMigration before
-         you enable the new stack.
+         stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both.
+         Please read http://wiki.linux1394.org/JujuMigration before you
+         enable the new stack.
 
          To compile this driver as a module, say M here: the module will be
          called firewire-core.  It functionally replaces ieee1394, raw1394,
          and video1394.
 
-          NOTE:
-
-         You should only build ONE of the stacks, unless you REALLY know what
-         you are doing.
-
 config FIREWIRE_OHCI
-       tristate "Support for OHCI FireWire host controllers"
+       tristate "OHCI-1394 controllers"
        depends on PCI && FIREWIRE
        help
          Enable this driver if you have a FireWire controller based
@@ -33,12 +31,12 @@ config FIREWIRE_OHCI
          called firewire-ohci.  It replaces ohci1394 of the classic IEEE 1394
          stack.
 
-          NOTE:
+         NOTE:
 
-         You should only build ohci1394 or firewire-ohci, but not both.
-         If you nevertheless want to install both, you should configure them
-         only as modules and blacklist the driver(s) which you don't want to
-         have auto-loaded.  Add either
+         You should only build either firewire-ohci or the old ohci1394 driver,
+         but not both.  If you nevertheless want to install both, you should
+         configure them only as modules and blacklist the driver(s) which you
+         don't want to have auto-loaded.  Add either
 
              blacklist firewire-ohci
          or
@@ -60,7 +58,7 @@ config FIREWIRE_OHCI_DEBUG
        default y
 
 config FIREWIRE_SBP2
-       tristate "Support for storage devices (SBP-2 protocol driver)"
+       tristate "Storage devices (SBP-2 protocol)"
        depends on FIREWIRE && SCSI
        help
          This option enables you to use SBP-2 devices connected to a
index dda14015e873dce10c4bfbd796b03952d079b9b3..c639915fc3cbc8637c39d93927488b1350001cc6 100644 (file)
@@ -205,6 +205,7 @@ fw_device_op_read(struct file *file,
        return dequeue_event(client, buffer, count);
 }
 
+/* caller must hold card->lock so that node pointers can be dereferenced here */
 static void
 fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
                     struct client *client)
@@ -214,7 +215,6 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event,
        event->closure       = client->bus_reset_closure;
        event->type          = FW_CDEV_EVENT_BUS_RESET;
        event->generation    = client->device->generation;
-       smp_rmb();           /* node_id must not be older than generation */
        event->node_id       = client->device->node_id;
        event->local_node_id = card->local_node->node_id;
        event->bm_node_id    = 0; /* FIXME: We don't track the BM. */
@@ -274,6 +274,7 @@ static int ioctl_get_info(struct client *client, void *buffer)
 {
        struct fw_cdev_get_info *get_info = buffer;
        struct fw_cdev_event_bus_reset bus_reset;
+       struct fw_card *card = client->device->card;
        unsigned long ret = 0;
 
        client->version = get_info->version;
@@ -299,13 +300,17 @@ static int ioctl_get_info(struct client *client, void *buffer)
        client->bus_reset_closure = get_info->bus_reset_closure;
        if (get_info->bus_reset != 0) {
                void __user *uptr = u64_to_uptr(get_info->bus_reset);
+               unsigned long flags;
 
+               spin_lock_irqsave(&card->lock, flags);
                fill_bus_reset_event(&bus_reset, client);
+               spin_unlock_irqrestore(&card->lock, flags);
+
                if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset)))
                        return -EFAULT;
        }
 
-       get_info->card = client->device->card->index;
+       get_info->card = card->index;
 
        return 0;
 }
index 4f02c55f13e15131b95bc615e540e2931ad63d96..0b66306af479e4d9fdd359dac87f335b31ae89b6 100644 (file)
@@ -265,27 +265,25 @@ static void log_irqs(u32 evt)
            !(evt & OHCI1394_busReset))
                return;
 
-       printk(KERN_DEBUG KBUILD_MODNAME ": IRQ "
-              "%08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-              evt,
-              evt & OHCI1394_selfIDComplete    ? " selfID"             : "",
-              evt & OHCI1394_RQPkt             ? " AR_req"             : "",
-              evt & OHCI1394_RSPkt             ? " AR_resp"            : "",
-              evt & OHCI1394_reqTxComplete     ? " AT_req"             : "",
-              evt & OHCI1394_respTxComplete    ? " AT_resp"            : "",
-              evt & OHCI1394_isochRx           ? " IR"                 : "",
-              evt & OHCI1394_isochTx           ? " IT"                 : "",
-              evt & OHCI1394_postedWriteErr    ? " postedWriteErr"     : "",
-              evt & OHCI1394_cycleTooLong      ? " cycleTooLong"       : "",
-              evt & OHCI1394_cycle64Seconds    ? " cycle64Seconds"     : "",
-              evt & OHCI1394_regAccessFail     ? " regAccessFail"      : "",
-              evt & OHCI1394_busReset          ? " busReset"           : "",
-              evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
-                      OHCI1394_RSPkt | OHCI1394_reqTxComplete |
-                      OHCI1394_respTxComplete | OHCI1394_isochRx |
-                      OHCI1394_isochTx | OHCI1394_postedWriteErr |
-                      OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
-                      OHCI1394_regAccessFail | OHCI1394_busReset)
+       fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
+           evt & OHCI1394_selfIDComplete       ? " selfID"             : "",
+           evt & OHCI1394_RQPkt                ? " AR_req"             : "",
+           evt & OHCI1394_RSPkt                ? " AR_resp"            : "",
+           evt & OHCI1394_reqTxComplete        ? " AT_req"             : "",
+           evt & OHCI1394_respTxComplete       ? " AT_resp"            : "",
+           evt & OHCI1394_isochRx              ? " IR"                 : "",
+           evt & OHCI1394_isochTx              ? " IT"                 : "",
+           evt & OHCI1394_postedWriteErr       ? " postedWriteErr"     : "",
+           evt & OHCI1394_cycleTooLong         ? " cycleTooLong"       : "",
+           evt & OHCI1394_cycle64Seconds       ? " cycle64Seconds"     : "",
+           evt & OHCI1394_regAccessFail        ? " regAccessFail"      : "",
+           evt & OHCI1394_busReset             ? " busReset"           : "",
+           evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
+                   OHCI1394_RSPkt | OHCI1394_reqTxComplete |
+                   OHCI1394_respTxComplete | OHCI1394_isochRx |
+                   OHCI1394_isochTx | OHCI1394_postedWriteErr |
+                   OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
+                   OHCI1394_regAccessFail | OHCI1394_busReset)
                                                ? " ?"                  : "");
 }
 
@@ -308,23 +306,22 @@ static void log_selfids(int node_id, int generation, int self_id_count, u32 *s)
        if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS)))
                return;
 
-       printk(KERN_DEBUG KBUILD_MODNAME ": %d selfIDs, generation %d, "
-              "local node ID %04x\n", self_id_count, generation, node_id);
+       fw_notify("%d selfIDs, generation %d, local node ID %04x\n",
+                 self_id_count, generation, node_id);
 
        for (; self_id_count--; ++s)
                if ((*s & 1 << 23) == 0)
-                       printk(KERN_DEBUG "selfID 0: %08x, phy %d [%c%c%c] "
-                              "%s gc=%d %s %s%s%s\n",
-                              *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2),
-                              speed[*s >> 14 & 3], *s >> 16 & 63,
-                              power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "",
-                              *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : "");
+                       fw_notify("selfID 0: %08x, phy %d [%c%c%c] "
+                           "%s gc=%d %s %s%s%s\n",
+                           *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2),
+                           speed[*s >> 14 & 3], *s >> 16 & 63,
+                           power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "",
+                           *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : "");
                else
-                       printk(KERN_DEBUG "selfID n: %08x, phy %d "
-                              "[%c%c%c%c%c%c%c%c]\n",
-                              *s, *s >> 24 & 63,
-                              _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10),
-                              _p(s,  8), _p(s,  6), _p(s,  4), _p(s,  2));
+                       fw_notify("selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n",
+                           *s, *s >> 24 & 63,
+                           _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10),
+                           _p(s,  8), _p(s,  6), _p(s,  4), _p(s,  2));
 }
 
 static const char *evts[] = {
@@ -373,15 +370,14 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
                        evt = 0x1f;
 
        if (evt == OHCI1394_evt_bus_reset) {
-               printk(KERN_DEBUG "A%c evt_bus_reset, generation %d\n",
-                      dir, (header[2] >> 16) & 0xff);
+               fw_notify("A%c evt_bus_reset, generation %d\n",
+                   dir, (header[2] >> 16) & 0xff);
                return;
        }
 
        if (header[0] == ~header[1]) {
-               printk(KERN_DEBUG "A%c %s, %s, %08x\n",
-                      dir, evts[evt], phys[header[0] >> 30 & 0x3],
-                      header[0]);
+               fw_notify("A%c %s, %s, %08x\n",
+                   dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]);
                return;
        }
 
@@ -400,24 +396,23 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
 
        switch (tcode) {
        case 0xe: case 0xa:
-               printk(KERN_DEBUG "A%c %s, %s\n",
-                      dir, evts[evt], tcodes[tcode]);
+               fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]);
                break;
        case 0x0: case 0x1: case 0x4: case 0x5: case 0x9:
-               printk(KERN_DEBUG "A%c spd %x tl %02x, "
-                      "%04x -> %04x, %s, "
-                      "%s, %04x%08x%s\n",
-                      dir, speed, header[0] >> 10 & 0x3f,
-                      header[1] >> 16, header[0] >> 16, evts[evt],
-                      tcodes[tcode], header[1] & 0xffff, header[2], specific);
+               fw_notify("A%c spd %x tl %02x, "
+                   "%04x -> %04x, %s, "
+                   "%s, %04x%08x%s\n",
+                   dir, speed, header[0] >> 10 & 0x3f,
+                   header[1] >> 16, header[0] >> 16, evts[evt],
+                   tcodes[tcode], header[1] & 0xffff, header[2], specific);
                break;
        default:
-               printk(KERN_DEBUG "A%c spd %x tl %02x, "
-                      "%04x -> %04x, %s, "
-                      "%s%s\n",
-                      dir, speed, header[0] >> 10 & 0x3f,
-                      header[1] >> 16, header[0] >> 16, evts[evt],
-                      tcodes[tcode], specific);
+               fw_notify("A%c spd %x tl %02x, "
+                   "%04x -> %04x, %s, "
+                   "%s%s\n",
+                   dir, speed, header[0] >> 10 & 0x3f,
+                   header[1] >> 16, header[0] >> 16, evts[evt],
+                   tcodes[tcode], specific);
        }
 }
 
@@ -548,6 +543,11 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
                p.header_length = 12;
                p.payload_length = 0;
                break;
+
+       default:
+               /* FIXME: Stop context, discard everything, and restart? */
+               p.header_length = 0;
+               p.payload_length = 0;
        }
 
        p.payload = (void *) buffer + p.header_length;
@@ -1468,6 +1468,9 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
        reg_write(ohci, OHCI1394_HCControlClear,
                  OHCI1394_HCControl_noByteSwapData);
 
+       reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
+       reg_write(ohci, OHCI1394_LinkControlClear,
+                 OHCI1394_LinkControl_rcvPhyPkt);
        reg_write(ohci, OHCI1394_LinkControlSet,
                  OHCI1394_LinkControl_rcvSelfID |
                  OHCI1394_LinkControl_cycleTimerEnable |
@@ -1481,7 +1484,6 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
        ar_context_run(&ohci->ar_request_ctx);
        ar_context_run(&ohci->ar_response_ctx);
 
-       reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
        reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
        reg_write(ohci, OHCI1394_IntEventClear, ~0);
        reg_write(ohci, OHCI1394_IntMaskClear, ~0);
index b2458bb8e9cade2fd79fea620b60eb9edd0aa7e0..227d2e036cd812f4e259fd13413298a818d16d6f 100644 (file)
@@ -1051,7 +1051,8 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
                        break;
 
                case SBP2_CSR_LOGICAL_UNIT_DIRECTORY:
-                       if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0)
+                       /* Adjust for the increment in the iterator */
+                       if (sbp2_scan_logical_unit_dir(tgt, ci.p - 1 + value) < 0)
                                return -ENOMEM;
                        break;
                }
index ccf0e4cf108f4b65298f1cde98041cc08027d7e2..03ae8a77c479f680da86de9cc1e407336bd23750 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/completion.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -297,37 +298,55 @@ EXPORT_SYMBOL(fw_send_request);
 struct fw_phy_packet {
        struct fw_packet packet;
        struct completion done;
+       struct kref kref;
 };
 
-static void
-transmit_phy_packet_callback(struct fw_packet *packet,
-                            struct fw_card *card, int status)
+static void phy_packet_release(struct kref *kref)
+{
+       struct fw_phy_packet *p =
+                       container_of(kref, struct fw_phy_packet, kref);
+       kfree(p);
+}
+
+static void transmit_phy_packet_callback(struct fw_packet *packet,
+                                        struct fw_card *card, int status)
 {
        struct fw_phy_packet *p =
                        container_of(packet, struct fw_phy_packet, packet);
 
        complete(&p->done);
+       kref_put(&p->kref, phy_packet_release);
 }
 
 void fw_send_phy_config(struct fw_card *card,
                        int node_id, int generation, int gap_count)
 {
-       struct fw_phy_packet p;
+       struct fw_phy_packet *p;
+       long timeout = DIV_ROUND_UP(HZ, 10);
        u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) |
                   PHY_CONFIG_ROOT_ID(node_id) |
                   PHY_CONFIG_GAP_COUNT(gap_count);
 
-       p.packet.header[0] = data;
-       p.packet.header[1] = ~data;
-       p.packet.header_length = 8;
-       p.packet.payload_length = 0;
-       p.packet.speed = SCODE_100;
-       p.packet.generation = generation;
-       p.packet.callback = transmit_phy_packet_callback;
-       init_completion(&p.done);
-
-       card->driver->send_request(card, &p.packet);
-       wait_for_completion(&p.done);
+       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       if (p == NULL)
+               return;
+
+       p->packet.header[0] = data;
+       p->packet.header[1] = ~data;
+       p->packet.header_length = 8;
+       p->packet.payload_length = 0;
+       p->packet.speed = SCODE_100;
+       p->packet.generation = generation;
+       p->packet.callback = transmit_phy_packet_callback;
+       init_completion(&p->done);
+       kref_set(&p->kref, 2);
+
+       card->driver->send_request(card, &p->packet);
+       timeout = wait_for_completion_timeout(&p->done, timeout);
+       kref_put(&p->kref, phy_packet_release);
+
+       /* will leak p if the callback is never executed */
+       WARN_ON(timeout == 0);
 }
 
 void fw_flush_transactions(struct fw_card *card)
@@ -572,7 +591,8 @@ allocate_request(struct fw_packet *p)
                break;
 
        default:
-               BUG();
+               fw_error("ERROR - corrupt request received - %08x %08x %08x\n",
+                        p->header[0], p->header[1], p->header[2]);
                return NULL;
        }
 
index ed33fddc4dee5689e8fae75e7b339692e9fcf6a1..f00f497b9ca9b38ed615a17955d42da607601214 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/platform_device.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/dmi.h>
 #include <asm/io.h>
 
 /* uGuru3 bank addresses */
@@ -323,7 +324,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX1 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0013, "unknown", {
+       { 0x0013, "Abit AW8D", {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -349,6 +350,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX2 Fan",           36, 2, 60, 1, 0 },
                { "AUX3 Fan",           37, 2, 60, 1, 0 },
                { "AUX4 Fan",           38, 2, 60, 1, 0 },
+               { "AUX5 Fan",           39, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
        { 0x0014, "Abit AB9 Pro", {
@@ -1111,11 +1113,12 @@ static int __init abituguru3_detect(void)
 {
        /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or
           0x08 at DATA and 0xAC at CMD. Sometimes the uGuru3 will hold 0x05
-          at CMD instead, why is unknown. So we test for 0x05 too. */
+          or 0x55 at CMD instead, why is unknown. */
        u8 data_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_DATA);
        u8 cmd_val = inb_p(ABIT_UGURU3_BASE + ABIT_UGURU3_CMD);
        if (((data_val == 0x00) || (data_val == 0x08)) &&
-                       ((cmd_val == 0xAC) || (cmd_val == 0x05)))
+                       ((cmd_val == 0xAC) || (cmd_val == 0x05) ||
+                        (cmd_val == 0x55)))
                return ABIT_UGURU3_BASE;
 
        ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = "
@@ -1138,6 +1141,15 @@ static int __init abituguru3_init(void)
        int address, err;
        struct resource res = { .flags = IORESOURCE_IO };
 
+#ifdef CONFIG_DMI
+       const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+
+       /* safety check, refuse to load on non Abit motherboards */
+       if (!force && (!board_vendor ||
+                       strcmp(board_vendor, "http://www.abit.com.tw/")))
+               return -ENODEV;
+#endif
+
        address = abituguru3_detect();
        if (address < 0)
                return address;
index c1009d6f97965b160d26ac4723235d97280a427c..93dbf5e7ff8a64751fd6be8b9faa5c0251ff0df4 100644 (file)
@@ -309,6 +309,9 @@ no_sensor_update:
                                                ADT7473_REG_PWM_BHVR(i));
        }
 
+       i = i2c_smbus_read_byte_data(client, ADT7473_REG_CFG4);
+       data->max_duty_at_overheat = !!(i & ADT7473_CFG4_MAX_DUTY_AT_OVT);
+
        data->limits_last_updated = local_jiffies;
        data->limits_valid = 1;
 
index fa7696905154ca1e14444ca2a95e946470084cd4..de698dc73020ccdf7edf88d8697fa1740c49c67b 100644 (file)
@@ -251,10 +251,13 @@ static int lm75_detach_client(struct i2c_client *client)
    the SMBus standard. */
 static int lm75_read_value(struct i2c_client *client, u8 reg)
 {
+       int value;
+
        if (reg == LM75_REG_CONF)
                return i2c_smbus_read_byte_data(client, reg);
-       else
-               return swab16(i2c_smbus_read_word_data(client, reg));
+
+       value = i2c_smbus_read_word_data(client, reg);
+       return (value < 0) ? value : swab16(value);
 }
 
 static int lm75_write_value(struct i2c_client *client, u8 reg, u16 value)
@@ -287,9 +290,16 @@ static struct lm75_data *lm75_update_device(struct device *dev)
                int i;
                dev_dbg(&client->dev, "Starting lm75 update\n");
 
-               for (i = 0; i < ARRAY_SIZE(data->temp); i++)
-                       data->temp[i] = lm75_read_value(client,
-                                                       LM75_REG_TEMP[i]);
+               for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
+                       int status;
+
+                       status = lm75_read_value(client, LM75_REG_TEMP[i]);
+                       if (status < 0)
+                               dev_dbg(&client->dev, "reg %d, err %d\n",
+                                               LM75_REG_TEMP[i], status);
+                       else
+                               data->temp[i] = status;
+               }
                data->last_updated = jiffies;
                data->valid = 1;
        }
index 182fe6a5605f9f7c64954f21c6ec3ecf88cb1aa7..ee5eca1c1921d9d1f7ba1d67bd638ed9d6ba2cb2 100644 (file)
@@ -192,23 +192,20 @@ static int RANGE_TO_REG( int range )
 {
        int i;
 
-       if ( range < lm85_range_map[0] ) { 
-               return 0 ;
-       } else if ( range > lm85_range_map[15] ) {
+       if (range >= lm85_range_map[15])
                return 15 ;
-       } else {  /* find closest match */
-               for ( i = 14 ; i >= 0 ; --i ) {
-                       if ( range > lm85_range_map[i] ) { /* range bracketed */
-                               if ((lm85_range_map[i+1] - range) < 
-                                       (range - lm85_range_map[i])) {
-                                       i++;
-                                       break;
-                               }
-                               break;
-                       }
+
+       /* Find the closest match */
+       for (i = 14; i >= 0; --i) {
+               if (range >= lm85_range_map[i]) {
+                       if ((lm85_range_map[i + 1] - range) <
+                                       (range - lm85_range_map[i]))
+                               return i + 1;
+                       return i;
                }
        }
-       return( i & 0x0f );
+
+       return 0;
 }
 #define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f])
 
index 1607536ff5fb3ec7da44b500157c1631703b3604..8e07de23d220911988d811f121bcd2b8d17e6699 100644 (file)
@@ -823,13 +823,6 @@ config BLK_DEV_IDE_RAPIDE
          Say Y here if you want to support the Yellowstone RapIDE controller
          manufactured for use with Acorn computers.
 
-config BLK_DEV_IDE_BAST
-       tristate "Simtec BAST / Thorcom VR1000 IDE support"
-       depends on ARM && (ARCH_BAST || MACH_VR1000)
-       help
-         Say Y here if you want to support the onboard IDE channels on the
-         Simtec BAST or the Thorcom VR1000
-
 config IDE_H8300
        tristate "H8300 IDE support"
        depends on H8300
index 936e7b0237f5499fe0305845679c12a96d025d16..5bc26053afa609c83e05426edc3d999cdef8d3a7 100644 (file)
@@ -1,7 +1,6 @@
 
 obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)       += icside.o
 obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)       += rapide.o
-obj-$(CONFIG_BLK_DEV_IDE_BAST)         += bast-ide.o
 obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710)  += palm_bk3710.o
 
 ifeq ($(CONFIG_IDE_ARM), m)
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
deleted file mode 100644 (file)
index 8e8c281..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2003-2004 Simtec Electronics
- *  Ben Dooks <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/arch/map.h>
-#include <asm/arch/bast-map.h>
-#include <asm/arch/bast-irq.h>
-
-#define DRV_NAME "bast-ide"
-
-static int __init bastide_register(unsigned int base, unsigned int aux, int irq)
-{
-       ide_hwif_t *hwif;
-       hw_regs_t hw;
-       int i;
-       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-
-       memset(&hw, 0, sizeof(hw));
-
-       base += BAST_IDE_CS;
-       aux  += BAST_IDE_CS;
-
-       for (i = 0; i <= 7; i++) {
-               hw.io_ports_array[i] = (unsigned long)base;
-               base += 0x20;
-       }
-
-       hw.io_ports.ctl_addr = aux + (6 * 0x20);
-       hw.irq = irq;
-       hw.chipset = ide_generic;
-
-       hwif = ide_find_port();
-       if (hwif == NULL)
-               goto out;
-
-       i = hwif->index;
-
-       ide_init_port_data(hwif, i);
-       ide_init_port_hw(hwif, &hw);
-       hwif->port_ops = NULL;
-
-       idx[0] = i;
-
-       ide_device_add(idx, NULL);
-out:
-       return 0;
-}
-
-static int __init bastide_init(void)
-{
-       unsigned long base = BAST_VA_IDEPRI + BAST_IDE_CS;
-
-       /* we can treat the VR1000 and the BAST the same */
-
-       if (!(machine_is_bast() || machine_is_vr1000()))
-               return 0;
-
-       printk("BAST: IDE driver, (c) 2003-2004 Simtec Electronics\n");
-
-       if (!request_mem_region(base, 0x400000, DRV_NAME)) {
-               printk(KERN_ERR "%s: resources busy\n", DRV_NAME);
-               return -EBUSY;
-       }
-
-       bastide_register(BAST_VA_IDEPRI, BAST_VA_IDEPRIAUX, IRQ_IDE0);
-       bastide_register(BAST_VA_IDESEC, BAST_VA_IDESECAUX, IRQ_IDE1);
-
-       return 0;
-}
-
-module_init(bastide_init);
-
-MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Simtec BAST / Thorcom VR1000 IDE driver");
index d024ac8fad14c95d2ac734f1c2f5d5549e5eda20..cc24803fadff72c45ecff00010888d7161ed7cf7 100644 (file)
@@ -353,8 +353,8 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
        struct clk *clkp;
        struct resource *mem, *irq;
        ide_hwif_t *hwif;
-       void __iomem *base;
-       int pribase, i;
+       unsigned long base;
+       int i;
        hw_regs_t hw;
        u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
 
@@ -374,22 +374,27 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev)
                printk(KERN_ERR "failed to get memory region resource\n");
                return -ENODEV;
        }
+
        irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (irq == NULL) {
                printk(KERN_ERR "failed to get IRQ resource\n");
                return -ENODEV;
        }
 
-       base = (void *)mem->start;
+       if (request_mem_region(mem->start, mem->end - mem->start + 1,
+                              "palm_bk3710") == NULL) {
+               printk(KERN_ERR "failed to request memory region\n");
+               return -EBUSY;
+       }
+
+       base = IO_ADDRESS(mem->start);
 
        /* Configure the Palm Chip controller */
-       palm_bk3710_chipinit(base);
+       palm_bk3710_chipinit((void __iomem *)base);
 
-       pribase = mem->start + IDE_PALM_ATA_PRI_REG_OFFSET;
        for (i = 0; i < IDE_NR_PORTS - 2; i++)
-               hw.io_ports_array[i] = pribase + i;
-       hw.io_ports.ctl_addr = mem->start +
-                       IDE_PALM_ATA_PRI_CTL_OFFSET;
+               hw.io_ports_array[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i;
+       hw.io_ports.ctl_addr = base + IDE_PALM_ATA_PRI_CTL_OFFSET;
        hw.irq = irq->start;
        hw.chipset = ide_palm3710;
 
@@ -434,4 +439,3 @@ static int __init palm_bk3710_init(void)
 
 module_init(palm_bk3710_init);
 MODULE_LICENSE("GPL");
-
index 0c908ca3ff79654ac3d0bf8fe500f32658d84016..ab545ffa15490367ed013bd9e04a674a1f2df76f 100644 (file)
@@ -225,10 +225,10 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
        u8 stat;
 
        /*
-        * Last sector was transfered, wait until drive is ready.
-        * This can take up to 10 usec, but we will wait max 1 ms.
+        * Last sector was transfered, wait until device is ready.  This can
+        * take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
         */
-       for (retries = 0; retries < 100; retries++) {
+       for (retries = 0; retries < 1000; retries++) {
                stat = ide_read_status(drive);
 
                if (stat & BUSY_STAT)
index f633b6b3c7f36e92ec5f709eaab0e21c54c552e3..3381424d70a195ed70bb3525e0160d96c18af033 100644 (file)
@@ -410,6 +410,7 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001),        /* Mitsubishi CFA */
        PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
        PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),        /* SanDisk CFA */
+       PCMCIA_DEVICE_MANF_CARD(0x004f, 0x0000),        /* Kingston */
        PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
        PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
        PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
@@ -439,6 +440,7 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
        PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDEII", 0x547e66dc, 0xb3662674),
        PCMCIA_DEVICE_PROD_ID12("LOOKMEET", "CBIDE2      ", 0xe37be2b5, 0x8671043b),
+       PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF300", 0x7ed2ad87, 0x7e9e78ee),
        PCMCIA_DEVICE_PROD_ID12("M-Systems", "CF500", 0x7ed2ad87, 0x7a13045c),
        PCMCIA_DEVICE_PROD_ID2("NinjaATA-", 0xebe0bd79),
        PCMCIA_DEVICE_PROD_ID12("PCMCIA", "CD-ROM", 0x281f1c5d, 0x66536591),
@@ -449,6 +451,7 @@ static struct pcmcia_device_id ide_ids[] = {
        PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6),
        PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003),
        PCMCIA_DEVICE_PROD_ID1("TRANSCEND    512M   ", 0xd0909443),
+       PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF45", 0x709b1bf1, 0xf68b6f32),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
        PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
index 545663ef820b3992211d4dab31a05ea28f7272c4..95f45f9b8e5efc67abc26ce53817bb8e398742f2 100644 (file)
@@ -4,7 +4,7 @@ menu "IEEE 1394 (FireWire) support"
 source "drivers/firewire/Kconfig"
 
 config IEEE1394
-       tristate "IEEE 1394 (FireWire) support"
+       tristate "Stable FireWire stack"
        depends on PCI || BROKEN
        help
          IEEE 1394 describes a high performance serial bus, which is also
@@ -19,30 +19,45 @@ config IEEE1394
          To compile this driver as a module, say M here: the
          module will be called ieee1394.
 
-comment "Subsystem Options"
-       depends on IEEE1394
-
-config IEEE1394_VERBOSEDEBUG
-       bool "Excessive debugging output"
-       depends on IEEE1394
+config IEEE1394_OHCI1394
+       tristate "OHCI-1394 controllers"
+       depends on PCI && IEEE1394
        help
-         If you say Y here, you will get very verbose debugging logs from
-         the subsystem which includes a dump of the header of every sent
-         and received packet.  This can amount to a high amount of data
-         collected in a very short time which is usually also saved to
-         disk by the system logging daemons.
+         Enable this driver if you have an IEEE 1394 controller based on the
+         OHCI-1394 specification. The current driver is only tested with OHCI
+         chipsets made by Texas Instruments and NEC. Most third-party vendors
+         use one of these chipsets.  It should work with any OHCI-1394
+         compliant card, however.
 
-         Say Y if you really want or need the debugging output, everyone
-         else says N.
+         To compile this driver as a module, say M here: the
+         module will be called ohci1394.
 
-comment "Controllers"
-       depends on IEEE1394
+         NOTE:
 
-comment "Texas Instruments PCILynx requires I2C"
+         You should only build either ohci1394 or the new firewire-ohci driver,
+         but not both.  If you nevertheless want to install both, you should
+         configure them only as modules and blacklist the driver(s) which you
+         don't want to have auto-loaded.  Add either
+
+             blacklist firewire-ohci
+         or
+             blacklist ohci1394
+             blacklist video1394
+             blacklist dv1394
+
+         to /etc/modprobe.conf or /etc/modprobe.d/* and update modprobe.conf
+         depending on your distribution.  The latter two modules should be
+         blacklisted together with ohci1394 because they depend on ohci1394.
+
+         If you have an old modprobe which doesn't implement the blacklist
+         directive, use "install modulename /bin/true" for the modules to be
+         blacklisted.
+
+comment "PCILynx controller requires I2C"
        depends on IEEE1394 && I2C=n
 
 config IEEE1394_PCILYNX
-       tristate "Texas Instruments PCILynx support"
+       tristate "PCILynx controller"
        depends on PCI && IEEE1394 && I2C
        select I2C_ALGOBIT
        help
@@ -57,35 +72,11 @@ config IEEE1394_PCILYNX
          PowerMacs G3 B&W contain the PCILynx controller.  Therefore
          almost everybody can say N here.
 
-config IEEE1394_OHCI1394
-       tristate "OHCI-1394 support"
-       depends on PCI && IEEE1394
-       help
-         Enable this driver if you have an IEEE 1394 controller based on the
-         OHCI-1394 specification. The current driver is only tested with OHCI
-         chipsets made by Texas Instruments and NEC. Most third-party vendors
-         use one of these chipsets.  It should work with any OHCI-1394
-         compliant card, however.
-
-         To compile this driver as a module, say M here: the
-         module will be called ohci1394.
-
-comment "Protocols"
-       depends on IEEE1394
-
-config IEEE1394_VIDEO1394
-       tristate "OHCI-1394 Video support"
-       depends on IEEE1394 && IEEE1394_OHCI1394
-       help
-         This option enables video device usage for OHCI-1394 cards.  Enable
-         this option only if you have an IEEE 1394 video device connected to
-         an OHCI-1394 card.
-
 comment "SBP-2 support (for storage devices) requires SCSI"
        depends on IEEE1394 && SCSI=n
 
 config IEEE1394_SBP2
-       tristate "SBP-2 support (Harddisks etc.)"
+       tristate "Storage devices (SBP-2 protocol)"
        depends on IEEE1394 && SCSI
        help
          This option enables you to use SBP-2 devices connected to an IEEE
@@ -127,24 +118,47 @@ config IEEE1394_ETH1394
 
          The module is called eth1394 although it does not emulate Ethernet.
 
+config IEEE1394_RAWIO
+       tristate "raw1394 userspace interface"
+       depends on IEEE1394
+       help
+         This option adds support for the raw1394 device file which enables
+         direct communication of user programs with IEEE 1394 devices
+         (isochronous and asynchronous).  Almost all application programs
+         which access FireWire require this option.
+
+         To compile this driver as a module, say M here: the module will be
+         called raw1394.
+
+config IEEE1394_VIDEO1394
+       tristate "video1394 userspace interface"
+       depends on IEEE1394 && IEEE1394_OHCI1394
+       help
+         This option adds support for the video1394 device files which enable
+         isochronous communication of user programs with IEEE 1394 devices,
+         especially video capture or export.  This interface is used by all
+         libdc1394 based programs and by several other programs, in addition to
+         the raw1394 interface.  It is generally not required for DV capture.
+
+         To compile this driver as a module, say M here: the module will be
+         called video1394.
+
 config IEEE1394_DV1394
-       tristate "OHCI-DV I/O support (deprecated)"
+       tristate "dv1394 userspace interface (deprecated)"
        depends on IEEE1394 && IEEE1394_OHCI1394
        help
          The dv1394 driver is unsupported and may be removed from Linux in a
          future release.  Its functionality is now provided by raw1394 together
          with libraries such as libiec61883.
 
-config IEEE1394_RAWIO
-       tristate "Raw IEEE1394 I/O support"
+config IEEE1394_VERBOSEDEBUG
+       bool "Excessive debugging output"
        depends on IEEE1394
        help
-         This option adds support for the raw1394 device file which enables
-         direct communication of user programs with the IEEE 1394 bus and thus
-         with the attached peripherals.  Almost all application programs which
-         access FireWire require this option.
+         If you say Y here, you will get very verbose debugging logs from the
+         ieee1394 drivers, including sent and received packet headers.  This
+         will quickly result in large amounts of data sent to the system log.
 
-         To compile this driver as a module, say M here: the module will be
-         called raw1394.
+         Say Y if you really need the debugging output.  Everyone else says N.
 
 endmenu
index b224079d4e1fd8898944de6c083e1889eabadf6f..d5862e5d99a09ce89509976b9bdc5049e49e5b26 100644 (file)
@@ -109,7 +109,11 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
 {
        struct page *page;
 
-       page = alloc_pages(gfp_mask, order);
+       /*
+        * Use __GFP_ZERO because buggy firmware assumes ICM pages are
+        * cleared, and subtle failures are seen if they aren't.
+        */
+       page = alloc_pages(gfp_mask | __GFP_ZERO, order);
        if (!page)
                return -ENOMEM;
 
index eebc72465fc9beb44d2ecfa77a78d24cbd31f891..72c63e5dd630709ddffccf8dc945147857bf41ba 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/sched.h>
 
 /*
  * Check that the effect_id is a valid effect and whether the user
@@ -166,8 +167,10 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect,
        if (ret)
                goto out;
 
+       spin_lock_irq(&dev->event_lock);
        ff->effects[id] = *effect;
        ff->effect_owners[id] = file;
+       spin_unlock_irq(&dev->event_lock);
 
  out:
        mutex_unlock(&ff->mutex);
@@ -189,16 +192,22 @@ static int erase_effect(struct input_dev *dev, int effect_id,
        if (error)
                return error;
 
+       spin_lock_irq(&dev->event_lock);
        ff->playback(dev, effect_id, 0);
+       ff->effect_owners[effect_id] = NULL;
+       spin_unlock_irq(&dev->event_lock);
 
        if (ff->erase) {
                error = ff->erase(dev, effect_id);
-               if (error)
+               if (error) {
+                       spin_lock_irq(&dev->event_lock);
+                       ff->effect_owners[effect_id] = file;
+                       spin_unlock_irq(&dev->event_lock);
+
                        return error;
+               }
        }
 
-       ff->effect_owners[effect_id] = NULL;
-
        return 0;
 }
 
@@ -263,8 +272,6 @@ int input_ff_event(struct input_dev *dev, unsigned int type,
        if (type != EV_FF)
                return 0;
 
-       mutex_lock(&ff->mutex);
-
        switch (code) {
        case FF_GAIN:
                if (!test_bit(FF_GAIN, dev->ffbit) || value > 0xffff)
@@ -286,7 +293,6 @@ int input_ff_event(struct input_dev *dev, unsigned int type,
                break;
        }
 
-       mutex_unlock(&ff->mutex);
        return 0;
 }
 EXPORT_SYMBOL_GPL(input_ff_event);
index 835def11419d36d7b56e0e216028714d384ad0f9..ab6a61db63ce2248b5553ec43678fab61642e9a7 100644 (file)
@@ -432,6 +432,7 @@ static int crypt_convert(struct crypt_config *cc,
                case 0:
                        atomic_dec(&ctx->pending);
                        ctx->sector++;
+                       cond_resched();
                        continue;
 
                /* error */
index 7cf512a34ccfc1ecd84c5264aff7d44184a14d95..2580ac1b9b0ff06f34d37f12ea829682017e5ef1 100644 (file)
@@ -3897,8 +3897,10 @@ static void autorun_devices(int part)
 
                md_probe(dev, NULL, NULL);
                mddev = mddev_find(dev);
-               if (!mddev) {
-                       printk(KERN_ERR 
+               if (!mddev || !mddev->gendisk) {
+                       if (mddev)
+                               mddev_put(mddev);
+                       printk(KERN_ERR
                                "md: cannot allocate memory for md drive.\n");
                        break;
                }
index 1de17da34a956e8383efb1b42474c3c4d3d15dbe..a71277b640ab036bea60206e29900c034ddd50a3 100644 (file)
@@ -2137,6 +2137,8 @@ static int run(mddev_t *mddev)
                    !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
+                       if (disk->rdev)
+                               conf->fullsync = 1;
                }
        }
 
index c37e256b117603f8f68aed3de3a40db9328e70f6..54c8ee28fcc4940517262389b16d4de1030709f3 100644 (file)
@@ -2898,6 +2898,8 @@ static void handle_stripe5(struct stripe_head *sh)
 
                for (i = conf->raid_disks; i--; ) {
                        set_bit(R5_Wantwrite, &sh->dev[i].flags);
+                       set_bit(R5_LOCKED, &dev->flags);
+                       s.locked++;
                        if (!test_and_set_bit(STRIPE_OP_IO, &sh->ops.pending))
                                sh->ops.count++;
                }
@@ -2911,6 +2913,7 @@ static void handle_stripe5(struct stripe_head *sh)
                        conf->raid_disks);
                s.locked += handle_write_operations5(sh, 1, 1);
        } else if (s.expanded &&
+                  s.locked == 0 &&
                !test_bit(STRIPE_OP_POSTXOR, &sh->ops.pending)) {
                clear_bit(STRIPE_EXPAND_READY, &sh->state);
                atomic_dec(&conf->reshape_stripes);
@@ -4305,7 +4308,9 @@ static int run(mddev_t *mddev)
                                " disk %d\n", bdevname(rdev->bdev,b),
                                raid_disk);
                        working_disks++;
-               }
+               } else
+                       /* Cannot rely on bitmap to complete recovery */
+                       conf->fullsync = 1;
        }
 
        /*
index a3485817e46c9e06b765bda262fdd9f8215b7168..8fa91f846d591bcd35d544d87aec42edbbfc5b96 100644 (file)
@@ -2201,3 +2201,41 @@ IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE] = {
        [0x25] = KEY_POWER,             /* power */
 };
 EXPORT_SYMBOL_GPL(ir_codes_powercolor_real_angel);
+
+IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
+       [0x20] = KEY_LIST,
+       [0x00] = KEY_POWER,
+       [0x28] = KEY_1,
+       [0x18] = KEY_2,
+       [0x38] = KEY_3,
+       [0x24] = KEY_4,
+       [0x14] = KEY_5,
+       [0x34] = KEY_6,
+       [0x2c] = KEY_7,
+       [0x1c] = KEY_8,
+       [0x3c] = KEY_9,
+       [0x12] = KEY_SUBTITLE,
+       [0x22] = KEY_0,
+       [0x32] = KEY_REWIND,
+       [0x3a] = KEY_SHUFFLE,
+       [0x02] = KEY_PRINT,
+       [0x11] = KEY_CHANNELDOWN,
+       [0x31] = KEY_CHANNELUP,
+       [0x0c] = KEY_ZOOM,
+       [0x1e] = KEY_VOLUMEDOWN,
+       [0x3e] = KEY_VOLUMEUP,
+       [0x0a] = KEY_MUTE,
+       [0x04] = KEY_AUDIO,
+       [0x26] = KEY_RECORD,
+       [0x06] = KEY_PLAY,
+       [0x36] = KEY_STOP,
+       [0x16] = KEY_PAUSE,
+       [0x2e] = KEY_REWIND,
+       [0x0e] = KEY_FASTFORWARD,
+       [0x30] = KEY_TEXT,
+       [0x21] = KEY_GREEN,
+       [0x01] = KEY_BLUE,
+       [0x08] = KEY_EPG,
+       [0x2a] = KEY_MENU,
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_a16d);
index f1894fec32b930343d69f0665a698ed267b8e731..6fb5b45865690b3a4279e891d09cf43e222a7dee 100644 (file)
@@ -649,9 +649,17 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
        u8 val;
 
        int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val);
+       /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range
+        * for frequencies above 61.1 MHz.  In these cases, the internal RF
+        * tracking filters calibration mechanism is used.
+        *
+        * There is no need to warn the user about this.
+        */
+       if (ret < 0)
+               goto fail;
 
        regs[R_EB14] = val;
-
+fail:
        return ret;
 }
 
index 89c01fb1f85981c5cbfa909e1579c2f75212cf07..93063c6fbbf634e42aac29b3502de2b66104e232 100644 (file)
@@ -45,6 +45,21 @@ static inline int charge_pump_source(struct dvb_frontend *fe, int force)
                                           TDA18271_MAIN_PLL, force);
 }
 
+static inline void tda18271_set_if_notch(struct dvb_frontend *fe)
+{
+       struct tda18271_priv *priv = fe->tuner_priv;
+       unsigned char *regs = priv->tda18271_regs;
+
+       switch (priv->mode) {
+       case TDA18271_ANALOG:
+               regs[R_MPD]  &= ~0x80; /* IF notch = 0 */
+               break;
+       case TDA18271_DIGITAL:
+               regs[R_MPD]  |= 0x80; /* IF notch = 1 */
+               break;
+       }
+}
+
 static int tda18271_channel_configuration(struct dvb_frontend *fe,
                                          struct tda18271_std_map_item *map,
                                          u32 freq, u32 bw)
@@ -60,25 +75,18 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
        regs[R_EP3]  &= ~0x1f; /* clear std bits */
        regs[R_EP3]  |= (map->agc_mode << 3) | map->std;
 
-       /* set rfagc to high speed mode */
-       regs[R_EP3] &= ~0x04;
+       if (priv->id == TDA18271HDC2) {
+               /* set rfagc to high speed mode */
+               regs[R_EP3] &= ~0x04;
+       }
 
        /* set cal mode to normal */
        regs[R_EP4]  &= ~0x03;
 
-       /* update IF output level & IF notch frequency */
+       /* update IF output level */
        regs[R_EP4]  &= ~0x1c; /* clear if level bits */
        regs[R_EP4]  |= (map->if_lvl << 2);
 
-       switch (priv->mode) {
-       case TDA18271_ANALOG:
-               regs[R_MPD]  &= ~0x80; /* IF notch = 0 */
-               break;
-       case TDA18271_DIGITAL:
-               regs[R_MPD]  |= 0x80; /* IF notch = 1 */
-               break;
-       }
-
        /* update FM_RFn */
        regs[R_EP4]  &= ~0x80;
        regs[R_EP4]  |= map->fm_rfn << 7;
@@ -95,6 +103,9 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
        /* disable Power Level Indicator */
        regs[R_EP1]  |= 0x40;
 
+       /* make sure thermometer is off */
+       regs[R_TM]   &= ~0x10;
+
        /* frequency dependent parameters */
 
        tda18271_calc_ir_measure(fe, &freq);
@@ -135,6 +146,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
        switch (priv->role) {
        case TDA18271_MASTER:
                tda18271_calc_main_pll(fe, N);
+               tda18271_set_if_notch(fe);
                tda18271_write_regs(fe, R_MPD, 4);
                break;
        case TDA18271_SLAVE:
@@ -142,6 +154,7 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
                tda18271_write_regs(fe, R_CPD, 4);
 
                regs[R_MPD] = regs[R_CPD] & 0x7f;
+               tda18271_set_if_notch(fe);
                tda18271_write_regs(fe, R_MPD, 1);
                break;
        }
@@ -160,12 +173,14 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe,
 
        msleep(20);
 
-       /* set rfagc to normal speed mode */
-       if (map->fm_rfn)
-               regs[R_EP3] &= ~0x04;
-       else
-               regs[R_EP3] |= 0x04;
-       ret = tda18271_write_regs(fe, R_EP3, 1);
+       if (priv->id == TDA18271HDC2) {
+               /* set rfagc to normal speed mode */
+               if (map->fm_rfn)
+                       regs[R_EP3] &= ~0x04;
+               else
+                       regs[R_EP3] |= 0x04;
+               ret = tda18271_write_regs(fe, R_EP3, 1);
+       }
 fail:
        return ret;
 }
@@ -507,7 +522,7 @@ static int tda18271_powerscan_init(struct dvb_frontend *fe)
        /* set cal mode to normal */
        regs[R_EP4]  &= ~0x03;
 
-       /* update IF output level & IF notch frequency */
+       /* update IF output level */
        regs[R_EP4]  &= ~0x1c; /* clear if level bits */
 
        ret = tda18271_write_regs(fe, R_EP3, 2);
index ceae6db901ecaa9543f5e4ef4bcd727e3d10cc42..7cf4f5bdb2ecef54de97f6af81407bb098964932 100644 (file)
@@ -177,6 +177,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
        {"FM Radio-INPUT1",   0x0208, 0x9002}
 };
 
+static int  xc5000_is_firmware_loaded(struct dvb_frontend *fe);
 static int  xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len);
 static int  xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len);
 static void xc5000_TunerReset(struct dvb_frontend *fe);
@@ -352,7 +353,7 @@ static int xc_SetTVStandard(struct xc5000_priv *priv,
 
 static int xc_shutdown(struct xc5000_priv *priv)
 {
-       return 0;
+       return XC_RESULT_SUCCESS;
        /* Fixme: cannot bring tuner back alive once shutdown
         *        without reloading the driver modules.
         *    return xc_write_reg(priv, XREG_POWER_DOWN, 0);
@@ -685,6 +686,25 @@ static int xc5000_set_params(struct dvb_frontend *fe,
        return 0;
 }
 
+static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
+{
+       struct xc5000_priv *priv = fe->tuner_priv;
+       int ret;
+       u16 id;
+
+       ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
+       if (ret == XC_RESULT_SUCCESS) {
+               if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
+                       ret = XC_RESULT_RESET_FAILURE;
+               else
+                       ret = XC_RESULT_SUCCESS;
+       }
+
+       dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
+               ret == XC_RESULT_SUCCESS ? "True" : "False", id);
+       return ret;
+}
+
 static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
 
 static int xc5000_set_analog_params(struct dvb_frontend *fe,
@@ -693,7 +713,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
        struct xc5000_priv *priv = fe->tuner_priv;
        int ret;
 
-       if(priv->fwloaded == 0)
+       if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
                xc_load_fw_and_init_tuner(fe);
 
        dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
@@ -808,11 +828,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
        struct xc5000_priv *priv = fe->tuner_priv;
        int ret = 0;
 
-       if (priv->fwloaded == 0) {
+       if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
                ret = xc5000_fwupload(fe);
                if (ret != XC_RESULT_SUCCESS)
                        return ret;
-               priv->fwloaded = 1;
        }
 
        /* Start the tuner self-calibration process */
@@ -852,7 +871,6 @@ static int xc5000_sleep(struct dvb_frontend *fe)
                return -EREMOTEIO;
        }
        else {
-               /* priv->fwloaded = 0; */
                return XC_RESULT_SUCCESS;
        }
 }
@@ -933,7 +951,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
                        cfg->i2c_address);
                printk(KERN_INFO
                        "xc5000: Firmware has been loaded previously\n");
-               priv->fwloaded = 1;
                break;
        case XC_PRODUCT_ID_FW_NOT_LOADED:
                printk(KERN_INFO
@@ -941,7 +958,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
                        cfg->i2c_address);
                printk(KERN_INFO
                        "xc5000: Firmware has not been loaded previously\n");
-               priv->fwloaded = 0;
                break;
        default:
                printk(KERN_ERR
index ecebfe4745adcadf30e3f2a82d31b00c3b21210e..a72a9887fe7ffeab488da51193be130ba7d98767 100644 (file)
@@ -30,7 +30,6 @@ struct xc5000_priv {
        u32 bandwidth;
        u8  video_standard;
        u8  rf_mode;
-       u8  fwloaded;
 
        void *devptr;
 };
index 0a8ac64a4e33a6a345cd6eea538b7397a33c6536..037f7ffb47b297e6696fd167b8849143cac654f6 100644 (file)
@@ -47,6 +47,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
                return -EINVAL;
        }
 
+       msleep(1); /* avoid I2C errors */
+
        return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
                               value, index, rbuf, rlen, 2000);
 }
@@ -92,16 +94,6 @@ static struct i2c_algorithm gl861_i2c_algo = {
 };
 
 /* Callbacks for DVB USB */
-static int gl861_identify_state(struct usb_device *udev,
-                               struct dvb_usb_device_properties *props,
-                               struct dvb_usb_device_description **desc,
-                               int *cold)
-{
-       *cold = 0;
-
-       return 0;
-}
-
 static struct zl10353_config gl861_zl10353_config = {
        .demod_address = 0x0f,
        .no_tuner = 1,
@@ -172,7 +164,6 @@ static struct dvb_usb_device_properties gl861_properties = {
 
        .size_of_priv     = 0,
 
-       .identify_state   = gl861_identify_state,
        .num_adapters = 1,
        .adapter = {{
 
@@ -194,13 +185,15 @@ static struct dvb_usb_device_properties gl861_properties = {
 
        .num_device_descs = 2,
        .devices = {
-               {   "MSI Mega Sky 55801 DVB-T USB2.0",
-                       { &gl861_table[0], NULL },
-                       { NULL },
+               {
+                       .name = "MSI Mega Sky 55801 DVB-T USB2.0",
+                       .cold_ids = { NULL },
+                       .warm_ids = { &gl861_table[0], NULL },
                },
-               {   "A-LINK DTU DVB-T USB2.0",
-                       { &gl861_table[1], NULL },
-                       { NULL },
+               {
+                       .name = "A-LINK DTU DVB-T USB2.0",
+                       .cold_ids = { NULL },
+                       .warm_ids = { &gl861_table[1], NULL },
                },
        }
 };
index 9e7653bb3b660bc4c44985db551cf94e0f65ee5e..118aab1a3e540943e7a325f5836999e4c4819d5f 100644 (file)
@@ -107,7 +107,7 @@ static struct dvb_usb_device_properties umt_properties = {
                        /* parameter for the MPEG2-data transfer */
                        .stream = {
                                .type = USB_BULK,
-                               .count = 20,
+                               .count = MAX_NO_URBS_FOR_DATA_STREAM,
                                .endpoint = 0x06,
                                .u = {
                                        .bulk = {
index 084a280c2d7f97cbf6835e1f6e5bf73cf363f8d3..03900d241a76da067545aaba61916d4c88385291 100644 (file)
@@ -463,10 +463,13 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
                               struct dvb_frontend_parameters *p)
 {
        struct au8522_state *state = fe->demodulator_priv;
+       int ret = -EINVAL;
 
        dprintk("%s(frequency=%d)\n", __func__, p->frequency);
 
-       state->current_frequency = p->frequency;
+       if ((state->current_frequency == p->frequency) &&
+           (state->current_modulation == p->u.vsb.modulation))
+               return 0;
 
        au8522_enable_modulation(fe, p->u.vsb.modulation);
 
@@ -476,11 +479,16 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
        if (fe->ops.tuner_ops.set_params) {
                if (fe->ops.i2c_gate_ctrl)
                        fe->ops.i2c_gate_ctrl(fe, 1);
-               fe->ops.tuner_ops.set_params(fe, p);
+               ret = fe->ops.tuner_ops.set_params(fe, p);
                if (fe->ops.i2c_gate_ctrl)
                        fe->ops.i2c_gate_ctrl(fe, 0);
        }
 
+       if (ret < 0)
+               return ret;
+
+       state->current_frequency = p->frequency;
+
        return 0;
 }
 
@@ -498,6 +506,16 @@ static int au8522_init(struct dvb_frontend *fe)
        return 0;
 }
 
+static int au8522_sleep(struct dvb_frontend *fe)
+{
+       struct au8522_state *state = fe->demodulator_priv;
+       dprintk("%s()\n", __func__);
+
+       state->current_frequency = 0;
+
+       return 0;
+}
+
 static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
 {
        struct au8522_state *state = fe->demodulator_priv;
@@ -509,10 +527,8 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
        if (state->current_modulation == VSB_8) {
                dprintk("%s() Checking VSB_8\n", __func__);
                reg = au8522_readreg(state, 0x4088);
-               if (reg & 0x01)
-                       *status |= FE_HAS_VITERBI;
-               if (reg & 0x02)
-                       *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+               if ((reg & 0x03) == 0x03)
+                       *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
        } else {
                dprintk("%s() Checking QAM\n", __func__);
                reg = au8522_readreg(state, 0x4541);
@@ -672,6 +688,7 @@ static struct dvb_frontend_ops au8522_ops = {
        },
 
        .init                 = au8522_init,
+       .sleep                = au8522_sleep,
        .i2c_gate_ctrl        = au8522_i2c_gate_ctrl,
        .set_frontend         = au8522_set_frontend,
        .get_frontend         = au8522_get_frontend,
index 17556183e871629c2ae4fabc116c598ce233ea70..35435bef8e7992af4e1e8648a8c408b0f2d62f18 100644 (file)
@@ -63,6 +63,7 @@ struct stv0299_state {
        u32 symbol_rate;
        fe_code_rate_t fec_inner;
        int errmode;
+       u32 ucblocks;
 };
 
 #define STATUS_BER 0
@@ -501,8 +502,10 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
 {
        struct stv0299_state* state = fe->demodulator_priv;
 
-       if (state->errmode != STATUS_BER) return 0;
-       *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+       if (state->errmode != STATUS_BER)
+               return -ENOSYS;
+
+       *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
 
        return 0;
 }
@@ -540,8 +543,12 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
        struct stv0299_state* state = fe->demodulator_priv;
 
-       if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
-       else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
+       if (state->errmode != STATUS_UCBLOCKS)
+               return -ENOSYS;
+
+       state->ucblocks += stv0299_readreg(state, 0x1e);
+       state->ucblocks += (stv0299_readreg(state, 0x1d) << 8);
+       *ucblocks = state->ucblocks;
 
        return 0;
 }
index 0727b80bc4d296a83f56317b9266fdbac705f562..c6ff5b82ff80d481e58151cbe47ee336fe76868d 100644 (file)
@@ -116,9 +116,12 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
        int ret;
 
        ret = i2c_transfer (state->i2c, msg, 2);
-       if (ret != 2)
-               printk("DVB: TDA10023: %s: readreg error (ret == %i)\n",
-                                __func__, ret);
+       if (ret != 2) {
+               int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
+               printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error "
+                       "(reg == 0x%02x, ret == %i)\n",
+                       num, __func__, reg, ret);
+       }
        return b1[0];
 }
 
@@ -129,11 +132,12 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
        int ret;
 
        ret = i2c_transfer (state->i2c, &msg, 1);
-       if (ret != 1)
-               printk("DVB: TDA10023(%d): %s, writereg error "
+       if (ret != 1) {
+               int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
+               printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error "
                        "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
-                       state->frontend.dvb->num, __func__, reg, data, ret);
-
+                       num, __func__, reg, data, ret);
+       }
        return (ret != 1) ? -EREMOTEIO : 0;
 }
 
@@ -464,7 +468,7 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
        int i;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 49973846373e843b5fc4d64e6aa97b14922f3a45..a0d6386535673223f557c8d068e233e9a900a239 100644 (file)
@@ -1248,11 +1248,14 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
                                     struct i2c_adapter* i2c)
 {
        struct tda1004x_state *state;
+       int id;
 
        /* allocate memory for the internal state */
        state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
-       if (!state)
+       if (!state) {
+               printk(KERN_ERR "Can't alocate memory for tda10045 state\n");
                return NULL;
+       }
 
        /* setup the state */
        state->config = config;
@@ -1260,7 +1263,15 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
        state->demod_type = TDA1004X_DEMOD_TDA10045;
 
        /* check if the demod is there */
-       if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) {
+       id = tda1004x_read_byte(state, TDA1004X_CHIPID);
+       if (id < 0) {
+               printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n");
+               kfree(state);
+               return NULL;
+       }
+
+       if (id != 0x25) {
+               printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
                kfree(state);
                return NULL;
        }
@@ -1307,11 +1318,14 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
                                     struct i2c_adapter* i2c)
 {
        struct tda1004x_state *state;
+       int id;
 
        /* allocate memory for the internal state */
        state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
-       if (!state)
+       if (!state) {
+               printk(KERN_ERR "Can't alocate memory for tda10046 state\n");
                return NULL;
+       }
 
        /* setup the state */
        state->config = config;
@@ -1319,7 +1333,14 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
        state->demod_type = TDA1004X_DEMOD_TDA10046;
 
        /* check if the demod is there */
-       if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) {
+       id = tda1004x_read_byte(state, TDA1004X_CHIPID);
+       if (id < 0) {
+               printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n");
+               kfree(state);
+               return NULL;
+       }
+       if (id != 0x46) {
+               printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
                kfree(state);
                return NULL;
        }
index d4339b1b3b6872e905532852ef31c4403158950b..07643e01009340cada617b9979a2837ad7747965 100644 (file)
@@ -101,6 +101,7 @@ config DVB_BUDGET
 config DVB_BUDGET_CI
        tristate "Budget cards with onboard CI connector"
        depends on DVB_BUDGET_CORE && I2C
+       depends on INPUT # due to IR
        select DVB_STV0297 if !DVB_FE_CUSTOMISE
        select DVB_STV0299 if !DVB_FE_CUSTOMISE
        select DVB_TDA1004X if !DVB_FE_CUSTOMISE
index 9d81074b31dfe7b2b3ca105234f3d518c2c8d3d8..3a3f5279e927287e68e326c1c7d91721ff704335 100644 (file)
@@ -427,6 +427,7 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
                        if (err) {
                                printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
                                        __func__, type);
+                               av7110->arm_errors++;
                                return -ETIMEDOUT;
                        }
                        msleep(1);
@@ -853,10 +854,8 @@ static osd_raw_window_t bpp2bit[8] = {
 
 static inline int WaitUntilBmpLoaded(struct av7110 *av7110)
 {
-       int ret = wait_event_interruptible_timeout(av7110->bmpq,
+       int ret = wait_event_timeout(av7110->bmpq,
                                av7110->bmp_state != BMP_LOADING, 10*HZ);
-       if (ret == -ERESTARTSYS)
-               return ret;
        if (ret == 0) {
                printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n",
                       ret, av7110->bmp_state);
index a2a6983444fa0d8fe146ceadcaabab3378e6d28f..898e12395e7c26e1f829beff5f773c85cd5671f8 100644 (file)
@@ -77,8 +77,14 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
 
        /* Make sure we support the board model */
        switch (tv.model) {
+       case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
        case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
+       case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+       case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+       case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
+       case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
        case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
+       case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
                break;
        default:
                printk(KERN_WARNING "%s: warning: "
@@ -175,6 +181,18 @@ struct usb_device_id au0828_usb_id_table [] = {
                .driver_info = AU0828_BOARD_HAUPPAUGE_HVR850 },
        { USB_DEVICE(0x0fe9, 0xd620),
                .driver_info = AU0828_BOARD_DVICO_FUSIONHDTV7 },
+       { USB_DEVICE(0x2040, 0x7210),
+               .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+       { USB_DEVICE(0x2040, 0x7217),
+               .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+       { USB_DEVICE(0x2040, 0x721b),
+               .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+       { USB_DEVICE(0x2040, 0x721f),
+               .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+       { USB_DEVICE(0x2040, 0x7280),
+               .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+       { USB_DEVICE(0x0fd9, 0x0008),
+               .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
        { },
 };
 
index 5f942690570c2079626c15c113cdaa02538d3e05..9aefdc5ea79a960983c9c78d5c3cd5e4348e1311 100644 (file)
@@ -10,8 +10,8 @@ config VIDEO_CX18
        select VIDEO_TVEEPROM
        select VIDEO_CX2341X
        select VIDEO_CS5345
-       select DVB_S5H1409
-       select MEDIA_TUNER_MXL5005S
+       select DVB_S5H1409 if !DVB_FE_CUSTOMISE
+       select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
        ---help---
          This is a video4linux driver for Conexant cx23418 based
          PCI combo video recorder devices.
index 9a26751615c618d6dcf1d5d42e36d02ecda29ef5..faca43eb940f7aa17bfbb552c038e0ad2ecd07f3 100644 (file)
@@ -69,6 +69,58 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
                             or_value);
 }
 
+int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask)
+{
+       int retval;
+       u32 saved_reg[8] = {0};
+
+       if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
+               saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL);
+               saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL);
+       }
+
+       if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
+               saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1);
+               saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC);
+       }
+
+       if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
+               saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL);
+               saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL);
+               saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG);
+               saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG);
+       }
+
+       retval = cx18_av_write(cx, addr, value);
+
+       if (no_acfg_mask & CXADEC_NO_ACFG_AFE) {
+               cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]);
+               cx18_av_write4(cx, CXADEC_AFE_CTRL,  saved_reg[1]);
+       }
+
+       if (no_acfg_mask & CXADEC_NO_ACFG_PLL) {
+               cx18_av_write4(cx, CXADEC_PLL_CTRL1,    saved_reg[2]);
+               cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]);
+       }
+
+       if (no_acfg_mask & CXADEC_NO_ACFG_VID) {
+               cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL,    saved_reg[4]);
+               cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL,     saved_reg[5]);
+               cx18_av_write4(cx, CXADEC_SRC_COMB_CFG,      saved_reg[6]);
+               cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]);
+       }
+
+       return retval;
+}
+
+int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask,
+                          u8 or_value, int no_acfg_mask)
+{
+       return cx18_av_write_no_acfg(cx, addr,
+                                    (cx18_av_read(cx, addr) & and_mask) |
+                                    or_value, no_acfg_mask);
+}
+
 /* ----------------------------------------------------------------------- */
 
 static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
@@ -170,13 +222,15 @@ static void input_change(struct cx18 *cx)
 
        /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */
        if (std & V4L2_STD_SECAM)
-               cx18_av_write(cx, 0x402, 0);
+               cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL);
        else {
-               cx18_av_write(cx, 0x402, 0x04);
+               cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL);
                cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11);
        }
-       cx18_av_and_or(cx, 0x401, ~0x60, 0);
-       cx18_av_and_or(cx, 0x401, ~0x60, 0x60);
+       cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0,
+                               CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
+       cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60,
+                               CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
 
        if (std & V4L2_STD_525_60) {
                if (std == V4L2_STD_NTSC_M_JP) {
@@ -228,7 +282,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
 
                if ((vid_input & ~0xff0) ||
                    luma < CX18_AV_SVIDEO_LUMA1 ||
-                   luma > CX18_AV_SVIDEO_LUMA4 ||
+                   luma > CX18_AV_SVIDEO_LUMA8 ||
                    chroma < CX18_AV_SVIDEO_CHROMA4 ||
                    chroma > CX18_AV_SVIDEO_CHROMA8) {
                        CX18_ERR("0x%04x is not a valid video input!\n",
@@ -262,7 +316,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
 
        cx18_av_write(cx, 0x103, reg);
        /* Set INPUT_MODE to Composite (0) or S-Video (1) */
-       cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02);
+       cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02,
+                               CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID);
        /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */
        cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);
        /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */
@@ -318,12 +373,12 @@ static int set_v4lstd(struct cx18 *cx)
           This happens for example with the Yuan MPC622. */
        if (fmt >= 4 && fmt < 8) {
                /* Set format to NTSC-M */
-               cx18_av_and_or(cx, 0x400, ~0xf, 1);
+               cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE);
                /* Turn off LCOMB */
                cx18_av_and_or(cx, 0x47b, ~6, 0);
        }
-       cx18_av_and_or(cx, 0x400, ~0xf, fmt);
-       cx18_av_and_or(cx, 0x403, ~0x3, pal_m);
+       cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE);
+       cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL);
        cx18_av_vbi_setup(cx);
        input_change(cx);
        return 0;
index 786901d72e9a84f96d2a48ae1607a90f15e497bb..c172823ce1d8801a93f384fbd5063057a1b6d2a3 100644 (file)
@@ -37,12 +37,16 @@ enum cx18_av_video_input {
        CX18_AV_COMPOSITE7,
        CX18_AV_COMPOSITE8,
 
-       /* S-Video inputs consist of one luma input (In1-In4) ORed with one
+       /* S-Video inputs consist of one luma input (In1-In8) ORed with one
           chroma input (In5-In8) */
        CX18_AV_SVIDEO_LUMA1 = 0x10,
        CX18_AV_SVIDEO_LUMA2 = 0x20,
        CX18_AV_SVIDEO_LUMA3 = 0x30,
        CX18_AV_SVIDEO_LUMA4 = 0x40,
+       CX18_AV_SVIDEO_LUMA5 = 0x50,
+       CX18_AV_SVIDEO_LUMA6 = 0x60,
+       CX18_AV_SVIDEO_LUMA7 = 0x70,
+       CX18_AV_SVIDEO_LUMA8 = 0x80,
        CX18_AV_SVIDEO_CHROMA4 = 0x400,
        CX18_AV_SVIDEO_CHROMA5 = 0x500,
        CX18_AV_SVIDEO_CHROMA6 = 0x600,
@@ -291,14 +295,24 @@ struct cx18_av_state {
 #define CXADEC_SELECT_AUDIO_STANDARD_FM    0xF9  /* FM radio */
 #define CXADEC_SELECT_AUDIO_STANDARD_AUTO  0xFF  /* Auto detect */
 
+/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/
+#define CXADEC_NO_ACFG_AFE     0x01 /* Preserve 0x100-0x107 */
+#define CXADEC_NO_ACFG_PLL     0x02 /* Preserve 0x108-0x10f */
+#define CXADEC_NO_ACFG_VID     0x04 /* Preserve 0x470-0x47f */
+#define CXADEC_NO_ACFG_ALL     0x07
+
 /* ----------------------------------------------------------------------- */
 /* cx18_av-core.c                                                         */
 int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
 int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
+int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value,
+                               int no_acfg_mask);
 u8 cx18_av_read(struct cx18 *cx, u16 addr);
 u32 cx18_av_read4(struct cx18 *cx, u16 addr);
 int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
 int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
+int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value,
+                               int no_acfg_mask);
 int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
 
 /* ----------------------------------------------------------------------- */
index baccd079243d9682efbe949ee11a6a69bfc419bb..c26e0ef5b07583927c5d5ddd80fee3c304557741 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "cx18-driver.h"
 #include "cx18-cards.h"
+#include "cx18-av-core.h"
 #include "cx18-i2c.h"
 #include <media/cs5345.h>
 
@@ -54,22 +55,22 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
        .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
                  CX18_HW_CS5345 | CX18_HW_DVB,
        .video_inputs = {
-               { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
-               { CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
-               { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
-               { CX18_CARD_INPUT_SVIDEO2,    2, CX23418_SVIDEO2    },
-               { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
+               { CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE7 },
+               { CX18_CARD_INPUT_SVIDEO1,    1, CX18_AV_SVIDEO1    },
+               { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
+               { CX18_CARD_INPUT_SVIDEO2,    2, CX18_AV_SVIDEO2    },
+               { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
        },
        .audio_inputs = {
                { CX18_CARD_INPUT_AUD_TUNER,
-                 CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
+                 CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
                { CX18_CARD_INPUT_LINE_IN1,
-                 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+                 CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
                { CX18_CARD_INPUT_LINE_IN2,
-                 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+                 CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
        },
        .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
-                        CX23418_AUDIO_SERIAL, 0 },
+                        CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
        .ddr = {
                /* ESMT M13S128324A-5B memory */
                .chip_config = 0x003,
@@ -81,6 +82,11 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
        },
        .gpio_init.initial_value = 0x3001,
        .gpio_init.direction = 0x3001,
+       .gpio_i2c_slave_reset = {
+               .active_lo_mask = 0x3001,
+               .msecs_asserted = 10,
+               .msecs_recovery = 40,
+       },
        .i2c = &cx18_i2c_std,
 };
 
@@ -94,22 +100,22 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
        .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
                  CX18_HW_CS5345 | CX18_HW_DVB,
        .video_inputs = {
-               { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
-               { CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
-               { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
-               { CX18_CARD_INPUT_SVIDEO2,    2, CX23418_SVIDEO2    },
-               { CX18_CARD_INPUT_COMPOSITE2, 2, CX23418_COMPOSITE4 },
+               { CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE7 },
+               { CX18_CARD_INPUT_SVIDEO1,    1, CX18_AV_SVIDEO1    },
+               { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
+               { CX18_CARD_INPUT_SVIDEO2,    2, CX18_AV_SVIDEO2    },
+               { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
        },
        .audio_inputs = {
                { CX18_CARD_INPUT_AUD_TUNER,
-                 CX23418_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
+                 CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
                { CX18_CARD_INPUT_LINE_IN1,
-                 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+                 CX18_AV_AUDIO_SERIAL, CS5345_IN_2 },
                { CX18_CARD_INPUT_LINE_IN2,
-                 CX23418_AUDIO_SERIAL, CS5345_IN_2 },
+                 CX18_AV_AUDIO_SERIAL, CS5345_IN_3 },
        },
        .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
-                        CX23418_AUDIO_SERIAL, 0 },
+                        CX18_AV_AUDIO_SERIAL, CS5345_IN_4 },
        .ddr = {
                /* Samsung K4D263238G-VC33 memory */
                .chip_config = 0x003,
@@ -121,6 +127,11 @@ static const struct cx18_card cx18_card_hvr1600_samsung = {
        },
        .gpio_init.initial_value = 0x3001,
        .gpio_init.direction = 0x3001,
+       .gpio_i2c_slave_reset = {
+               .active_lo_mask = 0x3001,
+               .msecs_asserted = 10,
+               .msecs_recovery = 40,
+       },
        .i2c = &cx18_i2c_std,
 };
 
@@ -141,19 +152,19 @@ static const struct cx18_card cx18_card_h900 = {
        .hw_audio_ctrl = CX18_HW_CX23418,
        .hw_all = CX18_HW_TUNER,
        .video_inputs = {
-               { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE2 },
+               { CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
                { CX18_CARD_INPUT_SVIDEO1,    1,
-                       CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
-               { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
+                       CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+               { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
        },
        .audio_inputs = {
                { CX18_CARD_INPUT_AUD_TUNER,
-                 CX23418_AUDIO8, 0 },
+                 CX18_AV_AUDIO8, 0 },
                { CX18_CARD_INPUT_LINE_IN1,
-                 CX23418_AUDIO_SERIAL, 0 },
+                 CX18_AV_AUDIO_SERIAL, 0 },
        },
        .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
-                        CX23418_AUDIO_SERIAL, 0 },
+                        CX18_AV_AUDIO_SERIAL, 0 },
        .tuners = {
                { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
        },
@@ -183,23 +194,26 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
 static const struct cx18_card cx18_card_mpc718 = {
        .type = CX18_CARD_YUAN_MPC718,
        .name = "Yuan MPC718",
-       .comment = "Not yet supported!\n",
-       .v4l2_capabilities = 0,
+       .comment = "Some Composite and S-Video inputs are currently working.\n",
+       .v4l2_capabilities = CX18_CAP_ENCODER,
        .hw_audio_ctrl = CX18_HW_CX23418,
        .hw_all = CX18_HW_TUNER,
        .video_inputs = {
-               { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
-               { CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
-               { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
+               { CX18_CARD_INPUT_VID_TUNER,  0, CX18_AV_COMPOSITE2 },
+               { CX18_CARD_INPUT_SVIDEO1,    1,
+                               CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
+               { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
+               { CX18_CARD_INPUT_SVIDEO2,    2,
+                               CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
+               { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
+               { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 },
        },
        .audio_inputs = {
-               { CX18_CARD_INPUT_AUD_TUNER,
-                 CX23418_AUDIO8, 0 },
-               { CX18_CARD_INPUT_LINE_IN1,
-                 CX23418_AUDIO_SERIAL, 0 },
+               { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5,       0 },
+               { CX18_CARD_INPUT_LINE_IN1,  CX18_AV_AUDIO_SERIAL, 0 },
+               { CX18_CARD_INPUT_LINE_IN2,  CX18_AV_AUDIO_SERIAL, 0 },
        },
-       .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
-                        CX23418_AUDIO_SERIAL, 0 },
+       .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 },
        .tuners = {
                /* XC3028 tuner */
                { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
index bccb67f0db16415a1efd6ffef20909b9d42cd46d..dc2dd945d4c3be4aefd2b324a6d4f368b8825c8c 100644 (file)
 #define        CX18_CARD_INPUT_COMPOSITE2      5
 #define        CX18_CARD_INPUT_COMPOSITE3      6
 
-enum cx34180_video_input {
-       /* Composite video inputs In1-In8 */
-       CX23418_COMPOSITE1 = 1,
-       CX23418_COMPOSITE2,
-       CX23418_COMPOSITE3,
-       CX23418_COMPOSITE4,
-       CX23418_COMPOSITE5,
-       CX23418_COMPOSITE6,
-       CX23418_COMPOSITE7,
-       CX23418_COMPOSITE8,
-
-       /* S-Video inputs consist of one luma input (In1-In4) ORed with one
-          chroma input (In5-In8) */
-       CX23418_SVIDEO_LUMA1 = 0x10,
-       CX23418_SVIDEO_LUMA2 = 0x20,
-       CX23418_SVIDEO_LUMA3 = 0x30,
-       CX23418_SVIDEO_LUMA4 = 0x40,
-       CX23418_SVIDEO_CHROMA4 = 0x400,
-       CX23418_SVIDEO_CHROMA5 = 0x500,
-       CX23418_SVIDEO_CHROMA6 = 0x600,
-       CX23418_SVIDEO_CHROMA7 = 0x700,
-       CX23418_SVIDEO_CHROMA8 = 0x800,
-
-       /* S-Video aliases for common luma/chroma combinations */
-       CX23418_SVIDEO1 = 0x510,
-       CX23418_SVIDEO2 = 0x620,
-       CX23418_SVIDEO3 = 0x730,
-       CX23418_SVIDEO4 = 0x840,
-};
-
 /* audio inputs */
 #define        CX18_CARD_INPUT_AUD_TUNER       1
 #define        CX18_CARD_INPUT_LINE_IN1        2
@@ -75,16 +45,6 @@ enum cx34180_video_input {
 #define CX18_CARD_MAX_AUDIO_INPUTS 3
 #define CX18_CARD_MAX_TUNERS      2
 
-enum cx23418_audio_input {
-       /* Audio inputs: serial or In4-In8 */
-       CX23418_AUDIO_SERIAL,
-       CX23418_AUDIO4 = 4,
-       CX23418_AUDIO5,
-       CX23418_AUDIO6,
-       CX23418_AUDIO7,
-       CX23418_AUDIO8,
-};
-
 /* V4L2 capability aliases */
 #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
                          V4L2_CAP_AUDIO | V4L2_CAP_READWRITE)
@@ -118,6 +78,13 @@ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
        u32 initial_value;
 };
 
+struct cx18_gpio_i2c_slave_reset {
+       u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */
+       u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */
+       int msecs_asserted; /* time period reset must remain asserted */
+       int msecs_recovery; /* time after deassert for chips to be ready */
+};
+
 struct cx18_card_tuner {
        v4l2_std_id std;        /* standard for which the tuner is suitable */
        int         tuner;      /* tuner ID (from tuner.h) */
@@ -154,7 +121,8 @@ struct cx18_card {
 
        /* GPIO card-specific settings */
        u8 xceive_pin;          /* XCeive tuner GPIO reset pin */
-       struct cx18_gpio_init           gpio_init;
+       struct cx18_gpio_init            gpio_init;
+       struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
 
        struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
        struct cx18_card_tuner_i2c *i2c;
index c9744173f9692d635455d844beb7a2f9aef2020a..cae38985b1313a306f4dedbe8c656f6208b737ca 100644 (file)
@@ -69,11 +69,21 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
        struct dvb_demux *demux = feed->demux;
        struct cx18_stream *stream = (struct cx18_stream *) demux->priv;
        struct cx18 *cx = stream->cx;
-       int ret = -EINVAL;
+       int ret;
        u32 v;
 
        CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n",
                        feed->pid, feed->index);
+
+       mutex_lock(&cx->serialize_lock);
+       ret = cx18_init_on_first_open(cx);
+       mutex_unlock(&cx->serialize_lock);
+       if (ret) {
+               CX18_ERR("Failed to initialize firmware starting DVB feed\n");
+               return ret;
+       }
+       ret = -EINVAL;
+
        switch (cx->card->type) {
        case CX18_CARD_HVR_1600_ESMT:
        case CX18_CARD_HVR_1600_SAMSUNG:
@@ -101,6 +111,11 @@ static int cx18_dvb_start_feed(struct dvb_demux_feed *feed)
                if (stream->dvb.feeding++ == 0) {
                        CX18_DEBUG_INFO("Starting Transport DMA\n");
                        ret = cx18_start_v4l2_encode_stream(stream);
+                       if (ret < 0) {
+                               CX18_DEBUG_INFO(
+                                       "Failed to start Transport DMA\n");
+                               stream->dvb.feeding--;
+                       }
                } else
                        ret = 0;
                mutex_unlock(&stream->dvb.feedlock);
index ceb63653c926f71e6b8dae4ce39e00e4e03314ea..b302833f6f9dd8d8250f4e716ed5fa9084d515d6 100644 (file)
@@ -53,10 +53,34 @@ static void gpio_write(struct cx18 *cx)
        write_reg(((dir & 0xffff) << 16) | (val & 0xffff),
                        CX18_REG_GPIO_OUT1);
        write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2);
-       write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
+       write_reg_sync((dir & 0xffff0000) | ((val & 0xffff0000) >> 16),
                        CX18_REG_GPIO_OUT2);
 }
 
+void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
+{
+       const struct cx18_gpio_i2c_slave_reset *p;
+
+       p = &cx->card->gpio_i2c_slave_reset;
+
+       if ((p->active_lo_mask | p->active_hi_mask) == 0)
+               return;
+
+       /* Assuming that the masks are a subset of the bits in gpio_dir */
+
+       /* Assert */
+       cx->gpio_val =
+               (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
+       gpio_write(cx);
+       schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+
+       /* Deassert */
+       cx->gpio_val =
+               (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
+       gpio_write(cx);
+       schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+}
+
 void cx18_gpio_init(struct cx18 *cx)
 {
        cx->gpio_dir = cx->card->gpio_init.direction;
index 41bac8856b50e050871d85ee655082e2408ee886..525c328f748a3d0f677863bdc4fdde9ae4bdc0fb 100644 (file)
@@ -21,4 +21,5 @@
  */
 
 void cx18_gpio_init(struct cx18 *cx);
+void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
 int cx18_reset_tuner_gpio(void *dev, int cmd, int value);
index 1d6c51a753137652028763005bc3c318404e4011..680bc4e35b79a3c67d38e072af2471fb30e35e2d 100644 (file)
@@ -405,6 +405,8 @@ int init_cx18_i2c(struct cx18 *cx)
        cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
        cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
 
+       cx18_reset_i2c_slaves_gpio(cx);
+
        return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
                i2c_bit_add_bus(&cx->i2c_adap[1]);
 }
index 607efdcd22f8d0eeae68ba7a57b01c2c171293cd..1da6f134888d6d524ee375d345c75574981706bc 100644 (file)
@@ -433,7 +433,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
                int chroma = vid_input & 0xf00;
 
                if ((vid_input & ~0xff0) ||
-                   luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 ||
+                   luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA8 ||
                    chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) {
                        v4l_err(client, "0x%04x is not a valid video input!\n",
                                vid_input);
index e976fc6bef7ccc7c6ec747fc5594f7a720aff505..80c8883e54b5c6ef853d5e8560da3424044376e3 100644 (file)
@@ -332,6 +332,12 @@ static int snd_cx88_pcm_open(struct snd_pcm_substream *substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err;
 
+       if (!chip) {
+               printk(KERN_ERR "BUG: cx88 can't find device struct."
+                               " Can't proceed with open\n");
+               return -ENODEV;
+       }
+
        err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
        if (err < 0)
                goto _error;
index 92b2a6db4fdc15edea12a61ccbdcfa522da7a534..3c006103c1eb369c4817fd74522ef7ffebc91e61 100644 (file)
@@ -268,6 +268,12 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
 
        dprintk("opening device and trying to acquire exclusive lock\n");
 
+       if (!dev) {
+               printk(KERN_ERR "BUG: em28xx can't find device struct."
+                               " Can't proceed with open\n");
+               return -ENODEV;
+       }
+
        /* Sets volume, mute, etc */
 
        dev->mute = 0;
@@ -415,6 +421,12 @@ static int em28xx_audio_init(struct em28xx *dev)
        static int          devnr;
        int                 ret, err;
 
+       if (dev->has_audio_class) {
+               /* This device does not support the extension (in this case
+                  the device is expecting the snd-usb-audio module */
+               return 0;
+       }
+
        printk(KERN_INFO "em28xx-audio.c: probing for em28x1 "
                         "non standard usbaudio\n");
        printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
@@ -458,6 +470,12 @@ static int em28xx_audio_fini(struct em28xx *dev)
        if (dev == NULL)
                return 0;
 
+       if (dev->has_audio_class) {
+               /* This device does not support the extension (in this case
+                  the device is expecting the snd-usb-audio module */
+               return 0;
+       }
+
        if (dev->adev) {
                snd_card_free(dev->adev->sndcard);
                kfree(dev->adev);
index 3e4f3c7e92e78ee62231feaebde1628d0cae27ff..8cbda43727c3de59ba73a9427706b0961f7d80b1 100644 (file)
@@ -157,6 +157,7 @@ struct em28xx_board em28xx_boards[] = {
                .tda9887_conf = TDA9887_PRESENT,
                .tuner_type   = TUNER_XC2028,
                .mts_firmware = 1,
+               .has_dvb        = 1,
                .decoder      = EM28XX_TVP5150,
                .input          = { {
                        .type     = EM28XX_VMUX_TELEVISION,
@@ -524,6 +525,9 @@ void em28xx_pre_card_setup(struct em28xx *dev)
        rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
        if (rc > 0) {
                switch (rc) {
+               case CHIP_ID_EM2860:
+                       em28xx_info("chip ID is em2860\n");
+                       break;
                case CHIP_ID_EM2883:
                        em28xx_info("chip ID is em2882/em2883\n");
                        dev->wait_after_write = 0;
index 8cf4983f0039602ce617fbe929a1edad032baa26..0b2333ee07f8ea6c3bbf7200cd70f47b89c3a61f 100644 (file)
@@ -382,6 +382,11 @@ static int dvb_init(struct em28xx *dev)
        int result = 0;
        struct em28xx_dvb *dvb;
 
+       if (!dev->has_dvb) {
+               /* This device does not support the extension */
+               return 0;
+       }
+
        dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
 
        if (dvb == NULL) {
@@ -444,6 +449,11 @@ out_free:
 
 static int dvb_fini(struct em28xx *dev)
 {
+       if (!dev->has_dvb) {
+               /* This device does not support the extension */
+               return 0;
+       }
+
        if (dev->dvb) {
                unregister_dvb(dev->dvb);
                dev->dvb = NULL;
index 9058bed07953d839fc69fd2a44042061cb0c5b3a..fac1ab23f6216dd74d4fcbc0a65fd26868d0fcd6 100644 (file)
@@ -84,5 +84,6 @@
 
 /* FIXME: Need to be populated with the other chip ID's */
 enum em28xx_chip_id {
+       CHIP_ID_EM2860 = 34,
        CHIP_ID_EM2883 = 36,
 };
index fb163ecd921684a4014b69e4de056512fa22904e..285bc62bbe4670f203cde0e08c2c14e1e00743bc 100644 (file)
@@ -1848,32 +1848,28 @@ static DEFINE_MUTEX(em28xx_extension_devlist_lock);
 
 int em28xx_register_extension(struct em28xx_ops *ops)
 {
-       struct em28xx *h, *dev = NULL;
-
-       list_for_each_entry(h, &em28xx_devlist, devlist)
-               dev = h;
+       struct em28xx *dev = NULL;
 
        mutex_lock(&em28xx_extension_devlist_lock);
        list_add_tail(&ops->next, &em28xx_extension_devlist);
-       if (dev)
-               ops->init(dev);
-
+       list_for_each_entry(dev, &em28xx_devlist, devlist) {
+               if (dev)
+                       ops->init(dev);
+       }
        printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name);
        mutex_unlock(&em28xx_extension_devlist_lock);
-
        return 0;
 }
 EXPORT_SYMBOL(em28xx_register_extension);
 
 void em28xx_unregister_extension(struct em28xx_ops *ops)
 {
-       struct em28xx *h, *dev = NULL;
-
-       list_for_each_entry(h, &em28xx_devlist, devlist)
-               dev = h;
+       struct em28xx *dev = NULL;
 
-       if (dev)
-               ops->fini(dev);
+       list_for_each_entry(dev, &em28xx_devlist, devlist) {
+               if (dev)
+                       ops->fini(dev);
+       }
 
        mutex_lock(&em28xx_extension_devlist_lock);
        printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name);
index 7cc8e9b19fb794fb57139515692de6d460afbd96..5ec5bb9a94d2e848095d8e737eb2936e6803b14d 100644 (file)
@@ -1019,12 +1019,12 @@ static int pxa_camera_probe(struct platform_device *pdev)
        struct pxa_camera_dev *pcdev;
        struct resource *res;
        void __iomem *base;
-       unsigned int irq;
+       int irq;
        int err = 0;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       if (!res || !irq) {
+       if (!res || irq < 0) {
                err = -ENODEV;
                goto exit;
        }
index ba3082422a01915dce20bce15832c495e9555d89..f118de6e36722950b43b5cb21d64520a32386f1f 100644 (file)
@@ -613,9 +613,15 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_card_saa7134_pcm_t *pcm;
        snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
-       struct saa7134_dev *dev = saa7134->dev;
+       struct saa7134_dev *dev;
        int amux, err;
 
+       if (!saa7134) {
+               printk(KERN_ERR "BUG: saa7134 can't find device struct."
+                               " Can't proceed with open\n");
+               return -ENODEV;
+       }
+       dev = saa7134->dev;
        mutex_lock(&dev->dmasound.lock);
 
        dev->dmasound.read_count  = 0;
index b111903aa322cd287a4d5ca0041396242b7e6c43..2618cfa592e7067287407a403f9501213575b8d0 100644 (file)
@@ -4114,11 +4114,7 @@ struct saa7134_board saa7134_boards[] = {
                .radio_type     = UNSET,
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
-                /*
-                   TODO:
                 .mpeg           = SAA7134_MPEG_DVB,
-                */
-
                 .inputs         = {{
                         .name = name_tv,
                         .vmux = 1,
@@ -4157,7 +4153,7 @@ struct saa7134_board saa7134_boards[] = {
                } },
                .radio = {
                        .name = name_radio,
-                       .amux = LINE1,
+                       .amux = TV,
                },
        },
        [SAA7134_BOARD_AVERMEDIA_M115] = {
@@ -4167,6 +4163,7 @@ struct saa7134_board saa7134_boards[] = {
                .radio_type     = UNSET,
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
+               .mpeg           = SAA7134_MPEG_DVB,
                .inputs         = {{
                        .name = name_tv,
                        .vmux = 1,
@@ -5351,22 +5348,21 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
 {
        switch (command) {
        case XC2028_TUNER_RESET:
-               saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
-               saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
-               mdelay(250);
-               saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0);
-               saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0);
-               mdelay(250);
-               saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x06e20000, 0x06e20000);
-               saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x06a20000, 0x06a20000);
-               mdelay(250);
-               saa_andorl(SAA7133_ANALOG_IO_SELECT >> 2, 0x02, 0x02);
-               saa_andorl(SAA7134_ANALOG_IN_CTRL1 >> 2, 0x81, 0x81);
-               saa_andorl(SAA7134_AUDIO_CLOCK0 >> 2, 0x03187de7, 0x03187de7);
-               saa_andorl(SAA7134_AUDIO_PLL_CTRL >> 2, 0x03, 0x03);
-               saa_andorl(SAA7134_AUDIO_CLOCKS_PER_FIELD0 >> 2,
-                          0x0001e000, 0x0001e000);
-               return 0;
+               saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00000000);
+               saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000);
+               switch (dev->board) {
+               case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+                       saa7134_set_gpio(dev, 23, 0);
+                       msleep(10);
+                       saa7134_set_gpio(dev, 23, 1);
+               break;
+               case SAA7134_BOARD_AVERMEDIA_A16D:
+                       saa7134_set_gpio(dev, 21, 0);
+                       msleep(10);
+                       saa7134_set_gpio(dev, 21, 1);
+               break;
+               }
+       return 0;
        }
        return -EINVAL;
 }
@@ -5553,9 +5549,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x08000000, 0x00000000);
                break;
        case SAA7134_BOARD_AVERMEDIA_CARDBUS:
-       case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
        case SAA7134_BOARD_AVERMEDIA_M115:
-       case SAA7134_BOARD_AVERMEDIA_A16D:
                /* power-down tuner chip */
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0xffffffff, 0);
                saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0);
@@ -5565,6 +5559,18 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
                msleep(10);
                break;
+       case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+               saa7134_set_gpio(dev, 23, 0);
+               msleep(10);
+               saa7134_set_gpio(dev, 23, 1);
+               break;
+       case SAA7134_BOARD_AVERMEDIA_A16D:
+               saa7134_set_gpio(dev, 21, 0);
+               msleep(10);
+               saa7134_set_gpio(dev, 21, 1);
+               msleep(1);
+               dev->has_remote = SAA7134_REMOTE_GPIO;
+               break;
        case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
                /* power-down tuner chip */
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x000A8004, 0x000A8004);
@@ -5615,7 +5621,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x80040100, 0x80040100);
                saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
                printk("%s: %s: hybrid analog/dvb card\n"
-                      "%s: Sorry, only the analog inputs are supported for now.\n",
+                      "%s: Sorry, only analog s-video and composite input "
+                      "are supported for now.\n",
                        dev->name, card(dev).name, dev->name);
                break;
        }
@@ -5675,6 +5682,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
 
                switch (dev->board) {
                case SAA7134_BOARD_AVERMEDIA_A16D:
+               case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
                        ctl.demod = XC3028_FE_ZARLINK456;
                        break;
                default:
index 469f93aac0083a1e049cb55bc27ed985ca31596d..341b101b0357d457003438ecaa210d16640dc580 100644 (file)
@@ -153,12 +153,12 @@ static int mt352_aver777_init(struct dvb_frontend* fe)
        return 0;
 }
 
-static int mt352_aver_a16d_init(struct dvb_frontend *fe)
+static int mt352_avermedia_xc3028_init(struct dvb_frontend *fe)
 {
-       static u8 clock_config []  = { CLOCK_CTL,  0x38, 0x2d };
-       static u8 reset []         = { RESET,      0x80 };
-       static u8 adc_ctl_1_cfg [] = { ADC_CTL_1,  0x40 };
-       static u8 agc_cfg []       = { AGC_TARGET, 0x28, 0xa0 };
+       static u8 clock_config []  = { CLOCK_CTL, 0x38, 0x2d };
+       static u8 reset []         = { RESET, 0x80 };
+       static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
+       static u8 agc_cfg []       = { AGC_TARGET, 0xe };
        static u8 capt_range_cfg[] = { CAPT_RANGE, 0x33 };
 
        mt352_write(fe, clock_config,   sizeof(clock_config));
@@ -167,12 +167,9 @@ static int mt352_aver_a16d_init(struct dvb_frontend *fe)
        mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
        mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
        mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
-
        return 0;
 }
 
-
-
 static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
                                           struct dvb_frontend_parameters* params)
 {
@@ -215,14 +212,10 @@ static struct mt352_config avermedia_777 = {
        .demod_init    = mt352_aver777_init,
 };
 
-static struct mt352_config avermedia_16d = {
-       .demod_address = 0xf,
-       .demod_init    = mt352_aver_a16d_init,
-};
-
-static struct mt352_config avermedia_e506r_mt352_dev = {
+static struct mt352_config avermedia_xc3028_mt352_dev = {
        .demod_address   = (0x1e >> 1),
        .no_tuner        = 1,
+       .demod_init      = mt352_avermedia_xc3028_init,
 };
 
 /* ==================================================================
@@ -975,9 +968,10 @@ static int dvb_init(struct saa7134_dev *dev)
                }
                break;
        case SAA7134_BOARD_AVERMEDIA_A16D:
-               dprintk("avertv A16D dvb setup\n");
-               dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_16d,
-                                              &dev->i2c_adap);
+               dprintk("AverMedia A16D dvb setup\n");
+               dev->dvb.frontend = dvb_attach(mt352_attach,
+                                               &avermedia_xc3028_mt352_dev,
+                                               &dev->i2c_adap);
                attach_xc3028 = 1;
                break;
        case SAA7134_BOARD_MD7134:
@@ -1091,7 +1085,8 @@ static int dvb_init(struct saa7134_dev *dev)
                                        ads_tech_duo_config.tuner_address);
                                goto dettach_frontend;
                        }
-               }
+               } else
+                       wprintk("failed to attach tda10046\n");
                break;
        case SAA7134_BOARD_TEVION_DVBT_220RF:
                if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
@@ -1260,11 +1255,14 @@ static int dvb_init(struct saa7134_dev *dev)
                        goto dettach_frontend;
                break;
        case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+               dprintk("AverMedia E506R dvb setup\n");
+               saa7134_set_gpio(dev, 25, 0);
+               msleep(10);
+               saa7134_set_gpio(dev, 25, 1);
                dev->dvb.frontend = dvb_attach(mt352_attach,
-                                              &avermedia_e506r_mt352_dev,
-                                              &dev->i2c_adap);
+                                               &avermedia_xc3028_mt352_dev,
+                                               &dev->i2c_adap);
                attach_xc3028 = 1;
-               break;
        case SAA7134_BOARD_MD7134_BRIDGE_2:
                dev->dvb.frontend = dvb_attach(tda10086_attach,
                                                &sd1878_4m, &dev->i2c_adap);
@@ -1338,7 +1336,8 @@ static int dvb_init(struct saa7134_dev *dev)
        return ret;
 
 dettach_frontend:
-       dvb_frontend_detach(dev->dvb.frontend);
+       if (dev->dvb.frontend)
+               dvb_frontend_detach(dev->dvb.frontend);
        dev->dvb.frontend = NULL;
 
        return -1;
index 81431ee418426894f5c285fdfef6f4609f2294a5..3ae71a3408223800ce442efc413c8589bb18ae4a 100644 (file)
@@ -110,9 +110,10 @@ static int ts_release(struct inode *inode, struct file *file)
 {
        struct saa7134_dev *dev = file->private_data;
 
+       mutex_lock(&dev->empress_tsq.vb_lock);
+
        videobuf_stop(&dev->empress_tsq);
        videobuf_mmap_free(&dev->empress_tsq);
-       dev->empress_users--;
 
        /* stop the encoder */
        ts_reset_encoder(dev);
@@ -121,6 +122,10 @@ static int ts_release(struct inode *inode, struct file *file)
        saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
                saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
 
+       dev->empress_users--;
+
+       mutex_unlock(&dev->empress_tsq.vb_lock);
+
        return 0;
 }
 
@@ -218,8 +223,7 @@ static int empress_enum_fmt_cap(struct file *file, void  *priv,
 static int empress_g_fmt_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f);
 
@@ -232,8 +236,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv,
 static int empress_s_fmt_cap(struct file *file, void *priv,
                                struct v4l2_format *f)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f);
 
@@ -247,8 +250,7 @@ static int empress_s_fmt_cap(struct file *file, void *priv,
 static int empress_reqbufs(struct file *file, void *priv,
                                        struct v4l2_requestbuffers *p)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        return videobuf_reqbufs(&dev->empress_tsq, p);
 }
@@ -256,24 +258,21 @@ static int empress_reqbufs(struct file *file, void *priv,
 static int empress_querybuf(struct file *file, void *priv,
                                        struct v4l2_buffer *b)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        return videobuf_querybuf(&dev->empress_tsq, b);
 }
 
 static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        return videobuf_qbuf(&dev->empress_tsq, b);
 }
 
 static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        return videobuf_dqbuf(&dev->empress_tsq, b,
                                file->f_flags & O_NONBLOCK);
@@ -282,8 +281,7 @@ static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 static int empress_streamon(struct file *file, void *priv,
                                        enum v4l2_buf_type type)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        return videobuf_streamon(&dev->empress_tsq);
 }
@@ -291,8 +289,7 @@ static int empress_streamon(struct file *file, void *priv,
 static int empress_streamoff(struct file *file, void *priv,
                                        enum v4l2_buf_type type)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        return videobuf_streamoff(&dev->empress_tsq);
 }
@@ -300,8 +297,7 @@ static int empress_streamoff(struct file *file, void *priv,
 static int empress_s_ext_ctrls(struct file *file, void *priv,
                               struct v4l2_ext_controls *ctrls)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        /* count == 0 is abused in saa6752hs.c, so that special
                case is handled here explicitly. */
@@ -320,8 +316,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
 static int empress_g_ext_ctrls(struct file *file, void *priv,
                               struct v4l2_ext_controls *ctrls)
 {
-       struct saa7134_fh *fh = priv;
-       struct saa7134_dev *dev = fh->dev;
+       struct saa7134_dev *dev = file->private_data;
 
        if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
                return -EINVAL;
index 919632b10aae0ed20510fc68c2d89e944117b00c..76e6501d238d0d31ddaf68305484de9faa9c6368 100644 (file)
@@ -323,6 +323,15 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
                saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
                break;
+       case SAA7134_BOARD_AVERMEDIA_A16D:
+               ir_codes     = ir_codes_avermedia_a16d;
+               mask_keycode = 0x02F200;
+               mask_keydown = 0x000400;
+               polling      = 50; /* ms */
+               /* Without this we won't receive key up events */
+               saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
+               saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
+               break;
        case SAA7134_BOARD_KWORLD_TERMINATOR:
                ir_codes     = ir_codes_pixelview;
                mask_keycode = 0x00001f;
index a1b92446c8b4ac78052a4849e23a9f428ccba2c1..d015bfe00950c5fcf1a943154cb6413ce8db60f5 100644 (file)
@@ -763,15 +763,6 @@ static struct device_driver ic_drv = {
        .owner  = THIS_MODULE,
 };
 
-/*
- * Image capture host - this is a host device, not a bus device, so,
- * no bus reference, no probing.
- */
-static struct class soc_camera_host_class = {
-       .owner          = THIS_MODULE,
-       .name           = "camera_host",
-};
-
 static void dummy_release(struct device *dev)
 {
 }
@@ -801,7 +792,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
 
        /* Number might be equal to the platform device ID */
        sprintf(ici->dev.bus_id, "camera_host%d", ici->nr);
-       ici->dev.class = &soc_camera_host_class;
 
        mutex_lock(&list_lock);
        list_for_each_entry(ix, &hosts, list) {
@@ -1003,14 +993,9 @@ static int __init soc_camera_init(void)
        ret = driver_register(&ic_drv);
        if (ret)
                goto edrvr;
-       ret = class_register(&soc_camera_host_class);
-       if (ret)
-               goto eclr;
 
        return 0;
 
-eclr:
-       driver_unregister(&ic_drv);
 edrvr:
        bus_unregister(&soc_camera_bus_type);
        return ret;
@@ -1018,7 +1003,6 @@ edrvr:
 
 static void __exit soc_camera_exit(void)
 {
-       class_unregister(&soc_camera_host_class);
        driver_unregister(&ic_drv);
        bus_unregister(&soc_camera_bus_type);
 }
index 31e8af0ba2785e105e60587b8153602b948f55eb..67a661cf5219bc65e225f304d5872579c034313b 100644 (file)
 #define VIDEO_NUM_DEVICES      256
 #define VIDEO_NAME              "video4linux"
 
+struct std_descr {
+       v4l2_std_id std;
+       const char *descr;
+};
+
+static const struct std_descr standards[] = {
+       { V4L2_STD_NTSC,        "NTSC"      },
+       { V4L2_STD_NTSC_M,      "NTSC-M"    },
+       { V4L2_STD_NTSC_M_JP,   "NTSC-M-JP" },
+       { V4L2_STD_NTSC_M_KR,   "NTSC-M-KR" },
+       { V4L2_STD_NTSC_443,    "NTSC-443"  },
+       { V4L2_STD_PAL,         "PAL"       },
+       { V4L2_STD_PAL_BG,      "PAL-BG"    },
+       { V4L2_STD_PAL_B,       "PAL-B"     },
+       { V4L2_STD_PAL_B1,      "PAL-B1"    },
+       { V4L2_STD_PAL_G,       "PAL-G"     },
+       { V4L2_STD_PAL_H,       "PAL-H"     },
+       { V4L2_STD_PAL_I,       "PAL-I"     },
+       { V4L2_STD_PAL_DK,      "PAL-DK"    },
+       { V4L2_STD_PAL_D,       "PAL-D"     },
+       { V4L2_STD_PAL_D1,      "PAL-D1"    },
+       { V4L2_STD_PAL_K,       "PAL-K"     },
+       { V4L2_STD_PAL_M,       "PAL-M"     },
+       { V4L2_STD_PAL_N,       "PAL-N"     },
+       { V4L2_STD_PAL_Nc,      "PAL-Nc"    },
+       { V4L2_STD_PAL_60,      "PAL-60"    },
+       { V4L2_STD_SECAM,       "SECAM"     },
+       { V4L2_STD_SECAM_B,     "SECAM-B"   },
+       { V4L2_STD_SECAM_G,     "SECAM-G"   },
+       { V4L2_STD_SECAM_H,     "SECAM-H"   },
+       { V4L2_STD_SECAM_DK,    "SECAM-DK"  },
+       { V4L2_STD_SECAM_D,     "SECAM-D"   },
+       { V4L2_STD_SECAM_K,     "SECAM-K"   },
+       { V4L2_STD_SECAM_K1,    "SECAM-K1"  },
+       { V4L2_STD_SECAM_L,     "SECAM-L"   },
+       { V4L2_STD_SECAM_LC,    "SECAM-Lc"  },
+       { 0,                    "Unknown"   }
+};
+
 /* video4linux standard ID conversion to standard name
  */
-char *v4l2_norm_to_name(v4l2_std_id id)
+const char *v4l2_norm_to_name(v4l2_std_id id)
 {
-       char *name;
        u32 myid = id;
+       int i;
 
        /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle
           64 bit comparations. So, on that architecture, with some gcc
@@ -64,110 +103,17 @@ char *v4l2_norm_to_name(v4l2_std_id id)
         */
        BUG_ON(myid != id);
 
-       switch (myid) {
-       case V4L2_STD_PAL:
-               name = "PAL";
-               break;
-       case V4L2_STD_PAL_BG:
-               name = "PAL-BG";
-               break;
-       case V4L2_STD_PAL_DK:
-               name = "PAL-DK";
-               break;
-       case V4L2_STD_PAL_B:
-               name = "PAL-B";
-               break;
-       case V4L2_STD_PAL_B1:
-               name = "PAL-B1";
-               break;
-       case V4L2_STD_PAL_G:
-               name = "PAL-G";
-               break;
-       case V4L2_STD_PAL_H:
-               name = "PAL-H";
-               break;
-       case V4L2_STD_PAL_I:
-               name = "PAL-I";
-               break;
-       case V4L2_STD_PAL_D:
-               name = "PAL-D";
-               break;
-       case V4L2_STD_PAL_D1:
-               name = "PAL-D1";
-               break;
-       case V4L2_STD_PAL_K:
-               name = "PAL-K";
-               break;
-       case V4L2_STD_PAL_M:
-               name = "PAL-M";
-               break;
-       case V4L2_STD_PAL_N:
-               name = "PAL-N";
-               break;
-       case V4L2_STD_PAL_Nc:
-               name = "PAL-Nc";
-               break;
-       case V4L2_STD_PAL_60:
-               name = "PAL-60";
-               break;
-       case V4L2_STD_NTSC:
-               name = "NTSC";
-               break;
-       case V4L2_STD_NTSC_M:
-               name = "NTSC-M";
-               break;
-       case V4L2_STD_NTSC_M_JP:
-               name = "NTSC-M-JP";
-               break;
-       case V4L2_STD_NTSC_443:
-               name = "NTSC-443";
-               break;
-       case V4L2_STD_NTSC_M_KR:
-               name = "NTSC-M-KR";
-               break;
-       case V4L2_STD_SECAM:
-               name = "SECAM";
-               break;
-       case V4L2_STD_SECAM_DK:
-               name = "SECAM-DK";
-               break;
-       case V4L2_STD_SECAM_B:
-               name = "SECAM-B";
-               break;
-       case V4L2_STD_SECAM_D:
-               name = "SECAM-D";
-               break;
-       case V4L2_STD_SECAM_G:
-               name = "SECAM-G";
-               break;
-       case V4L2_STD_SECAM_H:
-               name = "SECAM-H";
-               break;
-       case V4L2_STD_SECAM_K:
-               name = "SECAM-K";
-               break;
-       case V4L2_STD_SECAM_K1:
-               name = "SECAM-K1";
-               break;
-       case V4L2_STD_SECAM_L:
-               name = "SECAM-L";
-               break;
-       case V4L2_STD_SECAM_LC:
-               name = "SECAM-LC";
-               break;
-       default:
-               name = "Unknown";
-               break;
-       }
-
-       return name;
+       for (i = 0; standards[i].std; i++)
+               if (myid == standards[i].std)
+                       break;
+       return standards[i].descr;
 }
 EXPORT_SYMBOL(v4l2_norm_to_name);
 
 /* Fill in the fields of a v4l2_standard structure according to the
    'id' and 'transmission' parameters.  Returns negative on error.  */
 int v4l2_video_std_construct(struct v4l2_standard *vs,
-                            int id, char *name)
+                            int id, const char *name)
 {
        u32 index = vs->index;
 
@@ -1218,95 +1164,40 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
        case VIDIOC_ENUMSTD:
        {
                struct v4l2_standard *p = arg;
-               v4l2_std_id id = vfd->tvnorms,curr_id=0;
-               unsigned int index = p->index,i;
-
-               if (index<0) {
-                       ret=-EINVAL;
-                       break;
-               }
-
-               /* Return norm array on a canonical way */
-               for (i=0;i<= index && id; i++) {
-                       if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
-                               curr_id = V4L2_STD_PAL;
-                       } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
-                               curr_id = V4L2_STD_PAL_BG;
-                       } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
-                               curr_id = V4L2_STD_PAL_DK;
-                       } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
-                               curr_id = V4L2_STD_PAL_B;
-                       } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
-                               curr_id = V4L2_STD_PAL_B1;
-                       } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
-                               curr_id = V4L2_STD_PAL_G;
-                       } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
-                               curr_id = V4L2_STD_PAL_H;
-                       } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
-                               curr_id = V4L2_STD_PAL_I;
-                       } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
-                               curr_id = V4L2_STD_PAL_D;
-                       } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
-                               curr_id = V4L2_STD_PAL_D1;
-                       } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
-                               curr_id = V4L2_STD_PAL_K;
-                       } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
-                               curr_id = V4L2_STD_PAL_M;
-                       } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
-                               curr_id = V4L2_STD_PAL_N;
-                       } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
-                               curr_id = V4L2_STD_PAL_Nc;
-                       } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
-                               curr_id = V4L2_STD_PAL_60;
-                       } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
-                               curr_id = V4L2_STD_NTSC;
-                       } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
-                               curr_id = V4L2_STD_NTSC_M;
-                       } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
-                               curr_id = V4L2_STD_NTSC_M_JP;
-                       } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
-                               curr_id = V4L2_STD_NTSC_443;
-                       } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
-                               curr_id = V4L2_STD_NTSC_M_KR;
-                       } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
-                               curr_id = V4L2_STD_SECAM;
-                       } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
-                               curr_id = V4L2_STD_SECAM_DK;
-                       } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
-                               curr_id = V4L2_STD_SECAM_B;
-                       } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
-                               curr_id = V4L2_STD_SECAM_D;
-                       } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
-                               curr_id = V4L2_STD_SECAM_G;
-                       } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
-                               curr_id = V4L2_STD_SECAM_H;
-                       } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
-                               curr_id = V4L2_STD_SECAM_K;
-                       } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
-                               curr_id = V4L2_STD_SECAM_K1;
-                       } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
-                               curr_id = V4L2_STD_SECAM_L;
-                       } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
-                               curr_id = V4L2_STD_SECAM_LC;
-                       } else {
+               v4l2_std_id id = vfd->tvnorms, curr_id = 0;
+               unsigned int index = p->index, i, j = 0;
+               const char *descr = "";
+
+               /* Return norm array in a canonical way */
+               for (i = 0; i <= index && id; i++) {
+                       /* last std value in the standards array is 0, so this
+                          while always ends there since (id & 0) == 0. */
+                       while ((id & standards[j].std) != standards[j].std)
+                               j++;
+                       curr_id = standards[j].std;
+                       descr = standards[j].descr;
+                       j++;
+                       if (curr_id == 0)
                                break;
-                       }
-                       id &= ~curr_id;
+                       if (curr_id != V4L2_STD_PAL &&
+                           curr_id != V4L2_STD_SECAM &&
+                           curr_id != V4L2_STD_NTSC)
+                               id &= ~curr_id;
                }
-               if (i<=index)
+               if (i <= index)
                        return -EINVAL;
 
-               v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
+               v4l2_video_std_construct(p, curr_id, descr);
                p->index = index;
 
-               dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
+               dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
                                "framelines=%d\n", p->index,
                                (unsigned long long)p->id, p->name,
                                p->frameperiod.numerator,
                                p->frameperiod.denominator,
                                p->framelines);
 
-               ret=0;
+               ret = 0;
                break;
        }
        case VIDIOC_G_STD:
index 845be1864f685a01fad3a225bc9826ab09d61985..5ff9a58b6135b98b8644af14d042cc31cc824a5a 100644 (file)
@@ -327,13 +327,14 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
        int hmax  = buf->vb.height;
        int wmax  = buf->vb.width;
        struct timeval ts;
-       char *tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC);
+       char *tmpbuf;
        void *vbuf = videobuf_to_vmalloc(&buf->vb);
 
-       if (!tmpbuf)
+       if (!vbuf)
                return;
 
-       if (!vbuf)
+       tmpbuf = kmalloc(wmax * 2, GFP_ATOMIC);
+       if (!tmpbuf)
                return;
 
        for (h = 0; h < hmax; h++) {
index 2edda8cc7f9999af1e5f772df389c20719373190..aabad8ce7458c852a496422991c0683c0fe43d26 100644 (file)
@@ -1768,9 +1768,10 @@ vortex_timer(unsigned long data)
        case XCVR_MII: case XCVR_NWAY:
                {
                        ok = 1;
-                       spin_lock_bh(&vp->lock);
+                       /* Interrupts are already disabled */
+                       spin_lock(&vp->lock);
                        vortex_check_media(dev, 0);
-                       spin_unlock_bh(&vp->lock);
+                       spin_unlock(&vp->lock);
                }
                break;
          default:                                      /* Other media types handled by Tx timeouts. */
index f3cba5e24ec511a7a08ea6c0659155850a165b00..1037b1332312998aa36274b279381263419f0371 100644 (file)
@@ -1803,6 +1803,8 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
        if (rx->prev->skb) {
                struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data;
                put_unaligned_le32(rx->dma_addr, &prev_rfd->link);
+               pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
+                       sizeof(struct rfd), PCI_DMA_TODEVICE);
        }
 
        return 0;
index 701531e72e7b3b4d1ddab378e5b05795c320d052..a3f6a9c72ec8546b11ab987b27ea330ca1fba5e2 100644 (file)
@@ -347,7 +347,7 @@ e1000_set_tso(struct net_device *netdev, u32 data)
        else
                netdev->features &= ~NETIF_F_TSO;
 
-       if (data)
+       if (data && (adapter->hw.mac_type > e1000_82547_rev_2))
                netdev->features |= NETIF_F_TSO6;
        else
                netdev->features &= ~NETIF_F_TSO6;
index cab1835173cd9bb7096f82647a5f59ae13eaba18..648a87bbf4670ae8f87ffce4f123769d66de84f6 100644 (file)
@@ -2535,7 +2535,8 @@ void e1000e_down(struct e1000_adapter *adapter)
        adapter->link_speed = 0;
        adapter->link_duplex = 0;
 
-       e1000e_reset(adapter);
+       if (!pci_channel_offline(adapter->pdev))
+               e1000e_reset(adapter);
        e1000_clean_tx_ring(adapter);
        e1000_clean_rx_ring(adapter);
 
index 0b94833e23f7a48b76d16e3f5419d24d7f0556a7..e8cfadefa4b6751dbb74bd663a0f101e76a98d54 100644 (file)
@@ -1077,8 +1077,6 @@ static inline void rx_off(struct scc_priv *priv)
 
 static void start_timer(struct scc_priv *priv, int t, int r15)
 {
-       unsigned long flags;
-
        outb(priv->tmr_mode, priv->tmr_ctrl);
        if (t == 0) {
                tm_isr(priv);
index ae398f04c7b44d8ef8865ed4f902dba1d12a0172..e79a26a886c883e0fc56ba0318a1aaa87b41e366 100644 (file)
@@ -718,7 +718,8 @@ void igb_down(struct igb_adapter *adapter)
        adapter->link_speed = 0;
        adapter->link_duplex = 0;
 
-       igb_reset(adapter);
+       if (!pci_channel_offline(adapter->pdev))
+               igb_reset(adapter);
        igb_clean_all_tx_rings(adapter);
        igb_clean_all_rx_rings(adapter);
 }
index 679a0826780e3471346a902c516daf534811e80c..2c03f4e2ccc44427206e8a868412be0bb92fac49 100644 (file)
@@ -1271,7 +1271,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
 
                        framelen = le64_to_cpu(rxfd->rfs) & IPG_RFS_RXFRAMELEN;
 
-                       endframeLen = framelen - jumbo->current_size;
+                       endframelen = framelen - jumbo->current_size;
                        /*
                        if (framelen > IPG_RXFRAG_SIZE)
                                framelen=IPG_RXFRAG_SIZE;
@@ -1279,8 +1279,8 @@ static void ipg_nic_rx_with_end(struct net_device *dev,
                        if (framelen > IPG_RXSUPPORT_SIZE)
                                dev_kfree_skb_irq(jumbo->skb);
                        else {
-                               memcpy(skb_put(jumbo->skb, endframeLen),
-                                      skb->data, endframeLen);
+                               memcpy(skb_put(jumbo->skb, endframelen),
+                                      skb->data, endframelen);
 
                                jumbo->skb->protocol =
                                    eth_type_trans(jumbo->skb, dev);
@@ -1352,16 +1352,16 @@ static int ipg_nic_rx(struct net_device *dev)
 
                switch (ipg_nic_rx_check_frame_type(dev)) {
                case FRAME_WITH_START_WITH_END:
-                       ipg_nic_rx_with_start_and_end(dev, tp, rxfd, entry);
+                       ipg_nic_rx_with_start_and_end(dev, sp, rxfd, entry);
                        break;
                case FRAME_WITH_START:
-                       ipg_nic_rx_with_start(dev, tp, rxfd, entry);
+                       ipg_nic_rx_with_start(dev, sp, rxfd, entry);
                        break;
                case FRAME_WITH_END:
-                       ipg_nic_rx_with_end(dev, tp, rxfd, entry);
+                       ipg_nic_rx_with_end(dev, sp, rxfd, entry);
                        break;
                case FRAME_NO_START_NO_END:
-                       ipg_nic_rx_no_start_no_end(dev, tp, rxfd, entry);
+                       ipg_nic_rx_no_start_no_end(dev, sp, rxfd, entry);
                        break;
                }
        }
@@ -1808,7 +1808,7 @@ static int ipg_nic_open(struct net_device *dev)
        /* initialize JUMBO Frame control variable */
        sp->jumbo.found_start = 0;
        sp->jumbo.current_size = 0;
-       sp->jumbo.skb = 0;
+       sp->jumbo.skb = NULL;
        dev->mtu = IPG_TXFRAG_SIZE;
 #endif
 
index 7b859220c255b3b81017f156548df2dcca2f32e7..8f04609011538e257b820e9b521359750073cc63 100644 (file)
@@ -1969,7 +1969,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
 
-       ixgbe_reset(adapter);
+       if (!pci_channel_offline(adapter->pdev))
+               ixgbe_reset(adapter);
        ixgbe_clean_all_tx_rings(adapter);
        ixgbe_clean_all_rx_rings(adapter);
 
index 6797ed069f1f43ed659147da5d925bda1036e9e8..63cd67b931e7537cde2c407c63812c9fd3ffac02 100644 (file)
@@ -71,14 +71,18 @@ static irqreturn_t netxen_intr(int irq, void *data);
 static irqreturn_t netxen_msi_intr(int irq, void *data);
 
 /*  PCI Device ID Table  */
+#define ENTRY(device) \
+       {PCI_DEVICE(0x4040, (device)), \
+       .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
+
 static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
-       {PCI_DEVICE(0x4040, 0x0001), PCI_DEVICE_CLASS(0x020000, ~0)},
-       {PCI_DEVICE(0x4040, 0x0002), PCI_DEVICE_CLASS(0x020000, ~0)},
-       {PCI_DEVICE(0x4040, 0x0003), PCI_DEVICE_CLASS(0x020000, ~0)},
-       {PCI_DEVICE(0x4040, 0x0004), PCI_DEVICE_CLASS(0x020000, ~0)},
-       {PCI_DEVICE(0x4040, 0x0005), PCI_DEVICE_CLASS(0x020000, ~0)},
-       {PCI_DEVICE(0x4040, 0x0024), PCI_DEVICE_CLASS(0x020000, ~0)},
-       {PCI_DEVICE(0x4040, 0x0025), PCI_DEVICE_CLASS(0x020000, ~0)},
+       ENTRY(0x0001),
+       ENTRY(0x0002),
+       ENTRY(0x0003),
+       ENTRY(0x0004),
+       ENTRY(0x0005),
+       ENTRY(0x0024),
+       ENTRY(0x0025),
        {0,}
 };
 
index ce95c5d168fe9922382726ce71e295392548f2a3..70d012e90dcf35bb1aea12b0bcc6ee7f6e3d1260 100644 (file)
@@ -525,12 +525,14 @@ static int axnet_open(struct net_device *dev)
     int ret;
     axnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
+    unsigned int nic_base = dev->base_addr;
     
     DEBUG(2, "axnet_open('%s')\n", dev->name);
 
     if (!pcmcia_dev_present(link))
        return -ENODEV;
 
+    outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
     ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev);
     if (ret)
            return ret;
index fd8158a86f6490ce7dbaf389595b8e34a3d51821..2d4c4ad89b8dbda9fdcd773b7c9825d4de1889b8 100644 (file)
@@ -969,6 +969,7 @@ static int pcnet_open(struct net_device *dev)
     int ret;
     pcnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
+    unsigned int nic_base = dev->base_addr;
 
     DEBUG(2, "pcnet_open('%s')\n", dev->name);
 
@@ -976,6 +977,8 @@ static int pcnet_open(struct net_device *dev)
        return -ENODEV;
 
     set_misc_reg(dev);
+
+    outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
     ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
     if (ret)
            return ret;
index bafb69b6f7cbdeb26ea7975a2d46d2f04f7bdb24..fc6f4b8c64b35cc169ab228c9c130b6ed0a4c821 100644 (file)
@@ -942,7 +942,7 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
        m->msg_namelen = 0;
 
        if (skb) {
-               total_len = min(total_len, skb->len);
+               total_len = min_t(size_t, total_len, skb->len);
                error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
                if (error == 0)
                        error = total_len;
index b7f7b2227d5697df09413841074d143c5ef8ac88..bccee68bd48a53fb671f2634d2b7bc3dd64cb36e 100644 (file)
@@ -3701,7 +3701,9 @@ static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset)
                printk(KERN_ERR PFX
                                "%s: Driver up/down cycle failed, "
                                "closing device\n",qdev->ndev->name);
+               rtnl_lock();
                dev_close(qdev->ndev);
+               rtnl_unlock();
                return -1;
        }
        return 0;
index 858b191517b3dfc17800147191d0afe4e3f22b1b..504a48ff73c83e5cbac2eaa96c25bdc754bbd40e 100644 (file)
@@ -273,7 +273,7 @@ static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
        dma_addr_t mapping = desc_dma;
 
        while (size-- > 0) {
-               mapping += sizeof(sizeof(*desc));
+               mapping += sizeof(*desc);
                desc->ndesc = cpu_to_le32(mapping);
                desc->vndescp = desc + 1;
                desc++;
index b5c1e663417d874aaba92270b2f765fe5cab8ee0..ae7b697456b4c88245ec36e6599efb17e6dc280f 100644 (file)
@@ -2625,9 +2625,7 @@ static int fill_rx_buffers(struct ring_info *ring)
                        rxdp1->Buffer0_ptr = pci_map_single
                            (ring->pdev, skb->data, size - NET_IP_ALIGN,
                                PCI_DMA_FROMDEVICE);
-                       if( (rxdp1->Buffer0_ptr == 0) ||
-                               (rxdp1->Buffer0_ptr ==
-                               DMA_ERROR_CODE))
+                       if(pci_dma_mapping_error(rxdp1->Buffer0_ptr))
                                goto pci_map_failed;
 
                        rxdp->Control_2 =
@@ -2657,6 +2655,7 @@ static int fill_rx_buffers(struct ring_info *ring)
                        skb->data = (void *) (unsigned long)tmp;
                        skb_reset_tail_pointer(skb);
 
+                       /* AK: check is wrong. 0 can be valid dma address */
                        if (!(rxdp3->Buffer0_ptr))
                                rxdp3->Buffer0_ptr =
                                   pci_map_single(ring->pdev, ba->ba_0,
@@ -2665,8 +2664,7 @@ static int fill_rx_buffers(struct ring_info *ring)
                                pci_dma_sync_single_for_device(ring->pdev,
                                (dma_addr_t) rxdp3->Buffer0_ptr,
                                    BUF0_LEN, PCI_DMA_FROMDEVICE);
-                       if( (rxdp3->Buffer0_ptr == 0) ||
-                               (rxdp3->Buffer0_ptr == DMA_ERROR_CODE))
+                       if (pci_dma_mapping_error(rxdp3->Buffer0_ptr))
                                goto pci_map_failed;
 
                        rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
@@ -2681,18 +2679,17 @@ static int fill_rx_buffers(struct ring_info *ring)
                                (ring->pdev, skb->data, ring->mtu + 4,
                                                PCI_DMA_FROMDEVICE);
 
-                               if( (rxdp3->Buffer2_ptr == 0) ||
-                                       (rxdp3->Buffer2_ptr == DMA_ERROR_CODE))
+                               if (pci_dma_mapping_error(rxdp3->Buffer2_ptr))
                                        goto pci_map_failed;
 
+                               /* AK: check is wrong */
                                if (!rxdp3->Buffer1_ptr)
                                        rxdp3->Buffer1_ptr =
                                                pci_map_single(ring->pdev,
                                                ba->ba_1, BUF1_LEN,
                                                PCI_DMA_FROMDEVICE);
 
-                               if( (rxdp3->Buffer1_ptr == 0) ||
-                                       (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+                               if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) {
                                        pci_unmap_single
                                                (ring->pdev,
                                                (dma_addr_t)(unsigned long)
@@ -4264,16 +4261,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                txdp->Buffer_Pointer = pci_map_single(sp->pdev,
                                        fifo->ufo_in_band_v,
                                        sizeof(u64), PCI_DMA_TODEVICE);
-               if((txdp->Buffer_Pointer == 0) ||
-                       (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+               if (pci_dma_mapping_error(txdp->Buffer_Pointer))
                        goto pci_map_failed;
                txdp++;
        }
 
        txdp->Buffer_Pointer = pci_map_single
            (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
-       if((txdp->Buffer_Pointer == 0) ||
-               (txdp->Buffer_Pointer == DMA_ERROR_CODE))
+       if (pci_dma_mapping_error(txdp->Buffer_Pointer))
                goto pci_map_failed;
 
        txdp->Host_Control = (unsigned long) skb;
@@ -6884,10 +6879,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                                pci_map_single( sp->pdev, (*skb)->data,
                                        size - NET_IP_ALIGN,
                                        PCI_DMA_FROMDEVICE);
-                       if( (rxdp1->Buffer0_ptr == 0) ||
-                               (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) {
+                       if (pci_dma_mapping_error(rxdp1->Buffer0_ptr))
                                goto memalloc_failed;
-                       }
                        rxdp->Host_Control = (unsigned long) (*skb);
                }
        } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) {
@@ -6913,15 +6906,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                                pci_map_single(sp->pdev, (*skb)->data,
                                               dev->mtu + 4,
                                               PCI_DMA_FROMDEVICE);
-                       if( (rxdp3->Buffer2_ptr == 0) ||
-                               (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) {
+                       if (pci_dma_mapping_error(rxdp3->Buffer2_ptr))
                                goto memalloc_failed;
-                       }
                        rxdp3->Buffer0_ptr = *temp0 =
                                pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN,
                                                PCI_DMA_FROMDEVICE);
-                       if( (rxdp3->Buffer0_ptr == 0) ||
-                               (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) {
+                       if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) {
                                pci_unmap_single (sp->pdev,
                                        (dma_addr_t)rxdp3->Buffer2_ptr,
                                        dev->mtu + 4, PCI_DMA_FROMDEVICE);
@@ -6933,8 +6923,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
                        rxdp3->Buffer1_ptr = *temp1 =
                                pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN,
                                                PCI_DMA_FROMDEVICE);
-                       if( (rxdp3->Buffer1_ptr == 0) ||
-                               (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) {
+                       if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) {
                                pci_unmap_single (sp->pdev,
                                        (dma_addr_t)rxdp3->Buffer0_ptr,
                                        BUF0_LEN, PCI_DMA_FROMDEVICE);
index 4706f7f9acb628b423834e90a467f273f2245fd7..1827b6686c986ff4ab2c70c8521f3dc8cfe0c35d 100644 (file)
@@ -75,10 +75,6 @@ static int debug_level = ERR_DBG;
 /* DEBUG message print. */
 #define DBG_PRINT(dbg_level, args...)  if(!(debug_level<dbg_level)) printk(args)
 
-#ifndef DMA_ERROR_CODE
-#define DMA_ERROR_CODE          (~(dma_addr_t)0x0)
-#endif
-
 /* Protocol assist features of the NIC */
 #define L3_CKSUM_OK 0xFFFF
 #define L4_CKSUM_OK 0xFFFF
index 10e4e85da3fcae7af7e9435145f06dad72abd35f..b07b8cbadeaf8eb4a34dbbfe848ad5499f2a628b 100644 (file)
@@ -1394,6 +1394,7 @@ tc35815_open(struct net_device *dev)
        tc35815_chip_init(dev);
        spin_unlock_irq(&lp->lock);
 
+       netif_carrier_off(dev);
        /* schedule a link state check */
        phy_start(lp->phy_dev);
 
@@ -1735,7 +1736,6 @@ tc35815_rx(struct net_device *dev)
                        skb = lp->rx_skbs[cur_bd].skb;
                        prefetch(skb->data);
                        lp->rx_skbs[cur_bd].skb = NULL;
-                       lp->fbl_count--;
                        pci_unmap_single(lp->pci_dev,
                                         lp->rx_skbs[cur_bd].skb_dma,
                                         RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
@@ -1791,6 +1791,7 @@ tc35815_rx(struct net_device *dev)
 #ifdef TC35815_USE_PACKEDBUFFER
                        while (lp->fbl_curid != id)
 #else
+                       lp->fbl_count--;
                        while (lp->fbl_count < RX_BUF_NUM)
 #endif
                        {
@@ -2453,6 +2454,7 @@ static int tc35815_resume(struct pci_dev *pdev)
                return 0;
        pci_set_power_state(pdev, PCI_D0);
        tc35815_restart(dev);
+       netif_carrier_off(dev);
        if (lp->phy_dev)
                phy_start(lp->phy_dev);
        netif_device_attach(dev);
index 249e18053d5fa4a2d6e29a60e33878bbe1f78c90..069f8bb0a99fa401e254a03ff94a77a4217d58b5 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/x25.h>
 #include <linux/lapb.h>
 #include <linux/init.h>
+#include <linux/rtnetlink.h>
 #include "x25_asy.h"
 
 #include <net/x25device.h>
@@ -601,8 +602,10 @@ static void x25_asy_close_tty(struct tty_struct *tty)
        if (!sl || sl->magic != X25_ASY_MAGIC)
                return;
 
+       rtnl_lock();
        if (sl->dev->flags & IFF_UP)
                dev_close(sl->dev);
+       rtnl_unlock();
 
        tty->disc_data = NULL;
        sl->tty = NULL;
index 36a9c42df835c3fa77241533cf90f1eb6c14e9e4..76f4c7bad8b83e52b30000ccc62f86a77113e45b 100644 (file)
@@ -72,6 +72,9 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
        struct b43_wldev *dev = led->dev;
        bool radio_enabled;
 
+       if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED))
+               return;
+
        /* Checking the radio-enabled status here is slightly racy,
         * but we want to avoid the locking overhead and we don't care
         * whether the LED has the wrong state for a second. */
index fa4b0d8b74a26df90df59f8f3fa57dc8925d023e..a70827793086e68aa14291ecb1f3086a29cdf384 100644 (file)
@@ -2883,12 +2883,11 @@ static int b43_op_tx(struct ieee80211_hw *hw,
 
        if (unlikely(skb->len < 2 + 2 + 6)) {
                /* Too short, this can't be a valid frame. */
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
+               goto drop_packet;
        }
        B43_WARN_ON(skb_shinfo(skb)->nr_frags);
        if (unlikely(!dev))
-               return NETDEV_TX_BUSY;
+               goto drop_packet;
 
        /* Transmissions on seperate queues can run concurrently. */
        read_lock_irqsave(&wl->tx_lock, flags);
@@ -2904,7 +2903,12 @@ static int b43_op_tx(struct ieee80211_hw *hw,
        read_unlock_irqrestore(&wl->tx_lock, flags);
 
        if (unlikely(err))
-               return NETDEV_TX_BUSY;
+               goto drop_packet;
+       return NETDEV_TX_OK;
+
+drop_packet:
+       /* We can not transmit this packet. Drop it. */
+       dev_kfree_skb_any(skb);
        return NETDEV_TX_OK;
 }
 
index c990f87b107acff6603a24a70b8f402144f64d9c..93ddc1cbcc8b2bb7453e8040288a1a2771c1d01b 100644 (file)
@@ -876,6 +876,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
        if (!ring)
                goto out;
        ring->type = type;
+       ring->dev = dev;
 
        nr_slots = B43legacy_RXRING_SLOTS;
        if (for_tx)
@@ -922,7 +923,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
                                 DMA_TO_DEVICE);
        }
 
-       ring->dev = dev;
        ring->nr_slots = nr_slots;
        ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
        ring->index = controller_index;
index 204077c13870c05b619f781154bcc942eb1cdf1d..3e612d0a13e8fc927c766c09507067a0d009a988 100644 (file)
@@ -2378,8 +2378,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
        } else
                err = b43legacy_dma_tx(dev, skb, ctl);
 out:
-       if (unlikely(err))
-               return NETDEV_TX_BUSY;
+       if (unlikely(err)) {
+               /* Drop the packet. */
+               dev_kfree_skb_any(skb);
+       }
        return NETDEV_TX_OK;
 }
 
index 4fd73809602e7e8af816a30570b7da7306af71e3..020f450e9dba9cd7f903e7c5b380a5f0600d1c04 100644 (file)
@@ -64,7 +64,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
        int hdrlen, phdrlen, head_need, tail_need;
        u16 fc;
        int prism_header, ret;
-       struct ieee80211_hdr_4addr *hdr;
+       struct ieee80211_hdr_4addr *fhdr;
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -83,8 +83,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
                phdrlen = 0;
        }
 
-       hdr = (struct ieee80211_hdr_4addr *) skb->data;
-       fc = le16_to_cpu(hdr->frame_ctl);
+       fhdr = (struct ieee80211_hdr_4addr *) skb->data;
+       fc = le16_to_cpu(fhdr->frame_ctl);
 
        if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
                printk(KERN_DEBUG "%s: dropped management frame with header "
@@ -551,7 +551,7 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
             hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff ||
             hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) {
                /* RA (or BSSID) is not ours - drop */
-               PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with "
+               PDEBUG(DEBUG_EXTRA2, "%s: received WDS frame with "
                       "not own or broadcast %s=%s\n",
                       local->dev->name,
                       fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID",
index 0acd9589c48c0f36277f6b1351a559bbb1988f14..ab981afd481d6ea5a3cc199dcac224b015f6c5bd 100644 (file)
@@ -1930,7 +1930,7 @@ static void handle_pspoll(local_info_t *local,
                PDEBUG(DEBUG_PS, "   PSPOLL and AID[15:14] not set\n");
                return;
        }
-       aid &= ~BIT(15) & ~BIT(14);
+       aid &= ~(BIT(15) | BIT(14));
        if (aid == 0 || aid > MAX_AID_TABLE_SIZE) {
                PDEBUG(DEBUG_PS, "   invalid aid=%d\n", aid);
                return;
index ed4317a17cbb03beafb276e9f870dece124b24e8..80039a0ae0276c6514978dd2d945bfc284520447 100644 (file)
@@ -533,10 +533,10 @@ static void prism2_detach(struct pcmcia_device *link)
 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
 #define CFG_CHECK2(fn, retf) \
-do { int ret = (retf); \
-if (ret != 0) { \
-       PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \
-       cs_error(link, fn, ret); \
+do { int _ret = (retf); \
+if (_ret != 0) { \
+       PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \
+       cs_error(link, fn, _ret); \
        goto next_entry; \
 } \
 } while (0)
index cdf90c40f11b872c60fc293e5caef3a1d82756b9..936f52e3d95c4040a18515e2f949027a95442638 100644 (file)
@@ -2835,7 +2835,7 @@ static void hostap_passive_scan(unsigned long data)
 {
        local_info_t *local = (local_info_t *) data;
        struct net_device *dev = local->dev;
-       u16 channel;
+       u16 chan;
 
        if (local->passive_scan_interval <= 0)
                return;
@@ -2872,11 +2872,11 @@ static void hostap_passive_scan(unsigned long data)
 
                printk(KERN_DEBUG "%s: passive scan channel %d\n",
                       dev->name, local->passive_scan_channel);
-               channel = local->passive_scan_channel;
+               chan = local->passive_scan_channel;
                local->passive_scan_state = PASSIVE_SCAN_WAIT;
                local->passive_scan_timer.expires = jiffies + HZ / 10;
        } else {
-               channel = local->channel;
+               chan = local->channel;
                local->passive_scan_state = PASSIVE_SCAN_LISTEN;
                local->passive_scan_timer.expires = jiffies +
                        local->passive_scan_interval * HZ;
@@ -2884,9 +2884,9 @@ static void hostap_passive_scan(unsigned long data)
 
        if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST |
                                 (HFA384X_TEST_CHANGE_CHANNEL << 8),
-                                channel, NULL, 0))
+                                chan, NULL, 0))
                printk(KERN_ERR "%s: passive scan channel set %d "
-                      "failed\n", dev->name, channel);
+                      "failed\n", dev->name, chan);
 
        add_timer(&local->passive_scan_timer);
 }
index f7aec9309d0412c86dd0bc3fd111ff9c37ef7d5c..a38e85f334df2991e7d086085250d7fd092d2080 100644 (file)
@@ -594,7 +594,8 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
 }
 
 
-int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+static int hostap_80211_header_parse(const struct sk_buff *skb,
+                                    unsigned char *haddr)
 {
        struct hostap_interface *iface = netdev_priv(skb->dev);
        local_info_t *local = iface->local;
@@ -857,7 +858,6 @@ const struct header_ops hostap_80211_ops = {
        .rebuild        = eth_rebuild_header,
        .cache          = eth_header_cache,
        .cache_update   = eth_header_cache_update,
-
        .parse          = hostap_80211_header_parse,
 };
 EXPORT_SYMBOL(hostap_80211_ops);
@@ -1150,7 +1150,6 @@ EXPORT_SYMBOL(hostap_set_roaming);
 EXPORT_SYMBOL(hostap_set_auth_algs);
 EXPORT_SYMBOL(hostap_dump_rx_header);
 EXPORT_SYMBOL(hostap_dump_tx_header);
-EXPORT_SYMBOL(hostap_80211_header_parse);
 EXPORT_SYMBOL(hostap_80211_get_hdrlen);
 EXPORT_SYMBOL(hostap_get_stats);
 EXPORT_SYMBOL(hostap_setup_dev);
index 13925b627e3b5569f5ebaf1399f121dea3d489d2..b1b3c523185de39a2e5f38670cda26cf1aba6b17 100644 (file)
@@ -2227,7 +2227,10 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
        }
 
        IWL_DEBUG_INFO("Starting scan...\n");
-       priv->scan_bands = 2;
+       if (priv->cfg->sku & IWL_SKU_G)
+               priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+       if (priv->cfg->sku & IWL_SKU_A)
+               priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
        set_bit(STATUS_SCANNING, &priv->status);
        priv->scan_start = jiffies;
        priv->scan_pass_start = priv->scan_start;
@@ -3352,13 +3355,18 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
        cancel_delayed_work(&priv->scan_check);
 
        IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
-                      (priv->scan_bands == 2) ? "2.4" : "5.2",
+                      (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
+                                                       "2.4" : "5.2",
                       jiffies_to_msecs(elapsed_jiffies
                                        (priv->scan_pass_start, jiffies)));
 
-       /* Remove this scanned band from the list
-        * of pending bands to scan */
-       priv->scan_bands--;
+       /* Remove this scanned band from the list of pending
+        * bands to scan, band G precedes A in order of scanning
+        * as seen in iwl3945_bg_request_scan */
+       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
+               priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
+       else if (priv->scan_bands &  BIT(IEEE80211_BAND_5GHZ))
+               priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
 
        /* If a request to abort was given, or the scan did not succeed
         * then we reset the scan state machine and terminate,
@@ -4972,7 +4980,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
 
                ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
                if (!is_channel_valid(ch_info)) {
-                       IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
+                       IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
                                       scan_ch->channel);
                        continue;
                }
@@ -6315,21 +6323,16 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
 
        /* flags + rate selection */
 
-       switch (priv->scan_bands) {
-       case 2:
+       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
                scan->good_CRC_th = 0;
                band = IEEE80211_BAND_2GHZ;
-               break;
-
-       case 1:
+       } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
                scan->good_CRC_th = IWL_GOOD_CRC_TH;
                band = IEEE80211_BAND_5GHZ;
-               break;
-
-       default:
+       } else {
                IWL_WARNING("Invalid scan band count\n");
                goto done;
        }
@@ -6770,7 +6773,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
        ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
                                           conf->channel->hw_value);
        if (!is_channel_valid(ch_info)) {
-               IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n",
+               IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
                               conf->channel->hw_value, conf->channel->band);
                IWL_DEBUG_MAC80211("leave - invalid channel\n");
                spin_unlock_irqrestore(&priv->lock, flags);
index 883b42f7e9989dff95e085cf6afb6577eb9f7f1a..5ed16ce784689b9c1439d4fe96a98bd032a03e3f 100644 (file)
@@ -1774,7 +1774,10 @@ static int iwl4965_scan_initiate(struct iwl_priv *priv)
        }
 
        IWL_DEBUG_INFO("Starting scan...\n");
-       priv->scan_bands = 2;
+       if (priv->cfg->sku & IWL_SKU_G)
+               priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
+       if (priv->cfg->sku & IWL_SKU_A)
+               priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
        set_bit(STATUS_SCANNING, &priv->status);
        priv->scan_start = jiffies;
        priv->scan_pass_start = priv->scan_start;
@@ -3023,8 +3026,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
 
        IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
        if (index != -1) {
-               int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
 #ifdef CONFIG_IWL4965_HT
+               int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
+
                if (tid != MAX_TID_COUNT)
                        priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
                if (iwl4965_queue_space(&txq->q) > txq->q.low_mark &&
@@ -3276,13 +3280,18 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv,
        cancel_delayed_work(&priv->scan_check);
 
        IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
-                      (priv->scan_bands == 2) ? "2.4" : "5.2",
+                      (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
+                                               "2.4" : "5.2",
                       jiffies_to_msecs(elapsed_jiffies
                                        (priv->scan_pass_start, jiffies)));
 
-       /* Remove this scanned band from the list
-        * of pending bands to scan */
-       priv->scan_bands--;
+       /* Remove this scanned band from the list of pending
+        * bands to scan, band G precedes A in order of scanning
+        * as seen in iwl_bg_request_scan */
+       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
+               priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
+       else if (priv->scan_bands &  BIT(IEEE80211_BAND_5GHZ))
+               priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
 
        /* If a request to abort was given, or the scan did not succeed
         * then we reset the scan state machine and terminate,
@@ -3292,7 +3301,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv,
                clear_bit(STATUS_SCAN_ABORTING, &priv->status);
        } else {
                /* If there are more bands on this scan pass reschedule */
-               if (priv->scan_bands > 0)
+               if (priv->scan_bands)
                        goto reschedule;
        }
 
@@ -4635,10 +4644,9 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv,
 
                scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq);
 
-               ch_info = iwl_get_channel_info(priv, band,
-                                        scan_ch->channel);
+               ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
                if (!is_channel_valid(ch_info)) {
-                       IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
+                       IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
                                       scan_ch->channel);
                        continue;
                }
@@ -5830,8 +5838,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
        scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
 
-       switch (priv->scan_bands) {
-       case 2:
+       if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
                scan->tx_cmd.rate_n_flags =
                                iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP,
@@ -5839,17 +5846,13 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
 
                scan->good_CRC_th = 0;
                band = IEEE80211_BAND_2GHZ;
-               break;
-
-       case 1:
+       } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                scan->tx_cmd.rate_n_flags =
                                iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
                                RATE_MCS_ANT_B_MSK);
                scan->good_CRC_th = IWL_GOOD_CRC_TH;
                band = IEEE80211_BAND_5GHZ;
-               break;
-
-       default:
+       } else {
                IWL_WARNING("Invalid scan band count\n");
                goto done;
        }
index 762e85bef55dcef657ded932a53f911b051ae4b9..e43bae97ed8f66a6bc9ccb9eeb86a66a6db0302c 100644 (file)
@@ -290,7 +290,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
 
                avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
                avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
-               avs->mactime = cpu_to_be64(le64_to_cpu(clock));
+               avs->mactime = cpu_to_be64(clock);
                avs->hosttime = cpu_to_be64(jiffies);
                avs->phytype = cpu_to_be32(6);  /*OFDM: 6 for (g), 8 for (a) */
                avs->channel = cpu_to_be32(channel_of_freq(freq));
index fdbd0ef2be4bceef492431262796e6466a11e0b8..61e59c17a60aa09ae477d4df6f70a988ff47ad24 100644 (file)
@@ -138,11 +138,8 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt2500usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
-               mutex_unlock(&rt2x00dev->usb_cache_mutex);
-               return;
-       }
+       if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
+               goto exit_fail;
 
        /*
         * Write the data into the BBP.
@@ -155,6 +152,13 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
        rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
 
        mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
 }
 
 static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -168,10 +172,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt2500usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
-               return;
-       }
+       if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
+               goto exit_fail;
 
        /*
         * Write the request into the BBP.
@@ -186,17 +188,21 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt2500usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
-               *value = 0xff;
-               mutex_unlock(&rt2x00dev->usb_cache_mutex);
-               return;
-       }
+       if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
+               goto exit_fail;
 
        rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
        *value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
 
        mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
+       *value = 0xff;
 }
 
 static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
index 611d98320593869dc9c26faf2c64218c8c32e3ec..b4bf1e09cf9a906447ed8a5770e9e0cdfec52626 100644 (file)
@@ -821,6 +821,7 @@ struct rt2x00_dev {
        /*
         * Scheduled work.
         */
+       struct workqueue_struct *workqueue;
        struct work_struct intf_work;
        struct work_struct filter_work;
 
index 2673d568bcac286dc9f3cbdb8da9d3c5051ff7cc..c997d4f28ab39bd31e7e8b25adad8ea278b1c198 100644 (file)
@@ -75,7 +75,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
 
        rt2x00lib_reset_link_tuner(rt2x00dev);
 
-       queue_delayed_work(rt2x00dev->hw->workqueue,
+       queue_delayed_work(rt2x00dev->workqueue,
                           &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
 }
 
@@ -136,14 +136,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
        if (!__test_and_clear_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
                return;
 
-       /*
-        * Stop all scheduled work.
-        */
-       if (work_pending(&rt2x00dev->intf_work))
-               cancel_work_sync(&rt2x00dev->intf_work);
-       if (work_pending(&rt2x00dev->filter_work))
-               cancel_work_sync(&rt2x00dev->filter_work);
-
        /*
         * Stop the TX queues.
         */
@@ -398,8 +390,8 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
         * Increase tuner counter, and reschedule the next link tuner run.
         */
        rt2x00dev->link.count++;
-       queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work,
-                          LINK_TUNE_INTERVAL);
+       queue_delayed_work(rt2x00dev->workqueue,
+                          &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
 }
 
 static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
@@ -433,6 +425,15 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
 
        spin_unlock(&intf->lock);
 
+       /*
+        * It is possible the radio was disabled while the work had been
+        * scheduled. If that happens we should return here immediately,
+        * note that in the spinlock protected area above the delayed_flags
+        * have been cleared correctly.
+        */
+       if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+               return;
+
        if (delayed_flags & DELAYED_UPDATE_BEACON) {
                skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control);
                if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
@@ -441,7 +442,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
        }
 
        if (delayed_flags & DELAYED_CONFIG_ERP)
-               rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf);
+               rt2x00lib_config_erp(rt2x00dev, intf, &conf);
 
        if (delayed_flags & DELAYED_LED_ASSOC)
                rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
@@ -487,7 +488,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
                                                   rt2x00lib_beacondone_iter,
                                                   rt2x00dev);
 
-       queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+       queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
 
@@ -1130,6 +1131,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
        /*
         * Initialize configuration work.
         */
+       rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib");
+       if (!rt2x00dev->workqueue)
+               goto exit;
+
        INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
        INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
        INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
@@ -1189,6 +1194,13 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
        rt2x00rfkill_free(rt2x00dev);
        rt2x00leds_unregister(rt2x00dev);
 
+       /*
+        * Stop all queued work. Note that most tasks will already be halted
+        * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize().
+        */
+       flush_workqueue(rt2x00dev->workqueue);
+       destroy_workqueue(rt2x00dev->workqueue);
+
        /*
         * Free ieee80211_hw memory.
         */
index 87e280a21971faf5dbb8e5f15186ec8d41c21ec2..9cb023edd2e9bf7eaad394c5a205c2af3a6e9076 100644 (file)
@@ -428,7 +428,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
        if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
                rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
        else
-               queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
+               queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
 
@@ -509,7 +509,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
        memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
        if (delayed) {
                intf->delayed_flags |= delayed;
-               queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
+               queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
        }
        spin_unlock(&intf->lock);
 }
index fff8386e816ba289045ff8955575b7377a98b60b..83cc0147f6986570a00d39daa3cdf5a4381b2993 100644 (file)
@@ -134,11 +134,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt73usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
-               mutex_unlock(&rt2x00dev->usb_cache_mutex);
-               return;
-       }
+       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+               goto exit_fail;
 
        /*
         * Write the data into the BBP.
@@ -151,6 +148,13 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
 
        rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
        mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
 }
 
 static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -164,11 +168,8 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt73usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
-               mutex_unlock(&rt2x00dev->usb_cache_mutex);
-               return;
-       }
+       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+               goto exit_fail;
 
        /*
         * Write the request into the BBP.
@@ -184,14 +185,19 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
         * Wait until the BBP becomes ready.
         */
        reg = rt73usb_bbp_check(rt2x00dev);
-       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
-               ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
-               *value = 0xff;
-               return;
-       }
+       if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
+               goto exit_fail;
 
        *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
        mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       return;
+
+exit_fail:
+       mutex_unlock(&rt2x00dev->usb_cache_mutex);
+
+       ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
+       *value = 0xff;
 }
 
 static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,
index a0b6d414953dda3128acc7477827a7dcfbdd429b..59fbef08d690763920af4b7fac52752f30be0570 100644 (file)
@@ -2359,6 +2359,24 @@ void scsi_esp_unregister(struct esp *esp)
 }
 EXPORT_SYMBOL(scsi_esp_unregister);
 
+static int esp_target_alloc(struct scsi_target *starget)
+{
+       struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
+       struct esp_target_data *tp = &esp->target[starget->id];
+
+       tp->starget = starget;
+
+       return 0;
+}
+
+static void esp_target_destroy(struct scsi_target *starget)
+{
+       struct esp *esp = shost_priv(dev_to_shost(&starget->dev));
+       struct esp_target_data *tp = &esp->target[starget->id];
+
+       tp->starget = NULL;
+}
+
 static int esp_slave_alloc(struct scsi_device *dev)
 {
        struct esp *esp = shost_priv(dev->host);
@@ -2370,8 +2388,6 @@ static int esp_slave_alloc(struct scsi_device *dev)
                return -ENOMEM;
        dev->hostdata = lp;
 
-       tp->starget = dev->sdev_target;
-
        spi_min_period(tp->starget) = esp->min_period;
        spi_max_offset(tp->starget) = 15;
 
@@ -2608,6 +2624,8 @@ struct scsi_host_template scsi_esp_template = {
        .name                   = "esp",
        .info                   = esp_info,
        .queuecommand           = esp_queuecommand,
+       .target_alloc           = esp_target_alloc,
+       .target_destroy         = esp_target_destroy,
        .slave_alloc            = esp_slave_alloc,
        .slave_configure        = esp_slave_configure,
        .slave_destroy          = esp_slave_destroy,
index 45df83b9d847122abac77e2d7a9d5a59eb2cfb95..0fe031f003e7e8e5082dc91469204e53b35067b5 100644 (file)
@@ -61,7 +61,7 @@ static int ses_probe(struct device *dev)
        return err;
 }
 
-#define SES_TIMEOUT 30
+#define SES_TIMEOUT (30 * HZ)
 #define SES_RETRIES 3
 
 static int ses_recv_diag(struct scsi_device *sdev, int page_code,
index f20952c43cb83be784fbf4d35fceb0295ce44c8d..fd9bb777df286bfafeb9e36b306f7dbbe2e34e02 100644 (file)
@@ -49,6 +49,7 @@
 #define DMA_RX_YCOUNT          (PAGE_SIZE / DMA_RX_XCOUNT)
 
 #define DMA_RX_FLUSH_JIFFIES   (HZ / 50)
+#define CTS_CHECK_JIFFIES      (HZ / 50)
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
 static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
@@ -290,11 +291,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
 {
        struct circ_buf *xmit = &uart->port.info->xmit;
 
-       if (uart->port.x_char) {
-               UART_PUT_CHAR(uart, uart->port.x_char);
-               uart->port.icount.tx++;
-               uart->port.x_char = 0;
-       }
        /*
         * Check the modem control lines before
         * transmitting anything.
@@ -306,6 +302,12 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
                return;
        }
 
+       if (uart->port.x_char) {
+               UART_PUT_CHAR(uart, uart->port.x_char);
+               uart->port.icount.tx++;
+               uart->port.x_char = 0;
+       }
+
        while ((UART_GET_LSR(uart) & THRE) && xmit->tail != xmit->head) {
                UART_PUT_CHAR(uart, xmit->buf[xmit->tail]);
                xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -345,15 +347,6 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
 }
 #endif
 
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-static void bfin_serial_do_work(struct work_struct *work)
-{
-       struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue);
-
-       bfin_serial_mctrl_check(uart);
-}
-#endif
-
 #ifdef CONFIG_SERIAL_BFIN_DMA
 static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 {
@@ -361,6 +354,12 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
 
        uart->tx_done = 0;
 
+       /*
+        * Check the modem control lines before
+        * transmitting anything.
+        */
+       bfin_serial_mctrl_check(uart);
+
        if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
                uart->tx_count = 0;
                uart->tx_done = 1;
@@ -373,12 +372,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)
                uart->port.x_char = 0;
        }
 
-       /*
-        * Check the modem control lines before
-        * transmitting anything.
-        */
-       bfin_serial_mctrl_check(uart);
-
        uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
        if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail))
                uart->tx_count = UART_XMIT_SIZE - xmit->tail;
@@ -565,7 +558,10 @@ static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
        uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
        if (!(status & TIOCM_CTS)) {
                tty->hw_stopped = 1;
-               schedule_work(&uart->cts_workqueue);
+               uart->cts_timer.data = (unsigned long)(uart);
+               uart->cts_timer.function = (void *)bfin_serial_mctrl_check;
+               uart->cts_timer.expires = jiffies + CTS_CHECK_JIFFIES;
+               add_timer(&(uart->cts_timer));
        } else {
                tty->hw_stopped = 0;
        }
@@ -885,7 +881,7 @@ static void __init bfin_serial_init_ports(void)
                init_timer(&(bfin_serial_ports[i].rx_dma_timer));
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-               INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work);
+               init_timer(&(bfin_serial_ports[i].cts_timer));
                bfin_serial_ports[i].cts_pin        =
                        bfin_serial_resource[i].uart_cts_pin;
                bfin_serial_ports[i].rts_pin        =
index 4b628526df097562a94004a653a9ba16eed9dd18..a86e952ed4ca4de05891b19d54ef185802048bfc 100644 (file)
@@ -12,3 +12,12 @@ menuconfig THERMAL
          cooling devices.
          All platforms with ACPI thermal support can use this driver.
          If you want this support, you should say Y or M here.
+
+config THERMAL_HWMON
+       bool "Hardware monitoring support"
+       depends on HWMON=y || HWMON=THERMAL
+       help
+         The generic thermal sysfs driver's hardware monitoring support
+         requires a 2.10.7/3.0.2 or later lm-sensors userspace.
+
+         Say Y if your user-space is new enough.
index 6098787341f3d6ada67a195b7ee59d307b6a9c34..fe07462d5947fec44a4eb559a552670e84744a08 100644 (file)
@@ -295,8 +295,8 @@ thermal_cooling_device_trip_point_show(struct device *dev,
 
 /* Device management */
 
-#if defined(CONFIG_HWMON) ||   \
-       (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE))
+#if defined(CONFIG_THERMAL_HWMON)
+
 /* hwmon sys I/F */
 #include <linux/hwmon.h>
 static LIST_HEAD(thermal_hwmon_list);
index 8662a6b7a30b918725de2304ea0e6271339dffc0..25b352b664d96511a2e7bae9074947f60831b7b3 100644 (file)
@@ -68,7 +68,6 @@ obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
 obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o
 obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o
 obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o
-CFLAGS_hpwdt.o += -O
 obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o
 obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
 obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
index 2686f3eaeedf4c07f56eeafe21725977cd1a1ddc..eaa3f2a79ff55bebafa7a655092879322d0f7743 100644 (file)
@@ -140,49 +140,53 @@ static struct pci_device_id hpwdt_devices[] = {
 };
 MODULE_DEVICE_TABLE(pci, hpwdt_devices);
 
+extern asmlinkage void asminline_call(struct cmn_registers *pi86Regs, unsigned long *pRomEntry);
+
 #ifndef CONFIG_X86_64
 /* --32 Bit Bios------------------------------------------------------------ */
 
 #define HPWDT_ARCH     32
 
-asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
-                              unsigned long *pRomEntry)
-{
-       asm("pushl       %ebp               \n\t"
-           "movl        %esp, %ebp         \n\t"
-           "pusha                          \n\t"
-           "pushf                          \n\t"
-           "push        %es                \n\t"
-           "push        %ds                \n\t"
-           "pop         %es                \n\t"
-           "movl        8(%ebp),%eax       \n\t"
-           "movl        4(%eax),%ebx       \n\t"
-           "movl        8(%eax),%ecx       \n\t"
-           "movl        12(%eax),%edx      \n\t"
-           "movl        16(%eax),%esi      \n\t"
-           "movl        20(%eax),%edi      \n\t"
-           "movl        (%eax),%eax        \n\t"
-           "push        %cs                \n\t"
-           "call        *12(%ebp)          \n\t"
-           "pushf                          \n\t"
-           "pushl       %eax               \n\t"
-           "movl        8(%ebp),%eax       \n\t"
-           "movl        %ebx,4(%eax)       \n\t"
-           "movl        %ecx,8(%eax)       \n\t"
-           "movl        %edx,12(%eax)      \n\t"
-           "movl        %esi,16(%eax)      \n\t"
-           "movl        %edi,20(%eax)      \n\t"
-           "movw        %ds,24(%eax)       \n\t"
-           "movw        %es,26(%eax)       \n\t"
-           "popl        %ebx               \n\t"
-           "movl        %ebx,(%eax)        \n\t"
-           "popl        %ebx               \n\t"
-           "movl        %ebx,28(%eax)      \n\t"
-           "pop         %es                \n\t"
-           "popf                           \n\t"
-           "popa                           \n\t"
-           "leave                          \n\t" "ret");
-}
+asm(".text                          \n\t"
+    ".align 4                       \n"
+    "asminline_call:                \n\t"
+    "pushl       %ebp               \n\t"
+    "movl        %esp, %ebp         \n\t"
+    "pusha                          \n\t"
+    "pushf                          \n\t"
+    "push        %es                \n\t"
+    "push        %ds                \n\t"
+    "pop         %es                \n\t"
+    "movl        8(%ebp),%eax       \n\t"
+    "movl        4(%eax),%ebx       \n\t"
+    "movl        8(%eax),%ecx       \n\t"
+    "movl        12(%eax),%edx      \n\t"
+    "movl        16(%eax),%esi      \n\t"
+    "movl        20(%eax),%edi      \n\t"
+    "movl        (%eax),%eax        \n\t"
+    "push        %cs                \n\t"
+    "call        *12(%ebp)          \n\t"
+    "pushf                          \n\t"
+    "pushl       %eax               \n\t"
+    "movl        8(%ebp),%eax       \n\t"
+    "movl        %ebx,4(%eax)       \n\t"
+    "movl        %ecx,8(%eax)       \n\t"
+    "movl        %edx,12(%eax)      \n\t"
+    "movl        %esi,16(%eax)      \n\t"
+    "movl        %edi,20(%eax)      \n\t"
+    "movw        %ds,24(%eax)       \n\t"
+    "movw        %es,26(%eax)       \n\t"
+    "popl        %ebx               \n\t"
+    "movl        %ebx,(%eax)        \n\t"
+    "popl        %ebx               \n\t"
+    "movl        %ebx,28(%eax)      \n\t"
+    "pop         %es                \n\t"
+    "popf                           \n\t"
+    "popa                           \n\t"
+    "leave                          \n\t"
+    "ret                            \n\t"
+    ".previous");
+
 
 /*
  *     cru_detect
@@ -333,43 +337,44 @@ static int __devinit detect_cru_service(void)
 
 #define HPWDT_ARCH     64
 
-asmlinkage void asminline_call(struct cmn_registers *pi86Regs,
-                              unsigned long *pRomEntry)
-{
-       asm("pushq      %rbp            \n\t"
-           "movq       %rsp, %rbp      \n\t"
-           "pushq      %rax            \n\t"
-           "pushq      %rbx            \n\t"
-           "pushq      %rdx            \n\t"
-           "pushq      %r12            \n\t"
-           "pushq      %r9             \n\t"
-           "movq       %rsi, %r12      \n\t"
-           "movq       %rdi, %r9       \n\t"
-           "movl       4(%r9),%ebx     \n\t"
-           "movl       8(%r9),%ecx     \n\t"
-           "movl       12(%r9),%edx    \n\t"
-           "movl       16(%r9),%esi    \n\t"
-           "movl       20(%r9),%edi    \n\t"
-           "movl       (%r9),%eax      \n\t"
-           "call       *%r12           \n\t"
-           "pushfq                     \n\t"
-           "popq        %r12           \n\t"
-           "popfq                      \n\t"
-           "movl       %eax, (%r9)     \n\t"
-           "movl       %ebx, 4(%r9)    \n\t"
-           "movl       %ecx, 8(%r9)    \n\t"
-           "movl       %edx, 12(%r9)   \n\t"
-           "movl       %esi, 16(%r9)   \n\t"
-           "movl       %edi, 20(%r9)   \n\t"
-           "movq       %r12, %rax      \n\t"
-           "movl       %eax, 28(%r9)   \n\t"
-           "popq       %r9             \n\t"
-           "popq       %r12            \n\t"
-           "popq       %rdx            \n\t"
-           "popq       %rbx            \n\t"
-           "popq       %rax            \n\t"
-           "leave                      \n\t" "ret");
-}
+asm(".text                      \n\t"
+    ".align 4                   \n"
+    "asminline_call:            \n\t"
+    "pushq      %rbp            \n\t"
+    "movq       %rsp, %rbp      \n\t"
+    "pushq      %rax            \n\t"
+    "pushq      %rbx            \n\t"
+    "pushq      %rdx            \n\t"
+    "pushq      %r12            \n\t"
+    "pushq      %r9             \n\t"
+    "movq       %rsi, %r12      \n\t"
+    "movq       %rdi, %r9       \n\t"
+    "movl       4(%r9),%ebx     \n\t"
+    "movl       8(%r9),%ecx     \n\t"
+    "movl       12(%r9),%edx    \n\t"
+    "movl       16(%r9),%esi    \n\t"
+    "movl       20(%r9),%edi    \n\t"
+    "movl       (%r9),%eax      \n\t"
+    "call       *%r12           \n\t"
+    "pushfq                     \n\t"
+    "popq        %r12           \n\t"
+    "popfq                      \n\t"
+    "movl       %eax, (%r9)     \n\t"
+    "movl       %ebx, 4(%r9)    \n\t"
+    "movl       %ecx, 8(%r9)    \n\t"
+    "movl       %edx, 12(%r9)   \n\t"
+    "movl       %esi, 16(%r9)   \n\t"
+    "movl       %edi, 20(%r9)   \n\t"
+    "movq       %r12, %rax      \n\t"
+    "movl       %eax, 28(%r9)   \n\t"
+    "popq       %r9             \n\t"
+    "popq       %r12            \n\t"
+    "popq       %rdx            \n\t"
+    "popq       %rbx            \n\t"
+    "popq       %rax            \n\t"
+    "leave                      \n\t"
+    "ret                        \n\t"
+    ".previous");
 
 /*
  *     dmi_find_cru
index 470c10ceb0fb3a33dc8f28e7e8b2d3535042075b..10d8a0aa871a096eb3d8577b01d285aa9c1fa433 100644 (file)
@@ -931,8 +931,16 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
        struct gendisk *disk;
        int ret;
        int part;
+       int perm = 0;
 
-       ret = devcgroup_inode_permission(bdev->bd_inode, file->f_mode);
+       if (file->f_mode & FMODE_READ)
+               perm |= MAY_READ;
+       if (file->f_mode & FMODE_WRITE)
+               perm |= MAY_WRITE;
+       /*
+        * hooks: /n/, see "layering violations".
+        */
+       ret = devcgroup_inode_permission(bdev->bd_inode, perm);
        if (ret != 0)
                return ret;
 
index 3ee588d5f585b54d7aa50358648521b64423b3f8..6068c25b393ca21f5faf8c9ca1fdf8d6051fc836 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/syscalls.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/fdtable.h>
 #include <linux/fs.h>
 #include <linux/fsnotify.h>
 #include <linux/slab.h>
@@ -106,9 +107,10 @@ static void dentry_lru_remove(struct dentry *dentry)
 /*
  * Release the dentry's inode, using the filesystem
  * d_iput() operation if defined.
- * Called with dcache_lock and per dentry lock held, drops both.
  */
 static void dentry_iput(struct dentry * dentry)
+       __releases(dentry->d_lock)
+       __releases(dcache_lock)
 {
        struct inode *inode = dentry->d_inode;
        if (inode) {
@@ -132,12 +134,13 @@ static void dentry_iput(struct dentry * dentry)
  * d_kill - kill dentry and return parent
  * @dentry: dentry to kill
  *
- * Called with dcache_lock and d_lock, releases both.  The dentry must
- * already be unhashed and removed from the LRU.
+ * The dentry must already be unhashed and removed from the LRU.
  *
  * If this is the root of the dentry tree, return NULL.
  */
 static struct dentry *d_kill(struct dentry *dentry)
+       __releases(dentry->d_lock)
+       __releases(dcache_lock)
 {
        struct dentry *parent;
 
@@ -383,11 +386,11 @@ restart:
  * Try to prune ancestors as well.  This is necessary to prevent
  * quadratic behavior of shrink_dcache_parent(), but is also expected
  * to be beneficial in reducing dentry cache fragmentation.
- *
- * Called with dcache_lock, drops it and then regains.
- * Called with dentry->d_lock held, drops it.
  */
 static void prune_one_dentry(struct dentry * dentry)
+       __releases(dentry->d_lock)
+       __releases(dcache_lock)
+       __acquires(dcache_lock)
 {
        __d_drop(dentry);
        dentry = d_kill(dentry);
@@ -1604,10 +1607,9 @@ static int d_isparent(struct dentry *p1, struct dentry *p2)
  *
  * Note: If ever the locking in lock_rename() changes, then please
  * remember to update this too...
- *
- * On return, dcache_lock will have been unlocked.
  */
 static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
+       __releases(dcache_lock)
 {
        struct mutex *m1 = NULL, *m2 = NULL;
        struct dentry *ret;
@@ -1743,11 +1745,9 @@ out_nolock:
 shouldnt_be_hashed:
        spin_unlock(&dcache_lock);
        BUG();
-       goto shouldnt_be_hashed;
 }
 
-static int prepend(char **buffer, int *buflen, const char *str,
-                         int namelen)
+static int prepend(char **buffer, int *buflen, const char *str, int namelen)
 {
        *buflen -= namelen;
        if (*buflen < 0)
@@ -1757,8 +1757,13 @@ static int prepend(char **buffer, int *buflen, const char *str,
        return 0;
 }
 
+static int prepend_name(char **buffer, int *buflen, struct qstr *name)
+{
+       return prepend(buffer, buflen, name->name, name->len);
+}
+
 /**
- * d_path - return the path of a dentry
+ * __d_path - return the path of a dentry
  * @path: the dentry/vfsmount to report
  * @root: root vfsmnt/dentry (may be modified by this function)
  * @buffer: buffer to return value in
@@ -1779,9 +1784,10 @@ char *__d_path(const struct path *path, struct path *root,
 {
        struct dentry *dentry = path->dentry;
        struct vfsmount *vfsmnt = path->mnt;
-       char * end = buffer+buflen;
-       char * retval;
+       char *end = buffer + buflen;
+       char *retval;
 
+       spin_lock(&vfsmount_lock);
        prepend(&end, &buflen, "\0", 1);
        if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
                (prepend(&end, &buflen, " (deleted)", 10) != 0))
@@ -1800,38 +1806,37 @@ char *__d_path(const struct path *path, struct path *root,
                        break;
                if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
                        /* Global root? */
-                       spin_lock(&vfsmount_lock);
                        if (vfsmnt->mnt_parent == vfsmnt) {
-                               spin_unlock(&vfsmount_lock);
                                goto global_root;
                        }
                        dentry = vfsmnt->mnt_mountpoint;
                        vfsmnt = vfsmnt->mnt_parent;
-                       spin_unlock(&vfsmount_lock);
                        continue;
                }
                parent = dentry->d_parent;
                prefetch(parent);
-               if ((prepend(&end, &buflen, dentry->d_name.name,
-                               dentry->d_name.len) != 0) ||
+               if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
                    (prepend(&end, &buflen, "/", 1) != 0))
                        goto Elong;
                retval = end;
                dentry = parent;
        }
 
+out:
+       spin_unlock(&vfsmount_lock);
        return retval;
 
 global_root:
        retval += 1;    /* hit the slash */
-       if (prepend(&retval, &buflen, dentry->d_name.name,
-                   dentry->d_name.len) != 0)
+       if (prepend_name(&retval, &buflen, &dentry->d_name) != 0)
                goto Elong;
        root->mnt = vfsmnt;
        root->dentry = dentry;
-       return retval;
+       goto out;
+
 Elong:
-       return ERR_PTR(-ENAMETOOLONG);
+       retval = ERR_PTR(-ENAMETOOLONG);
+       goto out;
 }
 
 /**
@@ -1845,9 +1850,9 @@ Elong:
  *
  * Returns the buffer or an error code if the path was too long.
  *
- * "buflen" should be positive. Caller holds the dcache_lock.
+ * "buflen" should be positive.
  */
-char *d_path(struct path *path, char *buf, int buflen)
+char *d_path(const struct path *path, char *buf, int buflen)
 {
        char *res;
        struct path root;
@@ -1915,16 +1920,11 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
        retval = end-1;
        *retval = '/';
 
-       for (;;) {
-               struct dentry *parent;
-               if (IS_ROOT(dentry))
-                       break;
+       while (!IS_ROOT(dentry)) {
+               struct dentry *parent = dentry->d_parent;
 
-               parent = dentry->d_parent;
                prefetch(parent);
-
-               if ((prepend(&end, &buflen, dentry->d_name.name,
-                               dentry->d_name.len) != 0) ||
+               if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
                    (prepend(&end, &buflen, "/", 1) != 0))
                        goto Elong;
 
@@ -1975,7 +1975,7 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
        error = -ENOENT;
        /* Has the current directory has been unlinked? */
        spin_lock(&dcache_lock);
-       if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
+       if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
                unsigned long len;
                struct path tmp = root;
                char * cwd;
index 9ecb92f68543ab12f5531a7cf4cb2c6233d2258e..9ff7b1c04239d6581a12f0dd18a73538a0695abc 100644 (file)
@@ -855,7 +855,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
         */
 
        /* Update group descriptor block for new group */
-       gdp = (struct ext4_group_desc *)primary->b_data + gdb_off;
+       gdp = (struct ext4_group_desc *)((char *)primary->b_data +
+                                        gdb_off * EXT4_DESC_SIZE(sb));
 
        ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
        ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
index c19184f2e70e53f268c757dd77d6a481b6f8604d..bec76b1c2bb0c59c77d5d54bfae7502a2ff490fe 100644 (file)
@@ -246,15 +246,11 @@ static void find_metapath(const struct gfs2_sbd *sdp, u64 block,
 
 }
 
-static inline unsigned int zero_metapath_length(const struct metapath *mp,
-                                               unsigned height)
+static inline unsigned int metapath_branch_start(const struct metapath *mp)
 {
-       unsigned int i;
-       for (i = 0; i < height - 1; i++) {
-               if (mp->mp_list[i] != 0)
-                       return i;
-       }
-       return height;
+       if (mp->mp_list[0] == 0)
+               return 2;
+       return 1;
 }
 
 /**
@@ -436,7 +432,7 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct buffer_head *dibh = mp->mp_bh[0];
        u64 bn, dblock = 0;
-       unsigned n, i, blks, alloced = 0, iblks = 0, zmpl = 0;
+       unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
        unsigned dblks = 0;
        unsigned ptrs_per_blk;
        const unsigned end_of_metadata = height - 1;
@@ -471,9 +467,8 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
                        /* Building up tree height */
                        state = ALLOC_GROW_HEIGHT;
                        iblks = height - ip->i_height;
-                       zmpl = zero_metapath_length(mp, height);
-                       iblks -= zmpl;
-                       iblks += height;
+                       branch_start = metapath_branch_start(mp);
+                       iblks += (height - branch_start);
                }
        }
 
@@ -509,13 +504,13 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock,
                                        sizeof(struct gfs2_meta_header));
                                *ptr = zero_bn;
                                state = ALLOC_GROW_DEPTH;
-                               for(i = zmpl; i < height; i++) {
+                               for(i = branch_start; i < height; i++) {
                                        if (mp->mp_bh[i] == NULL)
                                                break;
                                        brelse(mp->mp_bh[i]);
                                        mp->mp_bh[i] = NULL;
                                }
-                               i = zmpl;
+                               i = branch_start;
                        }
                        if (n == 0)
                                break;
index 6387523a31530237da2d2545350787e4db53dd0d..3401628d742b6cbfd5b53c9a4ed11f42d3372413 100644 (file)
@@ -195,7 +195,7 @@ ulong_aligned:
           depending on architecture.  I've experimented with several ways
           of writing this section such as using an else before the goto
           but this one seems to be the fastest. */
-       while ((unsigned char *)plong < end - 1) {
+       while ((unsigned char *)plong < end - sizeof(unsigned long)) {
                prefetch(plong + 1);
                if (((*plong) & LBITMASK) != lskipval)
                        break;
index 11dbf08651b70861d31530ef73436dc2e3beffc1..dce8c747371c77e618ee387158c37451daf63c97 100644 (file)
@@ -561,9 +561,6 @@ static void locks_insert_lock(struct file_lock **pos, struct file_lock *fl)
        /* insert into file's list */
        fl->fl_next = *pos;
        *pos = fl;
-
-       if (fl->fl_ops && fl->fl_ops->fl_insert)
-               fl->fl_ops->fl_insert(fl);
 }
 
 /*
@@ -586,9 +583,6 @@ static void locks_delete_lock(struct file_lock **thisfl_p)
                fl->fl_fasync = NULL;
        }
 
-       if (fl->fl_ops && fl->fl_ops->fl_remove)
-               fl->fl_ops->fl_remove(fl);
-
        if (fl->fl_nspid) {
                put_pid(fl->fl_nspid);
                fl->fl_nspid = NULL;
index c7e43536c49ad06433c5963c446ce936e0f94e9f..01e67dddcc3d2033a2038c37f9f791ba0921a781 100644 (file)
@@ -581,15 +581,13 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd
        int result;
 
        /* make sure the stuff we saved doesn't go away */
-       dget(save.dentry);
-       mntget(save.mnt);
+       path_get(&save);
 
        result = __link_path_walk(name, nd);
        if (result == -ESTALE) {
                /* nd->path had been dropped */
                nd->path = save;
-               dget(nd->path.dentry);
-               mntget(nd->path.mnt);
+               path_get(&nd->path);
                nd->flags |= LOOKUP_REVAL;
                result = __link_path_walk(name, nd);
        }
@@ -1216,8 +1214,9 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
        nd->flags = flags;
        nd->depth = 0;
 
-       nd->path.mnt = mntget(mnt);
-       nd->path.dentry = dget(dentry);
+       nd->path.dentry = dentry;
+       nd->path.mnt = mnt;
+       path_get(&nd->path);
 
        retval = path_walk(name, nd);
        if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
@@ -2857,16 +2856,17 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
 {
        struct nameidata nd;
        void *cookie;
+       int res;
 
        nd.depth = 0;
        cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
-       if (!IS_ERR(cookie)) {
-               int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
-               if (dentry->d_inode->i_op->put_link)
-                       dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
-               cookie = ERR_PTR(res);
-       }
-       return PTR_ERR(cookie);
+       if (IS_ERR(cookie))
+               return PTR_ERR(cookie);
+
+       res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
+       if (dentry->d_inode->i_op->put_link)
+               dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
+       return res;
 }
 
 int vfs_follow_link(struct nameidata *nd, const char *link)
index 49c7cd0502cc39b9411460ac7b27b6ac367781c2..779d2eb649c57935f8929f02271e48ca03759151 100644 (file)
@@ -130,10 +130,11 @@ static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
                                struct mnt_fhstatus *res)
 {
        struct nfs_fh *fh = res->fh;
+       unsigned size;
 
        if ((res->status = ntohl(*p++)) == 0) {
-               int size = ntohl(*p++);
-               if (size <= NFS3_FHSIZE) {
+               size = ntohl(*p++);
+               if (size <= NFS3_FHSIZE && size != 0) {
                        fh->size = size;
                        memcpy(fh->data, p, size);
                } else
index 2a4a024a4e7bf09c53575b6ef74398c67779d329..614efeed5437f95da60a43563130593aa0d02d32 100644 (file)
@@ -1216,8 +1216,6 @@ static int nfs_validate_mount_data(void *options,
 {
        struct nfs_mount_data *data = (struct nfs_mount_data *)options;
 
-       memset(args, 0, sizeof(*args));
-
        if (data == NULL)
                goto out_no_data;
 
@@ -1251,13 +1249,13 @@ static int nfs_validate_mount_data(void *options,
        case 5:
                memset(data->context, 0, sizeof(data->context));
        case 6:
-               if (data->flags & NFS_MOUNT_VER3)
+               if (data->flags & NFS_MOUNT_VER3) {
+                       if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
+                               goto out_invalid_fh;
                        mntfh->size = data->root.size;
-               else
+               else
                        mntfh->size = NFS2_FHSIZE;
 
-               if (mntfh->size > sizeof(mntfh->data))
-                       goto out_invalid_fh;
 
                memcpy(mntfh->data, data->root.data, mntfh->size);
                if (mntfh->size < sizeof(mntfh->data))
@@ -1585,24 +1583,29 @@ static int nfs_get_sb(struct file_system_type *fs_type,
 {
        struct nfs_server *server = NULL;
        struct super_block *s;
-       struct nfs_fh mntfh;
-       struct nfs_parsed_mount_data data;
+       struct nfs_parsed_mount_data *data;
+       struct nfs_fh *mntfh;
        struct dentry *mntroot;
        int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
        struct nfs_sb_mountdata sb_mntdata = {
                .mntflags = flags,
        };
-       int error;
+       int error = -ENOMEM;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
+       if (data == NULL || mntfh == NULL)
+               goto out_free_fh;
 
-       security_init_mnt_opts(&data.lsm_opts);
+       security_init_mnt_opts(&data->lsm_opts);
 
        /* Validate the mount data */
-       error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
+       error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
        if (error < 0)
                goto out;
 
        /* Get a volume representation */
-       server = nfs_create_server(&data, &mntfh);
+       server = nfs_create_server(data, mntfh);
        if (IS_ERR(server)) {
                error = PTR_ERR(server);
                goto out;
@@ -1630,16 +1633,16 @@ static int nfs_get_sb(struct file_system_type *fs_type,
 
        if (!s->s_root) {
                /* initial superblock/root creation */
-               nfs_fill_super(s, &data);
+               nfs_fill_super(s, data);
        }
 
-       mntroot = nfs_get_root(s, &mntfh);
+       mntroot = nfs_get_root(s, mntfh);
        if (IS_ERR(mntroot)) {
                error = PTR_ERR(mntroot);
                goto error_splat_super;
        }
 
-       error = security_sb_set_mnt_opts(s, &data.lsm_opts);
+       error = security_sb_set_mnt_opts(s, &data->lsm_opts);
        if (error)
                goto error_splat_root;
 
@@ -1649,9 +1652,12 @@ static int nfs_get_sb(struct file_system_type *fs_type,
        error = 0;
 
 out:
-       kfree(data.nfs_server.hostname);
-       kfree(data.mount_server.hostname);
-       security_free_mnt_opts(&data.lsm_opts);
+       kfree(data->nfs_server.hostname);
+       kfree(data->mount_server.hostname);
+       security_free_mnt_opts(&data->lsm_opts);
+out_free_fh:
+       kfree(mntfh);
+       kfree(data);
        return error;
 
 out_err_nosb:
@@ -1800,8 +1806,6 @@ static int nfs4_validate_mount_data(void *options,
        struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
        char *c;
 
-       memset(args, 0, sizeof(*args));
-
        if (data == NULL)
                goto out_no_data;
 
@@ -1959,26 +1963,31 @@ out_no_client_address:
 static int nfs4_get_sb(struct file_system_type *fs_type,
        int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
 {
-       struct nfs_parsed_mount_data data;
+       struct nfs_parsed_mount_data *data;
        struct super_block *s;
        struct nfs_server *server;
-       struct nfs_fh mntfh;
+       struct nfs_fh *mntfh;
        struct dentry *mntroot;
        int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
        struct nfs_sb_mountdata sb_mntdata = {
                .mntflags = flags,
        };
-       int error;
+       int error = -ENOMEM;
 
-       security_init_mnt_opts(&data.lsm_opts);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
+       if (data == NULL || mntfh == NULL)
+               goto out_free_fh;
+
+       security_init_mnt_opts(&data->lsm_opts);
 
        /* Validate the mount data */
-       error = nfs4_validate_mount_data(raw_data, &data, dev_name);
+       error = nfs4_validate_mount_data(raw_data, data, dev_name);
        if (error < 0)
                goto out;
 
        /* Get a volume representation */
-       server = nfs4_create_server(&data, &mntfh);
+       server = nfs4_create_server(data, mntfh);
        if (IS_ERR(server)) {
                error = PTR_ERR(server);
                goto out;
@@ -2009,13 +2018,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
                nfs4_fill_super(s);
        }
 
-       mntroot = nfs4_get_root(s, &mntfh);
+       mntroot = nfs4_get_root(s, mntfh);
        if (IS_ERR(mntroot)) {
                error = PTR_ERR(mntroot);
                goto error_splat_super;
        }
 
-       error = security_sb_set_mnt_opts(s, &data.lsm_opts);
+       error = security_sb_set_mnt_opts(s, &data->lsm_opts);
        if (error)
                goto error_splat_root;
 
@@ -2025,10 +2034,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
        error = 0;
 
 out:
-       kfree(data.client_address);
-       kfree(data.nfs_server.export_path);
-       kfree(data.nfs_server.hostname);
-       security_free_mnt_opts(&data.lsm_opts);
+       kfree(data->client_address);
+       kfree(data->nfs_server.export_path);
+       kfree(data->nfs_server.hostname);
+       security_free_mnt_opts(&data->lsm_opts);
+out_free_fh:
+       kfree(mntfh);
+       kfree(data);
        return error;
 
 out_free:
index 6d8ace3e3259d9f643fbf1e92fc3c4f1c4dc40f0..f333848fd3be29a010dfee8116e4978cd8655b57 100644 (file)
@@ -739,12 +739,13 @@ int nfs_updatepage(struct file *file, struct page *page,
        }
 
        status = nfs_writepage_setup(ctx, page, offset, count);
-       __set_page_dirty_nobuffers(page);
+       if (status < 0)
+               nfs_set_pageerror(page);
+       else
+               __set_page_dirty_nobuffers(page);
 
         dprintk("NFS:      nfs_updatepage returns %d (isize %Ld)\n",
                        status, (long long)i_size_read(inode));
-       if (status < 0)
-               nfs_set_pageerror(page);
        return status;
 }
 
index ec228bc9f8824128ea99c5cb24abc743063e00bb..700f4e0d9572170a4de51527bc1698768a848afe 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1003,8 +1003,7 @@ struct file *create_write_pipe(void)
 void free_write_pipe(struct file *f)
 {
        free_pipe_info(f->f_dentry->d_inode);
-       dput(f->f_path.dentry);
-       mntput(f->f_path.mnt);
+       path_put(&f->f_path);
        put_filp(f);
 }
 
@@ -1015,8 +1014,8 @@ struct file *create_read_pipe(struct file *wrf)
                return ERR_PTR(-ENFILE);
 
        /* Grab pipe from the writer */
-       f->f_path.mnt = mntget(wrf->f_path.mnt);
-       f->f_path.dentry = dget(wrf->f_path.dentry);
+       f->f_path = wrf->f_path;
+       path_get(&wrf->f_path);
        f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping;
 
        f->f_pos = 0;
@@ -1068,8 +1067,7 @@ int do_pipe(int *fd)
  err_fdr:
        put_unused_fd(fdr);
  err_read_pipe:
-       dput(fr->f_dentry);
-       mntput(fr->f_vfsmnt);
+       path_put(&fr->f_path);
        put_filp(fr);
  err_write_pipe:
        free_write_pipe(fw);
index 8dda969614a9163f602fa62dca53a411c3400136..da0e88201c3a03bfa7e44eea8805a62dcd540539 100644 (file)
@@ -249,7 +249,6 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
                                                retval++;
                                        }
                                }
-                               cond_resched();
                        }
                        if (res_in)
                                *rinp = res_in;
@@ -257,6 +256,7 @@ int do_select(int n, fd_set_bits *fds, s64 *timeout)
                                *routp = res_out;
                        if (res_ex)
                                *rexp = res_ex;
+                       cond_resched();
                }
                wait = NULL;
                if (retval || !*timeout || signal_pending(current))
index 7a5f69be6ac2127de968661bd6d5e134712940b3..44cc702f96cc994919170bbee7621c841347b0ea 100644 (file)
@@ -682,38 +682,26 @@ static int udf_vrs(struct super_block *sb, int silent)
 /*
  * Check whether there is an anchor block in the given block
  */
-static int udf_check_anchor_block(struct super_block *sb, sector_t block,
-                                       bool varconv)
+static int udf_check_anchor_block(struct super_block *sb, sector_t block)
 {
-       struct buffer_head *bh = NULL;
-       tag *t;
+       struct buffer_head *bh;
        uint16_t ident;
-       uint32_t location;
 
-       if (varconv) {
-               if (udf_fixed_to_variable(block) >=
-                   sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
-                       return 0;
-               bh = sb_bread(sb, udf_fixed_to_variable(block));
-       }
-       else
-               bh = sb_bread(sb, block);
+       if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
+           udf_fixed_to_variable(block) >=
+           sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
+               return 0;
 
+       bh = udf_read_tagged(sb, block, block, &ident);
        if (!bh)
                return 0;
-
-       t = (tag *)bh->b_data;
-       ident = le16_to_cpu(t->tagIdent);
-       location = le32_to_cpu(t->tagLocation);
        brelse(bh);
-       if (ident != TAG_IDENT_AVDP)
-               return 0;
-       return location == block;
+
+       return ident == TAG_IDENT_AVDP;
 }
 
 /* Search for an anchor volume descriptor pointer */
-static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
-                                       sector_t lastblock)
+static sector_t udf_scan_anchors(struct super_block *sb, sector_t lastblock)
 {
        sector_t last[6];
        int i;
@@ -739,7 +727,7 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
                                sb->s_blocksize_bits)
                        continue;
 
-               if (udf_check_anchor_block(sb, last[i], varconv)) {
+               if (udf_check_anchor_block(sb, last[i])) {
                        sbi->s_anchor[0] = last[i];
                        sbi->s_anchor[1] = last[i] - 256;
                        return last[i];
@@ -748,17 +736,17 @@ static sector_t udf_scan_anchors(struct super_block *sb, bool varconv,
                if (last[i] < 256)
                        continue;
 
-               if (udf_check_anchor_block(sb, last[i] - 256, varconv)) {
+               if (udf_check_anchor_block(sb, last[i] - 256)) {
                        sbi->s_anchor[1] = last[i] - 256;
                        return last[i];
                }
        }
 
-       if (udf_check_anchor_block(sb, sbi->s_session + 256, varconv)) {
+       if (udf_check_anchor_block(sb, sbi->s_session + 256)) {
                sbi->s_anchor[0] = sbi->s_session + 256;
                return last[0];
        }
-       if (udf_check_anchor_block(sb, sbi->s_session + 512, varconv)) {
+       if (udf_check_anchor_block(sb, sbi->s_session + 512)) {
                sbi->s_anchor[0] = sbi->s_session + 512;
                return last[0];
        }
@@ -780,23 +768,24 @@ static void udf_find_anchor(struct super_block *sb)
        int i;
        struct udf_sb_info *sbi = UDF_SB(sb);
 
-       lastblock = udf_scan_anchors(sb, 0, sbi->s_last_block);
+       lastblock = udf_scan_anchors(sb, sbi->s_last_block);
        if (lastblock)
                goto check_anchor;
 
        /* No anchor found? Try VARCONV conversion of block numbers */
+       UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
        /* Firstly, we try to not convert number of the last block */
-       lastblock = udf_scan_anchors(sb, 1,
+       lastblock = udf_scan_anchors(sb,
                                udf_variable_to_fixed(sbi->s_last_block));
-       if (lastblock) {
-               UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+       if (lastblock)
                goto check_anchor;
-       }
 
        /* Secondly, we try with converted number of the last block */
-       lastblock = udf_scan_anchors(sb, 1, sbi->s_last_block);
-       if (lastblock)
-               UDF_SET_FLAG(sb, UDF_FLAG_VARCONV);
+       lastblock = udf_scan_anchors(sb, sbi->s_last_block);
+       if (!lastblock) {
+               /* VARCONV didn't help. Clear it. */
+               UDF_CLEAR_FLAG(sb, UDF_FLAG_VARCONV);
+       }
 
 check_anchor:
        /*
index af059d5cb485df8289eda123380f4937c0c7b77c..b6b664e7145ec7e0debea47c041b7c3faa9a0aee 100644 (file)
@@ -40,14 +40,9 @@ asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times)
 
 #endif
 
-static bool nsec_special(long nsec)
-{
-       return nsec == UTIME_OMIT || nsec == UTIME_NOW;
-}
-
 static bool nsec_valid(long nsec)
 {
-       if (nsec_special(nsec))
+       if (nsec == UTIME_OMIT || nsec == UTIME_NOW)
                return true;
 
        return nsec >= 0 && nsec <= 999999999;
@@ -102,7 +97,11 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
        if (error)
                goto dput_and_out;
 
-       /* Don't worry, the checks are done in inode_change_ok() */
+       if (times && times[0].tv_nsec == UTIME_NOW &&
+                    times[1].tv_nsec == UTIME_NOW)
+               times = NULL;
+
+       /* In most cases, the checks are done in inode_change_ok() */
        newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
        if (times) {
                error = -EPERM;
@@ -124,28 +123,34 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
                        newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
                        newattrs.ia_valid |= ATTR_MTIME_SET;
                }
-       }
 
-       /*
-        * If times is NULL or both times are either UTIME_OMIT or
-        * UTIME_NOW, then need to check permissions, because
-        * inode_change_ok() won't do it.
-        */
-       if (!times || (nsec_special(times[0].tv_nsec) &&
-                      nsec_special(times[1].tv_nsec))) {
+               /*
+                * For the UTIME_OMIT/UTIME_NOW and UTIME_NOW/UTIME_OMIT
+                * cases, we need to make an extra check that is not done by
+                * inode_change_ok().
+                */
+               if (((times[0].tv_nsec == UTIME_NOW &&
+                           times[1].tv_nsec == UTIME_OMIT)
+                    ||
+                    (times[0].tv_nsec == UTIME_OMIT &&
+                           times[1].tv_nsec == UTIME_NOW))
+                   && !is_owner_or_cap(inode))
+                       goto mnt_drop_write_and_out;
+       } else {
+
+               /*
+                * If times is NULL (or both times are UTIME_NOW),
+                * then we need to check permissions, because
+                * inode_change_ok() won't do it.
+                */
                error = -EACCES;
                 if (IS_IMMUTABLE(inode))
                        goto mnt_drop_write_and_out;
 
                if (!is_owner_or_cap(inode)) {
-                       if (f) {
-                               if (!(f->f_mode & FMODE_WRITE))
-                                       goto mnt_drop_write_and_out;
-                       } else {
-                               error = vfs_permission(&nd, MAY_WRITE);
-                               if (error)
-                                       goto mnt_drop_write_and_out;
-                       }
+                       error = permission(inode, MAY_WRITE, NULL);
+                       if (error)
+                               goto mnt_drop_write_and_out;
                }
        }
        mutex_lock(&inode->i_mutex);
@@ -169,14 +174,6 @@ asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __
        if (utimes) {
                if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
                        return -EFAULT;
-               if ((tstimes[0].tv_nsec == UTIME_OMIT ||
-                    tstimes[0].tv_nsec == UTIME_NOW) &&
-                   tstimes[0].tv_sec != 0)
-                       return -EINVAL;
-               if ((tstimes[1].tv_nsec == UTIME_OMIT ||
-                    tstimes[1].tv_nsec == UTIME_NOW) &&
-                   tstimes[1].tv_sec != 0)
-                       return -EINVAL;
 
                /* Nothing to do, we must not even check the path.  */
                if (tstimes[0].tv_nsec == UTIME_OMIT &&
index 525b4f6a7ace816784b504de4d89373a6a0d6233..acf55b48347207550edadb3691081bf1df1d251e 100644 (file)
@@ -261,7 +261,7 @@ struct el_MCPCIA_uncorrected_frame_mcheck {
        }
 #endif
 
-static inline int __mcpcia_is_mmio(unsigned long addr)
+extern inline int __mcpcia_is_mmio(unsigned long addr)
 {
        return (addr & 0x80000000UL) == 0;
 }
index 90e6b5d6c2143d8ab23e13b596803e52fec1411f..46bfff58f67093877e4815a30c6c165d9be192d3 100644 (file)
@@ -356,13 +356,13 @@ struct el_t2_frame_corrected {
 #define vip    volatile int *
 #define vuip   volatile unsigned int *
 
-static inline u8 t2_inb(unsigned long addr)
+extern inline u8 t2_inb(unsigned long addr)
 {
        long result = *(vip) ((addr << 5) + T2_IO + 0x00);
        return __kernel_extbl(result, addr & 3);
 }
 
-static inline void t2_outb(u8 b, unsigned long addr)
+extern inline void t2_outb(u8 b, unsigned long addr)
 {
        unsigned long w;
 
@@ -371,13 +371,13 @@ static inline void t2_outb(u8 b, unsigned long addr)
        mb();
 }
 
-static inline u16 t2_inw(unsigned long addr)
+extern inline u16 t2_inw(unsigned long addr)
 {
        long result = *(vip) ((addr << 5) + T2_IO + 0x08);
        return __kernel_extwl(result, addr & 3);
 }
 
-static inline void t2_outw(u16 b, unsigned long addr)
+extern inline void t2_outw(u16 b, unsigned long addr)
 {
        unsigned long w;
 
@@ -386,12 +386,12 @@ static inline void t2_outw(u16 b, unsigned long addr)
        mb();
 }
 
-static inline u32 t2_inl(unsigned long addr)
+extern inline u32 t2_inl(unsigned long addr)
 {
        return *(vuip) ((addr << 5) + T2_IO + 0x18);
 }
 
-static inline void t2_outl(u32 b, unsigned long addr)
+extern inline void t2_outl(u32 b, unsigned long addr)
 {
        *(vuip) ((addr << 5) + T2_IO + 0x18) = b;
        mb();
@@ -435,7 +435,7 @@ static inline void t2_outl(u32 b, unsigned long addr)
        set_hae(msb); \
 }
 
-static DEFINE_SPINLOCK(t2_hae_lock);
+extern spinlock_t t2_hae_lock;
 
 /*
  * NOTE: take T2_DENSE_MEM off in each readX/writeX routine, since
index 38f18cf18c9d0e99ae5f353893379923193c6b1b..e971ab000f9519c18cda4df33f26182d377aafa2 100644 (file)
@@ -35,7 +35,7 @@
  * register not being up-to-date with respect to the hardware
  * value.
  */
-static inline void __set_hae(unsigned long new_hae)
+extern inline void __set_hae(unsigned long new_hae)
 {
        unsigned long flags;
        local_irq_save(flags);
@@ -49,7 +49,7 @@ static inline void __set_hae(unsigned long new_hae)
        local_irq_restore(flags);
 }
 
-static inline void set_hae(unsigned long new_hae)
+extern inline void set_hae(unsigned long new_hae)
 {
        if (new_hae != alpha_mv.hae_cache)
                __set_hae(new_hae);
@@ -176,7 +176,7 @@ REMAP2(u64, writeq, volatile)
 #undef REMAP1
 #undef REMAP2
 
-static inline void __iomem *generic_ioportmap(unsigned long a)
+extern inline void __iomem *generic_ioportmap(unsigned long a)
 {
        return alpha_mv.mv_ioportmap(a);
 }
index 6a5be1f7debf3a941c3c4db049459cacd019253f..86c08a02d2393fe3dc49bacbd6eec3e2e11a2f69 100644 (file)
@@ -23,7 +23,7 @@
 #endif
 
 
-extern inline unsigned long
+static inline unsigned long
 __reload_thread(struct pcb_struct *pcb)
 {
        register unsigned long a0 __asm__("$16");
@@ -114,7 +114,7 @@ extern unsigned long last_asn;
 #define __MMU_EXTERN_INLINE
 #endif
 
-static inline unsigned long
+extern inline unsigned long
 __get_new_mm_context(struct mm_struct *mm, long cpu)
 {
        unsigned long asn = cpu_last_asn(cpu);
@@ -226,7 +226,7 @@ ev4_activate_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm)
 # endif
 #endif
 
-extern inline int
+static inline int
 init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
        int i;
index 48348fe34c19bc5b6ace3fbfe7a88838033577c9..3495e8e00d70fd2ca96531e702b1956a3aa5f5de 100644 (file)
@@ -1,6 +1,78 @@
 #ifndef __ALPHA_PERCPU_H
 #define __ALPHA_PERCPU_H
+#include <linux/compiler.h>
+#include <linux/threads.h>
 
-#include <asm-generic/percpu.h>
+/*
+ * Determine the real variable name from the name visible in the
+ * kernel sources.
+ */
+#define per_cpu_var(var) per_cpu__##var
+
+#ifdef CONFIG_SMP
+
+/*
+ * per_cpu_offset() is the offset that has to be added to a
+ * percpu variable to get to the instance for a certain processor.
+ */
+extern unsigned long __per_cpu_offset[NR_CPUS];
+
+#define per_cpu_offset(x) (__per_cpu_offset[x])
+
+#define __my_cpu_offset per_cpu_offset(raw_smp_processor_id())
+#ifdef CONFIG_DEBUG_PREEMPT
+#define my_cpu_offset per_cpu_offset(smp_processor_id())
+#else
+#define my_cpu_offset __my_cpu_offset
+#endif
+
+#ifndef MODULE
+#define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset))
+#define PER_CPU_ATTRIBUTES
+#else
+/*
+ * To calculate addresses of locally defined variables, GCC uses 32-bit
+ * displacement from the GP. Which doesn't work for per cpu variables in
+ * modules, as an offset to the kernel per cpu area is way above 4G.
+ *
+ * This forces allocation of a GOT entry for per cpu variable using
+ * ldq instruction with a 'literal' relocation.
+ */
+#define SHIFT_PERCPU_PTR(var, offset) ({               \
+       extern int simple_identifier_##var(void);       \
+       unsigned long __ptr, tmp_gp;                    \
+       asm (  "br      %1, 1f                        \n\
+       1:      ldgp    %1, 0(%1)                     \n\
+               ldq %0, per_cpu__" #var"(%1)\t!literal"         \
+               : "=&r"(__ptr), "=&r"(tmp_gp));         \
+       (typeof(&per_cpu_var(var)))(__ptr + (offset)); })
+
+#define PER_CPU_ATTRIBUTES     __used
+
+#endif /* MODULE */
+
+/*
+ * A percpu variable may point to a discarded regions. The following are
+ * established ways to produce a usable pointer from the percpu variable
+ * offset.
+ */
+#define per_cpu(var, cpu) \
+       (*SHIFT_PERCPU_PTR(var, per_cpu_offset(cpu)))
+#define __get_cpu_var(var) \
+       (*SHIFT_PERCPU_PTR(var, my_cpu_offset))
+#define __raw_get_cpu_var(var) \
+       (*SHIFT_PERCPU_PTR(var, __my_cpu_offset))
+
+#else /* ! SMP */
+
+#define per_cpu(var, cpu)              (*((void)(cpu), &per_cpu_var(var)))
+#define __get_cpu_var(var)             per_cpu_var(var)
+#define __raw_get_cpu_var(var)         per_cpu_var(var)
+
+#define PER_CPU_ATTRIBUTES
+
+#endif /* SMP */
+
+#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name)
 
 #endif /* __ALPHA_PERCPU_H */
index ed221d6408fc308acbf737d84ba51adb9899dc28..afe20fa58c990927fd10c5e94d41fe4d8d9eee8a 100644 (file)
@@ -184,7 +184,7 @@ enum amask_enum {
    __amask; })
 
 #define __CALL_PAL_R0(NAME, TYPE)                              \
-static inline TYPE NAME(void)                                  \
+extern inline TYPE NAME(void)                                  \
 {                                                              \
        register TYPE __r0 __asm__("$0");                       \
        __asm__ __volatile__(                                   \
@@ -196,7 +196,7 @@ static inline TYPE NAME(void)                                       \
 }
 
 #define __CALL_PAL_W1(NAME, TYPE0)                             \
-static inline void NAME(TYPE0 arg0)                            \
+extern inline void NAME(TYPE0 arg0)                            \
 {                                                              \
        register TYPE0 __r16 __asm__("$16") = arg0;             \
        __asm__ __volatile__(                                   \
@@ -207,7 +207,7 @@ static inline void NAME(TYPE0 arg0)                         \
 }
 
 #define __CALL_PAL_W2(NAME, TYPE0, TYPE1)                      \
-static inline void NAME(TYPE0 arg0, TYPE1 arg1)                        \
+extern inline void NAME(TYPE0 arg0, TYPE1 arg1)                        \
 {                                                              \
        register TYPE0 __r16 __asm__("$16") = arg0;             \
        register TYPE1 __r17 __asm__("$17") = arg1;             \
@@ -219,7 +219,7 @@ static inline void NAME(TYPE0 arg0, TYPE1 arg1)                     \
 }
 
 #define __CALL_PAL_RW1(NAME, RTYPE, TYPE0)                     \
-static inline RTYPE NAME(TYPE0 arg0)                           \
+extern inline RTYPE NAME(TYPE0 arg0)                           \
 {                                                              \
        register RTYPE __r0 __asm__("$0");                      \
        register TYPE0 __r16 __asm__("$16") = arg0;             \
@@ -232,7 +232,7 @@ static inline RTYPE NAME(TYPE0 arg0)                                \
 }
 
 #define __CALL_PAL_RW2(NAME, RTYPE, TYPE0, TYPE1)              \
-static inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1)               \
+extern inline RTYPE NAME(TYPE0 arg0, TYPE1 arg1)               \
 {                                                              \
        register RTYPE __r0 __asm__("$0");                      \
        register TYPE0 __r16 __asm__("$16") = arg0;             \
index e8df1e7aae6b39155c6cdf625e2549aef6d97627..c00106bac52146745a5b128e7e05b1e1480e8400 100644 (file)
@@ -13,7 +13,7 @@
 #define VT_BUF_HAVE_MEMSETW
 #define VT_BUF_HAVE_MEMCPYW
 
-extern inline void scr_writew(u16 val, volatile u16 *addr)
+static inline void scr_writew(u16 val, volatile u16 *addr)
 {
        if (__is_ioaddr(addr))
                __raw_writew(val, (volatile u16 __iomem *) addr);
@@ -21,7 +21,7 @@ extern inline void scr_writew(u16 val, volatile u16 *addr)
                *addr = val;
 }
 
-extern inline u16 scr_readw(volatile const u16 *addr)
+static inline u16 scr_readw(volatile const u16 *addr)
 {
        if (__is_ioaddr(addr))
                return __raw_readw((volatile const u16 __iomem *) addr);
@@ -29,7 +29,7 @@ extern inline u16 scr_readw(volatile const u16 *addr)
                return *addr;
 }
 
-extern inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
+static inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
 {
        if (__is_ioaddr(s))
                memsetw_io((u16 __iomem *) s, c, count);
index 96bd09e31e3612b187bb931ad60b05008fa792e8..2526b6ed6faa78ce72d45d9e210743c589850f8e 100644 (file)
@@ -96,7 +96,7 @@ struct bfin_serial_port {
        struct work_struct tx_dma_workqueue;
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct cts_workqueue;
+       struct timer_list cts_timer;
        int cts_pin;
        int rts_pin;
 #endif
index e924569ad1d8a668ba17685bb1b0ffa9b8b1f85a..ebf592b59aab4b88a1d790f013f86535d55ccfeb 100644 (file)
@@ -88,7 +88,7 @@ struct bfin_serial_port {
 # endif
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int                     cts_pin;
        int                     rts_pin;
 #endif
index 41d7b6490bb11b608303faa85a5ea6cdd439633f..1bf56ffa22f946236dfcfad9d14b27db6e26d090 100644 (file)
@@ -96,7 +96,7 @@ struct bfin_serial_port {
        struct work_struct      tx_dma_workqueue;
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int             cts_pin;
        int             rts_pin;
 #endif
index 59b4ad4e5b4a0dc0bb3bbb8e163cebb9ca1efbf2..5e29446a8e03dde1acbf65bcc136a8cb83f5f60a 100644 (file)
@@ -99,7 +99,7 @@ struct bfin_serial_port {
        struct work_struct      tx_dma_workqueue;
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int             cts_pin;
        int             rts_pin;
 #endif
@@ -187,7 +187,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 
 #ifdef CONFIG_BFIN_UART1_CTSRTS
        peripheral_request(P_UART1_RTS, DRIVER_NAME);
-       peripheral_request(P_UART1_CTS DRIVER_NAME);
+       peripheral_request(P_UART1_CTS, DRIVER_NAME);
 #endif
 #endif
 
@@ -202,7 +202,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
 
 #ifdef CONFIG_BFIN_UART3_CTSRTS
        peripheral_request(P_UART3_RTS, DRIVER_NAME);
-       peripheral_request(P_UART3_CTS DRIVER_NAME);
+       peripheral_request(P_UART3_CTS, DRIVER_NAME);
 #endif
 #endif
        SSYNC();
index 30d90b580f186cfed41520d3351dc47310eaca8d..8aa02780e642ccde6deee3e79b4fe401d481902d 100644 (file)
@@ -88,7 +88,7 @@ struct bfin_serial_port {
 # endif
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
-       struct work_struct      cts_workqueue;
+       struct timer_list       cts_timer;
        int                     cts_pin;
        int                     rts_pin;
 #endif
index 92a6d91d0c1adb1d6974c0fb863917d77c396ed6..7cd25b8e7c9a4b891fcf00fd60b3985e5d48c59e 100644 (file)
@@ -1,6 +1,6 @@
 header-y  += kvm.h
 
-ifeq ($(wildcard include/asm-$(SRCARCH)/a.out.h),include/asm-$(SRCARCH)/a.out.h)
+ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
 unifdef-y += a.out.h
 endif
 unifdef-y += auxvec.h
index 7381916dfcbb298a8e1e6e66628b5b6c5a2de6fa..bca352e033c39ff78c2adf71c6f1038e3620eaaf 100644 (file)
@@ -1,6 +1,5 @@
 include include/asm-generic/Kbuild.asm
 
-header-y += a.out.h
 header-y += auxvec.h
 header-y += ioctls.h
 header-y += mman.h
index 1d8cd01fa5147221ccf6e598b8d8f0d3a100bf3e..844f2a89afbcdb28a8a6272fd9826b8a24777351 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/kvm_para.h>
 #include <linux/kvm_types.h>
 
+#include <asm/pvclock-abi.h>
 #include <asm/desc.h>
 
 #define KVM_MAX_VCPUS 16
@@ -282,7 +283,8 @@ struct kvm_vcpu_arch {
        struct x86_emulate_ctxt emulate_ctxt;
 
        gpa_t time;
-       struct kvm_vcpu_time_info hv_clock;
+       struct pvclock_vcpu_time_info hv_clock;
+       unsigned int hv_clock_tsc_khz;
        unsigned int time_offset;
        struct page *time_page;
 };
index 5098459420705ea53f41c2d05b0a91b688980334..bfd9900742bfe77426bbf50977cec8594c752b0d 100644 (file)
@@ -48,24 +48,6 @@ struct kvm_mmu_op_release_pt {
 #ifdef __KERNEL__
 #include <asm/processor.h>
 
-/* xen binary-compatible interface. See xen headers for details */
-struct kvm_vcpu_time_info {
-       uint32_t version;
-       uint32_t pad0;
-       uint64_t tsc_timestamp;
-       uint64_t system_time;
-       uint32_t tsc_to_system_mul;
-       int8_t   tsc_shift;
-       int8_t   pad[3];
-} __attribute__((__packed__)); /* 32 bytes */
-
-struct kvm_wall_clock {
-       uint32_t wc_version;
-       uint32_t wc_sec;
-       uint32_t wc_nsec;
-} __attribute__((__packed__));
-
-
 extern void kvmclock_init(void);
 
 
diff --git a/include/asm-x86/pvclock-abi.h b/include/asm-x86/pvclock-abi.h
new file mode 100644 (file)
index 0000000..6857f84
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef _ASM_X86_PVCLOCK_ABI_H_
+#define _ASM_X86_PVCLOCK_ABI_H_
+#ifndef __ASSEMBLY__
+
+/*
+ * These structs MUST NOT be changed.
+ * They are the ABI between hypervisor and guest OS.
+ * Both Xen and KVM are using this.
+ *
+ * pvclock_vcpu_time_info holds the system time and the tsc timestamp
+ * of the last update. So the guest can use the tsc delta to get a
+ * more precise system time.  There is one per virtual cpu.
+ *
+ * pvclock_wall_clock references the point in time when the system
+ * time was zero (usually boot time), thus the guest calculates the
+ * current wall clock by adding the system time.
+ *
+ * Protocol for the "version" fields is: hypervisor raises it (making
+ * it uneven) before it starts updating the fields and raises it again
+ * (making it even) when it is done.  Thus the guest can make sure the
+ * time values it got are consistent by checking the version before
+ * and after reading them.
+ */
+
+struct pvclock_vcpu_time_info {
+       u32   version;
+       u32   pad0;
+       u64   tsc_timestamp;
+       u64   system_time;
+       u32   tsc_to_system_mul;
+       s8    tsc_shift;
+       u8    pad[3];
+} __attribute__((__packed__)); /* 32 bytes */
+
+struct pvclock_wall_clock {
+       u32   version;
+       u32   sec;
+       u32   nsec;
+} __attribute__((__packed__));
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_PVCLOCK_ABI_H_ */
diff --git a/include/asm-x86/pvclock.h b/include/asm-x86/pvclock.h
new file mode 100644 (file)
index 0000000..85b1bba
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _ASM_X86_PVCLOCK_H_
+#define _ASM_X86_PVCLOCK_H_
+
+#include <linux/clocksource.h>
+#include <asm/pvclock-abi.h>
+
+/* some helper functions for xen and kvm pv clock sources */
+cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
+void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
+                           struct pvclock_vcpu_time_info *vcpu,
+                           struct timespec *ts);
+
+#endif /* _ASM_X86_PVCLOCK_H_ */
index b6fbb2573e8872a6496fdd1c75ee65a864a9395f..71d70d1fbce280585d575ba3f131847c0da19cd8 100644 (file)
@@ -166,7 +166,7 @@ unifdef-y += acct.h
 unifdef-y += adb.h
 unifdef-y += adfs_fs.h
 unifdef-y += agpgart.h
-ifeq ($(wildcard include/asm-$(SRCARCH)/a.out.h),include/asm-$(SRCARCH)/a.out.h)
+ifneq ($(wildcard $(srctree)/include/asm-$(SRCARCH)/a.out.h),)
 unifdef-y += a.out.h
 endif
 unifdef-y += apm_bios.h
index 63c3bb98558f6b3e2d07cd9040621273966c1eec..8b82974bdc125b561bf156a1dbfa58d3a51e3751 100644 (file)
@@ -571,7 +571,7 @@ extern void             audit_log_lost(const char *message);
 extern int                 audit_update_lsm_rules(void);
 
                                /* Private API (for audit.c only) */
-extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
+extern int audit_filter_user(struct netlink_skb_parms *cb);
 extern int audit_filter_type(int type);
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
                                void *data, size_t datasz, uid_t loginuid,
index 6a5dbdc8a7dcef7fc265f5d68c7dbe91e42e92ad..686895bacd9dcc8500518d4bddc3629ec9533dd4 100644 (file)
@@ -94,7 +94,7 @@ extern unsigned long init_bootmem_node(pg_data_t *pgdat,
                                       unsigned long freepfn,
                                       unsigned long startpfn,
                                       unsigned long endpfn);
-extern void reserve_bootmem_node(pg_data_t *pgdat,
+extern int reserve_bootmem_node(pg_data_t *pgdat,
                                 unsigned long physaddr,
                                 unsigned long size,
                                 int flags);
index 2a6639407c8037581ce7baa58e95c8c936a26245..d982eb89c77d324a7875c1486ac421d7ecdfdae7 100644 (file)
@@ -300,7 +300,7 @@ extern int d_validate(struct dentry *, struct dentry *);
 extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
 
 extern char *__d_path(const struct path *path, struct path *root, char *, int);
-extern char *d_path(struct path *, char *, int);
+extern char *d_path(const struct path *, char *, int);
 extern char *dentry_path(struct dentry *, char *, int);
 
 /* Allocation counts.. */
index d490779f18d946e52d443148cb8501649aad9030..7c1080826832da855da0d099f6aab387f308fd7e 100644 (file)
@@ -894,8 +894,6 @@ static inline int file_check_writeable(struct file *filp)
 typedef struct files_struct *fl_owner_t;
 
 struct file_lock_operations {
-       void (*fl_insert)(struct file_lock *);  /* lock insertion callback */
-       void (*fl_remove)(struct file_lock *);  /* lock removal callback */
        void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
        void (*fl_release_private)(struct file_lock *);
 };
index 80335b7d77c5bea2d9f64320c46fb19dfcb60cc2..c4335faebb63eba7eb9771dc8f937b1fa82103ac 100644 (file)
@@ -84,7 +84,11 @@ struct net_lro_mgr {
                                    from received packets and eth protocol
                                    is still ETH_P_8021Q */
 
-       u32 ip_summed;      /* Set in non generated SKBs in page mode */
+       /*
+        * Set for generated SKBs that are not added to
+        * the frag list in fragmented mode
+        */
+       u32 ip_summed;
        u32 ip_summed_aggr; /* Set in aggregated SKBs: CHECKSUM_UNNECESSARY
                             * or CHECKSUM_NONE */
 
index e075c4b762fb367e0a3ad07227c440cb7500629e..d150c57e5f0af8653fc2ab96d3b1e3c3a17ec5b5 100644 (file)
@@ -534,8 +534,8 @@ struct input_absinfo {
 
 #define KEY_FRAMEBACK          0x1b4   /* Consumer - transport controls */
 #define KEY_FRAMEFORWARD       0x1b5
-
 #define KEY_CONTEXT_MENU       0x1b6   /* GenDesc - system context menu */
+#define KEY_MEDIA_REPEAT       0x1b7   /* Consumer - transport control */
 
 #define KEY_DEL_EOL            0x1c0
 #define KEY_DEL_EOS            0x1c1
index 092b1b25291daffb16f3de899e446f1adc24274a..de9d1df4bba21aa5eaebeb9e62d4a0c4cab69129 100644 (file)
@@ -33,6 +33,7 @@
 #define KVM_REQ_REPORT_TPR_ACCESS  2
 #define KVM_REQ_MMU_RELOAD         3
 #define KVM_REQ_TRIPLE_FAULT       4
+#define KVM_REQ_PENDING_TIMER      5
 
 struct kvm_vcpu;
 extern struct kmem_cache *kvm_vcpu_cache;
index f27fd2009334922325866c69d2abe42bb45bfd67..25f87102ab663e149e10043c9c399a8d8ca3bd96 100644 (file)
@@ -88,6 +88,8 @@ struct wireless_dev;
 #define NETDEV_TX_BUSY 1       /* driver tx path was busy*/
 #define NETDEV_TX_LOCKED -1    /* driver tx lock was already taken */
 
+#ifdef  __KERNEL__
+
 /*
  *     Compute the worst case header length according to the protocols
  *     used.
@@ -114,6 +116,8 @@ struct wireless_dev;
 #define MAX_HEADER (LL_MAX_HEADER + 48)
 #endif
 
+#endif  /*  __KERNEL__  */
+
 struct net_device_subqueue
 {
        /* Give a control state for each queue.  This struct may contain
index 06d3e6eb9ca84ddb19b85e862ab51bafbaf0ce4b..917707e6151d7d2c5e4e5c3e6bd2b4310f86d971 100644 (file)
@@ -66,8 +66,7 @@ struct thermal_cooling_device {
                                ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
 #define CELSIUS_TO_KELVIN(t)   ((t)*10+2732)
 
-#if defined(CONFIG_HWMON) ||   \
-       (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE))
+#if defined(CONFIG_THERMAL_HWMON)
 /* thermal zone devices with the same type share one hwmon device */
 struct thermal_hwmon_device {
        char type[THERMAL_NAME_LENGTH];
@@ -94,8 +93,7 @@ struct thermal_zone_device {
        struct idr idr;
        struct mutex lock;      /* protect cooling devices list */
        struct list_head node;
-#if defined(CONFIG_HWMON) ||   \
-       (defined(CONFIG_HWMON_MODULE) && defined(CONFIG_THERMAL_MODULE))
+#if defined(CONFIG_THERMAL_HWMON)
        struct list_head hwmon_node;
        struct thermal_hwmon_device *hwmon;
        struct thermal_hwmon_attr temp_input;   /* hwmon sys attr */
index 59f1c0bd8f9c6f8734a1320185a3eb28a9b29990..d2a003586761cbef8f5913ec49831c7cf41e7624 100644 (file)
@@ -27,8 +27,7 @@
  *     This routine is called by the kernel to write a series of
  *     characters to the tty device.  The characters may come from
  *     user space or kernel space.  This routine will return the
- *     number of characters actually accepted for writing.  This
- *     routine is mandatory.
+ *     number of characters actually accepted for writing.
  *
  *     Optional: Required for writable devices.
  *
  *     This routine notifies the tty driver that it should hangup the
  *     tty device.
  *
- *     Required:
+ *     Optional:
  *
  * void (*break_ctl)(struct tty_stuct *tty, int state);
  *
index cd599ad29fb2114b2b7e26ab46e613c8ea5ccff5..db431d513f2f01ce27cb9d150ed85f62f61d7195 100644 (file)
@@ -32,12 +32,16 @@ enum cx25840_video_input {
        CX25840_COMPOSITE7,
        CX25840_COMPOSITE8,
 
-       /* S-Video inputs consist of one luma input (In1-In4) ORed with one
+       /* S-Video inputs consist of one luma input (In1-In8) ORed with one
           chroma input (In5-In8) */
        CX25840_SVIDEO_LUMA1 = 0x10,
        CX25840_SVIDEO_LUMA2 = 0x20,
        CX25840_SVIDEO_LUMA3 = 0x30,
        CX25840_SVIDEO_LUMA4 = 0x40,
+       CX25840_SVIDEO_LUMA5 = 0x50,
+       CX25840_SVIDEO_LUMA6 = 0x60,
+       CX25840_SVIDEO_LUMA7 = 0x70,
+       CX25840_SVIDEO_LUMA8 = 0x80,
        CX25840_SVIDEO_CHROMA4 = 0x400,
        CX25840_SVIDEO_CHROMA5 = 0x500,
        CX25840_SVIDEO_CHROMA6 = 0x600,
index bfee8be5d63fb6b69765535a8384e928017b8b40..b8e8aa91905a4450bf3ff9c431e2ba7168092f1a 100644 (file)
@@ -146,6 +146,7 @@ extern IR_KEYTAB_TYPE ir_codes_behold_columbus[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_pinnacle_pctv_hd[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_genius_tvgo_a11mce[IR_KEYTAB_SIZE];
 extern IR_KEYTAB_TYPE ir_codes_powercolor_real_angel[IR_KEYTAB_SIZE];
+extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE];
 
 #endif
 
index 33f01ae08f767da78c532c257332391bfb48b88c..859f7a6f6f67ab0c5073deb703c928de9f614d2f 100644 (file)
@@ -40,9 +40,9 @@
 #define VFL_TYPE_VTX           3
 
 /*  Video standard functions  */
-extern char *v4l2_norm_to_name(v4l2_std_id id);
+extern const char *v4l2_norm_to_name(v4l2_std_id id);
 extern int v4l2_video_std_construct(struct v4l2_standard *vs,
-                                   int id, char *name);
+                                   int id, const char *name);
 /* Prints the ioctl in a human-readable format */
 extern void v4l_printk_ioctl(unsigned int cmd);
 
index e0a612bc9c4ef8f5bdb1a3b70a1685b153ca38fa..f422f7218e1c1d257c3a90d19dcc64853d3473ff 100644 (file)
@@ -367,6 +367,12 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
                 a->s6_addr32[2] | a->s6_addr32[3] ) == 0); 
 }
 
+static inline int ipv6_addr_loopback(const struct in6_addr *a)
+{
+       return ((a->s6_addr32[0] | a->s6_addr32[1] |
+                a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0);
+}
+
 static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
 {
        return ((a->s6_addr32[0] | a->s6_addr32[1] |
index dae3f9ec11549b240ae07be19dc4f58a2389ce62..bcd1623245cbfc09e879776beceeafeeee229fdc 100644 (file)
@@ -595,6 +595,15 @@ enum ieee80211_key_alg {
        ALG_CCMP,
 };
 
+/**
+ * enum ieee80211_key_len - key length
+ * @WEP40: WEP 5 byte long key
+ * @WEP104: WEP 13 byte long key
+ */
+enum ieee80211_key_len {
+       LEN_WEP40 = 5,
+       LEN_WEP104 = 13,
+};
 
 /**
  * enum ieee80211_key_flags - key flags
index aa540e6be502b49c5b7322e6ee57f630e6fa584a..d9dd0f7072969d7407c145f96d54d82a51c00d7a 100644 (file)
@@ -95,6 +95,11 @@ extern struct list_head net_namespace_list;
 #ifdef CONFIG_NET_NS
 extern void __put_net(struct net *net);
 
+static inline int net_alive(struct net *net)
+{
+       return net && atomic_read(&net->count);
+}
+
 static inline struct net *get_net(struct net *net)
 {
        atomic_inc(&net->count);
@@ -125,6 +130,12 @@ int net_eq(const struct net *net1, const struct net *net2)
        return net1 == net2;
 }
 #else
+
+static inline int net_alive(struct net *net)
+{
+       return 1;
+}
+
 static inline struct net *get_net(struct net *net)
 {
        return net;
index ab502ec1c61c3752b022b24ce49f833235b8621c..a87fc0312edc1a724560771980b06ac1a497daf3 100644 (file)
@@ -178,7 +178,7 @@ extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops);
 extern struct Qdisc *qdisc_create_dflt(struct net_device *dev,
                                       struct Qdisc_ops *ops, u32 parentid);
 extern void tcf_destroy(struct tcf_proto *tp);
-extern void tcf_destroy_chain(struct tcf_proto *fl);
+extern void tcf_destroy_chain(struct tcf_proto **fl);
 
 static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
                                       struct sk_buff_head *list)
index 9b018da48cf3145705af0a2f4f0b4228e8b1b889..819a0331cda9d440fd368f16d38941db371caa8c 100644 (file)
@@ -10,6 +10,7 @@
 #define __XEN_PUBLIC_XEN_H__
 
 #include <asm/xen/interface.h>
+#include <asm/pvclock-abi.h>
 
 /*
  * XEN "SYSTEM CALLS" (a.k.a. HYPERCALLS).
@@ -336,7 +337,7 @@ struct vcpu_info {
        uint8_t evtchn_upcall_mask;
        unsigned long evtchn_pending_sel;
        struct arch_vcpu_info arch;
-       struct vcpu_time_info time;
+       struct pvclock_vcpu_time_info time;
 }; /* 64 bytes (x86) */
 
 /*
@@ -384,9 +385,7 @@ struct shared_info {
         * Wallclock time: updated only by control software. Guests should base
         * their gettimeofday() syscall on this wallclock-base value.
         */
-       uint32_t wc_version;      /* Version counter: see vcpu_time_info_t. */
-       uint32_t wc_sec;          /* Secs  00:00:00 UTC, Jan 1, 1970.  */
-       uint32_t wc_nsec;         /* Nsecs 00:00:00 UTC, Jan 1, 1970.  */
+       struct pvclock_wall_clock wc;
 
        struct arch_shared_info arch;
 
index e8692a5748c24d2bd841ea7a81eaa09ae992bb04..e092f1c0ce3030916d9ad4c3af2b90fd64082f15 100644 (file)
@@ -738,7 +738,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                if (!audit_enabled && msg_type != AUDIT_USER_AVC)
                        return 0;
 
-               err = audit_filter_user(&NETLINK_CB(skb), msg_type);
+               err = audit_filter_user(&NETLINK_CB(skb));
                if (err == 1) {
                        err = 0;
                        if (msg_type == AUDIT_USER_TTY) {
@@ -779,7 +779,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                }
                /* fallthrough */
        case AUDIT_LIST:
-               err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
+               err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid,
                                           uid, seq, data, nlmsg_len(nlh),
                                           loginuid, sessionid, sid);
                break;
@@ -798,7 +798,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                }
                /* fallthrough */
        case AUDIT_LIST_RULES:
-               err = audit_receive_filter(nlh->nlmsg_type, NETLINK_CB(skb).pid,
+               err = audit_receive_filter(msg_type, NETLINK_CB(skb).pid,
                                           uid, seq, data, nlmsg_len(nlh),
                                           loginuid, sessionid, sid);
                break;
index 0e0bd27e65129ec94e087753ba398c42f92acc7e..98c50cc671bb85525f8534cc422bc692dbef5dc9 100644 (file)
@@ -1544,6 +1544,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid,
  * @data: payload data
  * @datasz: size of payload data
  * @loginuid: loginuid of sender
+ * @sessionid: sessionid for netlink audit message
  * @sid: SE Linux Security ID of sender
  */
 int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
@@ -1720,7 +1721,7 @@ static int audit_filter_user_rules(struct netlink_skb_parms *cb,
        return 1;
 }
 
-int audit_filter_user(struct netlink_skb_parms *cb, int type)
+int audit_filter_user(struct netlink_skb_parms *cb)
 {
        enum audit_state state = AUDIT_DISABLED;
        struct audit_entry *e;
index 039baa4cd90c1109a4c7e2bd382207242ab39f8f..9fceb97e989c25c82e438010437804774b892025 100644 (file)
@@ -1037,8 +1037,8 @@ int current_cpuset_is_being_rebound(void)
 
 static int update_relax_domain_level(struct cpuset *cs, s64 val)
 {
-       if ((int)val < 0)
-               val = -1;
+       if (val < -1 || val >= SD_LV_MAX)
+               return -EINVAL;
 
        if (val != cs->relax_domain_level) {
                cs->relax_domain_level = val;
@@ -1890,6 +1890,12 @@ static void common_cpu_mem_hotplug_unplug(void)
        top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
        scan_for_empty_cpusets(&top_cpuset);
 
+       /*
+        * Scheduler destroys domains on hotplug events.
+        * Rebuild them based on the current settings.
+        */
+       rebuild_sched_domains();
+
        cgroup_unlock();
 }
 
index 449def8074fea501f16371365c5721b173797164..7d1136e97c142d198b897dab1846acd99f1f655f 100644 (file)
@@ -1096,21 +1096,64 @@ static void unqueue_me_pi(struct futex_q *q)
  * private futexes.
  */
 static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
-                               struct task_struct *newowner)
+                               struct task_struct *newowner,
+                               struct rw_semaphore *fshared)
 {
        u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS;
        struct futex_pi_state *pi_state = q->pi_state;
+       struct task_struct *oldowner = pi_state->owner;
        u32 uval, curval, newval;
-       int ret;
+       int ret, attempt = 0;
 
        /* Owner died? */
+       if (!pi_state->owner)
+               newtid |= FUTEX_OWNER_DIED;
+
+       /*
+        * We are here either because we stole the rtmutex from the
+        * pending owner or we are the pending owner which failed to
+        * get the rtmutex. We have to replace the pending owner TID
+        * in the user space variable. This must be atomic as we have
+        * to preserve the owner died bit here.
+        *
+        * Note: We write the user space value _before_ changing the
+        * pi_state because we can fault here. Imagine swapped out
+        * pages or a fork, which was running right before we acquired
+        * mmap_sem, that marked all the anonymous memory readonly for
+        * cow.
+        *
+        * Modifying pi_state _before_ the user space value would
+        * leave the pi_state in an inconsistent state when we fault
+        * here, because we need to drop the hash bucket lock to
+        * handle the fault. This might be observed in the PID check
+        * in lookup_pi_state.
+        */
+retry:
+       if (get_futex_value_locked(&uval, uaddr))
+               goto handle_fault;
+
+       while (1) {
+               newval = (uval & FUTEX_OWNER_DIED) | newtid;
+
+               curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
+
+               if (curval == -EFAULT)
+                       goto handle_fault;
+               if (curval == uval)
+                       break;
+               uval = curval;
+       }
+
+       /*
+        * We fixed up user space. Now we need to fix the pi_state
+        * itself.
+        */
        if (pi_state->owner != NULL) {
                spin_lock_irq(&pi_state->owner->pi_lock);
                WARN_ON(list_empty(&pi_state->list));
                list_del_init(&pi_state->list);
                spin_unlock_irq(&pi_state->owner->pi_lock);
-       } else
-               newtid |= FUTEX_OWNER_DIED;
+       }
 
        pi_state->owner = newowner;
 
@@ -1118,26 +1161,35 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
        WARN_ON(!list_empty(&pi_state->list));
        list_add(&pi_state->list, &newowner->pi_state_list);
        spin_unlock_irq(&newowner->pi_lock);
+       return 0;
 
        /*
-        * We own it, so we have to replace the pending owner
-        * TID. This must be atomic as we have preserve the
-        * owner died bit here.
+        * To handle the page fault we need to drop the hash bucket
+        * lock here. That gives the other task (either the pending
+        * owner itself or the task which stole the rtmutex) the
+        * chance to try the fixup of the pi_state. So once we are
+        * back from handling the fault we need to check the pi_state
+        * after reacquiring the hash bucket lock and before trying to
+        * do another fixup. When the fixup has been done already we
+        * simply return.
         */
-       ret = get_futex_value_locked(&uval, uaddr);
+handle_fault:
+       spin_unlock(q->lock_ptr);
 
-       while (!ret) {
-               newval = (uval & FUTEX_OWNER_DIED) | newtid;
+       ret = futex_handle_fault((unsigned long)uaddr, fshared, attempt++);
 
-               curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
+       spin_lock(q->lock_ptr);
 
-               if (curval == -EFAULT)
-                       ret = -EFAULT;
-               if (curval == uval)
-                       break;
-               uval = curval;
-       }
-       return ret;
+       /*
+        * Check if someone else fixed it for us:
+        */
+       if (pi_state->owner != oldowner)
+               return 0;
+
+       if (ret)
+               return ret;
+
+       goto retry;
 }
 
 /*
@@ -1507,7 +1559,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
                 * that case:
                 */
                if (q.pi_state->owner != curr)
-                       ret = fixup_pi_state_owner(uaddr, &q, curr);
+                       ret = fixup_pi_state_owner(uaddr, &q, curr, fshared);
        } else {
                /*
                 * Catch the rare case, where the lock was released
@@ -1539,7 +1591,8 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
                                int res;
 
                                owner = rt_mutex_owner(&q.pi_state->pi_mutex);
-                               res = fixup_pi_state_owner(uaddr, &q, owner);
+                               res = fixup_pi_state_owner(uaddr, &q, owner,
+                                                          fshared);
 
                                /* propagate -EFAULT, if the fixup failed */
                                if (res)
index 79e3c90113c2874d592ece9d9cdef0e496499870..3ec23c3ec97fae75910a399b4b7200fb6a9169c6 100644 (file)
@@ -1499,7 +1499,8 @@ int kgdb_nmicallback(int cpu, void *regs)
        return 1;
 }
 
-void kgdb_console_write(struct console *co, const char *s, unsigned count)
+static void kgdb_console_write(struct console *co, const char *s,
+   unsigned count)
 {
        unsigned long flags;
 
index e1cdf196a51507ae644c8a7369b599c5233f8604..5e02b7740702fa928d188d7afd9855689d1b7b41 100644 (file)
@@ -217,8 +217,6 @@ long rcu_batches_completed(void)
 }
 EXPORT_SYMBOL_GPL(rcu_batches_completed);
 
-EXPORT_SYMBOL_GPL(rcu_batches_completed_bh);
-
 void __rcu_read_lock(void)
 {
        int idx;
index eaf6751e7612cbc5167865c8c1e4e929ff32ca5a..a66e85639de2e541dd9726245cd344d3ea2d9f3b 100644 (file)
@@ -1127,6 +1127,7 @@ static enum hrtimer_restart hrtick(struct hrtimer *timer)
        return HRTIMER_NORESTART;
 }
 
+#ifdef CONFIG_SMP
 static void hotplug_hrtick_disable(int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
@@ -1182,6 +1183,7 @@ static void init_hrtick(void)
 {
        hotcpu_notifier(hotplug_hrtick, 0);
 }
+#endif /* CONFIG_SMP */
 
 static void init_rq_hrtick(struct rq *rq)
 {
@@ -4396,22 +4398,20 @@ do_wait_for_common(struct completion *x, long timeout, int state)
                             signal_pending(current)) ||
                            (state == TASK_KILLABLE &&
                             fatal_signal_pending(current))) {
-                               __remove_wait_queue(&x->wait, &wait);
-                               return -ERESTARTSYS;
+                               timeout = -ERESTARTSYS;
+                               break;
                        }
                        __set_current_state(state);
                        spin_unlock_irq(&x->wait.lock);
                        timeout = schedule_timeout(timeout);
                        spin_lock_irq(&x->wait.lock);
-                       if (!timeout) {
-                               __remove_wait_queue(&x->wait, &wait);
-                               return timeout;
-                       }
-               } while (!x->done);
+               } while (!x->done && timeout);
                __remove_wait_queue(&x->wait, &wait);
+               if (!x->done)
+                       return timeout;
        }
        x->done--;
-       return timeout;
+       return timeout ?: 1;
 }
 
 static long __sched
@@ -5887,6 +5887,7 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
                next = pick_next_task(rq, rq->curr);
                if (!next)
                        break;
+               next->sched_class->put_prev_task(rq, next);
                migrate_dead(dead_cpu, next);
 
        }
@@ -6877,7 +6878,12 @@ static int default_relax_domain_level = -1;
 
 static int __init setup_relax_domain_level(char *str)
 {
-       default_relax_domain_level = simple_strtoul(str, NULL, 0);
+       unsigned long val;
+
+       val = simple_strtoul(str, NULL, 0);
+       if (val < SD_LV_MAX)
+               default_relax_domain_level = val;
+
        return 1;
 }
 __setup("relax_domain_level=", setup_relax_domain_level);
@@ -7235,6 +7241,18 @@ void __attribute__((weak)) arch_update_cpu_topology(void)
 {
 }
 
+/*
+ * Free current domain masks.
+ * Called after all cpus are attached to NULL domain.
+ */
+static void free_sched_domains(void)
+{
+       ndoms_cur = 0;
+       if (doms_cur != &fallback_doms)
+               kfree(doms_cur);
+       doms_cur = &fallback_doms;
+}
+
 /*
  * Set up scheduler domains and groups. Callers must hold the hotplug lock.
  * For now this just excludes isolated cpus, but could be used to
@@ -7382,6 +7400,7 @@ int arch_reinit_sched_domains(void)
        get_online_cpus();
        mutex_lock(&sched_domains_mutex);
        detach_destroy_domains(&cpu_online_map);
+       free_sched_domains();
        err = arch_init_sched_domains(&cpu_online_map);
        mutex_unlock(&sched_domains_mutex);
        put_online_cpus();
@@ -7467,6 +7486,7 @@ static int update_sched_domains(struct notifier_block *nfb,
        case CPU_DOWN_PREPARE:
        case CPU_DOWN_PREPARE_FROZEN:
                detach_destroy_domains(&cpu_online_map);
+               free_sched_domains();
                return NOTIFY_OK;
 
        case CPU_UP_CANCELED:
@@ -7485,8 +7505,16 @@ static int update_sched_domains(struct notifier_block *nfb,
                return NOTIFY_DONE;
        }
 
+#ifndef CONFIG_CPUSETS
+       /*
+        * Create default domain partitioning if cpusets are disabled.
+        * Otherwise we let cpusets rebuild the domains based on the
+        * current setup.
+        */
+
        /* The hotplug lock is already held by cpu_up/cpu_down */
        arch_init_sched_domains(&cpu_online_map);
+#endif
 
        return NOTIFY_OK;
 }
@@ -7626,7 +7654,6 @@ static void init_tg_rt_entry(struct task_group *tg, struct rt_rq *rt_rq,
        else
                rt_se->rt_rq = parent->my_q;
 
-       rt_se->rt_rq = &rq->rt;
        rt_se->my_q = rt_rq;
        rt_se->parent = parent;
        INIT_LIST_HEAD(&rt_se->run_list);
@@ -8348,7 +8375,7 @@ static unsigned long to_ratio(u64 period, u64 runtime)
 #ifdef CONFIG_CGROUP_SCHED
 static int __rt_schedulable(struct task_group *tg, u64 period, u64 runtime)
 {
-       struct task_group *tgi, *parent = tg->parent;
+       struct task_group *tgi, *parent = tg ? tg->parent : NULL;
        unsigned long total = 0;
 
        if (!parent) {
index 3432d573205d415d8a02070c3f59d3ab2f68fbbb..0f3c19197fa4e0ca4c614916efc818554db5afef 100644 (file)
@@ -250,7 +250,8 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun)
                        if (rt_rq->rt_time || rt_rq->rt_nr_running)
                                idle = 0;
                        spin_unlock(&rt_rq->rt_runtime_lock);
-               }
+               } else if (rt_rq->rt_nr_running)
+                       idle = 0;
 
                if (enqueue)
                        sched_rt_rq_enqueue(rt_rq);
@@ -449,13 +450,19 @@ void dec_rt_tasks(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 #endif
 }
 
-static void enqueue_rt_entity(struct sched_rt_entity *rt_se)
+static void __enqueue_rt_entity(struct sched_rt_entity *rt_se)
 {
        struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
        struct rt_prio_array *array = &rt_rq->active;
        struct rt_rq *group_rq = group_rt_rq(rt_se);
 
-       if (group_rq && rt_rq_throttled(group_rq))
+       /*
+        * Don't enqueue the group if its throttled, or when empty.
+        * The latter is a consequence of the former when a child group
+        * get throttled and the current group doesn't have any other
+        * active members.
+        */
+       if (group_rq && (rt_rq_throttled(group_rq) || !group_rq->rt_nr_running))
                return;
 
        list_add_tail(&rt_se->run_list, array->queue + rt_se_prio(rt_se));
@@ -464,7 +471,7 @@ static void enqueue_rt_entity(struct sched_rt_entity *rt_se)
        inc_rt_tasks(rt_se, rt_rq);
 }
 
-static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
+static void __dequeue_rt_entity(struct sched_rt_entity *rt_se)
 {
        struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
        struct rt_prio_array *array = &rt_rq->active;
@@ -480,11 +487,10 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
  * Because the prio of an upper entry depends on the lower
  * entries, we must remove entries top - down.
  */
-static void dequeue_rt_stack(struct task_struct *p)
+static void dequeue_rt_stack(struct sched_rt_entity *rt_se)
 {
-       struct sched_rt_entity *rt_se, *back = NULL;
+       struct sched_rt_entity *back = NULL;
 
-       rt_se = &p->rt;
        for_each_sched_rt_entity(rt_se) {
                rt_se->back = back;
                back = rt_se;
@@ -492,7 +498,26 @@ static void dequeue_rt_stack(struct task_struct *p)
 
        for (rt_se = back; rt_se; rt_se = rt_se->back) {
                if (on_rt_rq(rt_se))
-                       dequeue_rt_entity(rt_se);
+                       __dequeue_rt_entity(rt_se);
+       }
+}
+
+static void enqueue_rt_entity(struct sched_rt_entity *rt_se)
+{
+       dequeue_rt_stack(rt_se);
+       for_each_sched_rt_entity(rt_se)
+               __enqueue_rt_entity(rt_se);
+}
+
+static void dequeue_rt_entity(struct sched_rt_entity *rt_se)
+{
+       dequeue_rt_stack(rt_se);
+
+       for_each_sched_rt_entity(rt_se) {
+               struct rt_rq *rt_rq = group_rt_rq(rt_se);
+
+               if (rt_rq && rt_rq->rt_nr_running)
+                       __enqueue_rt_entity(rt_se);
        }
 }
 
@@ -506,32 +531,15 @@ static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
        if (wakeup)
                rt_se->timeout = 0;
 
-       dequeue_rt_stack(p);
-
-       /*
-        * enqueue everybody, bottom - up.
-        */
-       for_each_sched_rt_entity(rt_se)
-               enqueue_rt_entity(rt_se);
+       enqueue_rt_entity(rt_se);
 }
 
 static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep)
 {
        struct sched_rt_entity *rt_se = &p->rt;
-       struct rt_rq *rt_rq;
 
        update_curr_rt(rq);
-
-       dequeue_rt_stack(p);
-
-       /*
-        * re-enqueue all non-empty rt_rq entities.
-        */
-       for_each_sched_rt_entity(rt_se) {
-               rt_rq = group_rt_rq(rt_se);
-               if (rt_rq && rt_rq->rt_nr_running)
-                       enqueue_rt_entity(rt_se);
-       }
+       dequeue_rt_entity(rt_se);
 }
 
 /*
@@ -542,8 +550,10 @@ static
 void requeue_rt_entity(struct rt_rq *rt_rq, struct sched_rt_entity *rt_se)
 {
        struct rt_prio_array *array = &rt_rq->active;
+       struct list_head *queue = array->queue + rt_se_prio(rt_se);
 
-       list_move_tail(&rt_se->run_list, array->queue + rt_se_prio(rt_se));
+       if (on_rt_rq(rt_se))
+               list_move_tail(&rt_se->run_list, queue);
 }
 
 static void requeue_task_rt(struct rq *rq, struct task_struct *p)
index a38878e0e49d50cebcbb52fc5a976df23497f3ef..80179ef7450e95684f9d3f0221fce3b32615bbd5 100644 (file)
@@ -198,6 +198,9 @@ static inline void sched_info_queued(struct task_struct *t)
 /*
  * Called when a process ceases being the active-running process, either
  * voluntarily or involuntarily.  Now we can calculate how long we ran.
+ * Also, if the process is still in the TASK_RUNNING state, call
+ * sched_info_queued() to mark that it has now again started waiting on
+ * the runqueue.
  */
 static inline void sched_info_depart(struct task_struct *t)
 {
@@ -206,6 +209,9 @@ static inline void sched_info_depart(struct task_struct *t)
 
        t->sched_info.cpu_time += delta;
        rq_sched_info_depart(task_rq(t), delta);
+
+       if (t->state == TASK_RUNNING)
+               sched_info_queued(t);
 }
 
 /*
index 01b6522fd92bc0b28f7df00eb66876a389b34908..c828c2339cc9e8a8992df52f31756f8894c7f6b1 100644 (file)
@@ -49,12 +49,17 @@ static unsigned long get_timestamp(int this_cpu)
        return cpu_clock(this_cpu) >> 30LL;  /* 2^30 ~= 10^9 */
 }
 
-void touch_softlockup_watchdog(void)
+static void __touch_softlockup_watchdog(void)
 {
        int this_cpu = raw_smp_processor_id();
 
        __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu);
 }
+
+void touch_softlockup_watchdog(void)
+{
+       __raw_get_cpu_var(touch_timestamp) = 0;
+}
 EXPORT_SYMBOL(touch_softlockup_watchdog);
 
 void touch_all_softlockup_watchdogs(void)
@@ -80,7 +85,7 @@ void softlockup_tick(void)
        unsigned long now;
 
        if (touch_timestamp == 0) {
-               touch_softlockup_watchdog();
+               __touch_softlockup_watchdog();
                return;
        }
 
@@ -95,7 +100,7 @@ void softlockup_tick(void)
 
        /* do not print during early bootup: */
        if (unlikely(system_state != SYSTEM_RUNNING)) {
-               touch_softlockup_watchdog();
+               __touch_softlockup_watchdog();
                return;
        }
 
@@ -214,7 +219,7 @@ static int watchdog(void *__bind_cpu)
        sched_setscheduler(current, SCHED_FIFO, &param);
 
        /* initialize timestamp */
-       touch_softlockup_watchdog();
+       __touch_softlockup_watchdog();
 
        set_current_state(TASK_INTERRUPTIBLE);
        /*
@@ -223,7 +228,7 @@ static int watchdog(void *__bind_cpu)
         * debug-printout triggers in softlockup_tick().
         */
        while (!kthread_should_stop()) {
-               touch_softlockup_watchdog();
+               __touch_softlockup_watchdog();
                schedule();
 
                if (kthread_should_stop())
index a76a5e122ae134dabd283073c6404aac51501243..85b18d79be89acee07e25004eac991df799f0b8a 100644 (file)
@@ -68,6 +68,7 @@ static int fill_pool(void)
 {
        gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
        struct debug_obj *new;
+       unsigned long flags;
 
        if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL))
                return obj_pool_free;
@@ -81,10 +82,10 @@ static int fill_pool(void)
                if (!new)
                        return obj_pool_free;
 
-               spin_lock(&pool_lock);
+               spin_lock_irqsave(&pool_lock, flags);
                hlist_add_head(&new->node, &obj_pool);
                obj_pool_free++;
-               spin_unlock(&pool_lock);
+               spin_unlock_irqrestore(&pool_lock, flags);
        }
        return obj_pool_free;
 }
@@ -110,16 +111,13 @@ static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b)
 }
 
 /*
- * Allocate a new object. If the pool is empty and no refill possible,
- * switch off the debugger.
+ * Allocate a new object. If the pool is empty, switch off the debugger.
  */
 static struct debug_obj *
 alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
 {
        struct debug_obj *obj = NULL;
-       int retry = 0;
 
-repeat:
        spin_lock(&pool_lock);
        if (obj_pool.first) {
                obj         = hlist_entry(obj_pool.first, typeof(*obj), node);
@@ -141,9 +139,6 @@ repeat:
        }
        spin_unlock(&pool_lock);
 
-       if (fill_pool() && !obj && !retry++)
-               goto repeat;
-
        return obj;
 }
 
@@ -261,6 +256,8 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
        struct debug_obj *obj;
        unsigned long flags;
 
+       fill_pool();
+
        db = get_bucket((unsigned long) addr);
 
        spin_lock_irqsave(&db->lock, flags);
index d90822c378a48af52878f41e5db18858496fddb9..4a7fce72898ed40f13d58bca7cc1d97293d8bba0 100644 (file)
@@ -63,7 +63,7 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
        struct ts_bm *bm = ts_config_priv(conf);
        unsigned int i, text_len, consumed = state->offset;
        const u8 *text;
-       int shift = bm->patlen, bs;
+       int shift = bm->patlen - 1, bs;
 
        for (;;) {
                text_len = conf->get_next_block(consumed, &text, conf, state);
index e8fb927392b9ac02b4ad16878847551d103a1b43..8d9f60e06f621e1d6bf614238ca86b82dcb3e840 100644 (file)
@@ -442,15 +442,17 @@ unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
        return init_bootmem_core(pgdat, freepfn, startpfn, endpfn);
 }
 
-void __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
+int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
                                 unsigned long size, int flags)
 {
        int ret;
 
        ret = can_reserve_bootmem_core(pgdat->bdata, physaddr, size, flags);
        if (ret < 0)
-               return;
+               return -ENOMEM;
        reserve_bootmem_core(pgdat->bdata, physaddr, size, flags);
+
+       return 0;
 }
 
 void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
index 19e0ae9beecb71062f4a8030f6ab8df14bfa9d51..d14b251a25a638dec1b5327a6261a67660ba67d5 100644 (file)
@@ -999,17 +999,15 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
                goto no_page_table;
 
        ptep = pte_offset_map_lock(mm, pmd, address, &ptl);
-       if (!ptep)
-               goto out;
 
        pte = *ptep;
        if (!pte_present(pte))
-               goto unlock;
+               goto no_page;
        if ((flags & FOLL_WRITE) && !pte_write(pte))
                goto unlock;
        page = vm_normal_page(vma, address, pte);
        if (unlikely(!page))
-               goto unlock;
+               goto bad_page;
 
        if (flags & FOLL_GET)
                get_page(page);
@@ -1024,6 +1022,15 @@ unlock:
 out:
        return page;
 
+bad_page:
+       pte_unmap_unlock(ptep, ptl);
+       return ERR_PTR(-EFAULT);
+
+no_page:
+       pte_unmap_unlock(ptep, ptl);
+       if (!pte_none(pte))
+               return page;
+       /* Fall through to ZERO_PAGE handling */
 no_page_table:
        /*
         * When core dumping an enormous anonymous area that nobody
@@ -1038,6 +1045,26 @@ no_page_table:
        return page;
 }
 
+/* Can we do the FOLL_ANON optimization? */
+static inline int use_zero_page(struct vm_area_struct *vma)
+{
+       /*
+        * We don't want to optimize FOLL_ANON for make_pages_present()
+        * when it tries to page in a VM_LOCKED region. As to VM_SHARED,
+        * we want to get the page from the page tables to make sure
+        * that we serialize and update with any other user of that
+        * mapping.
+        */
+       if (vma->vm_flags & (VM_LOCKED | VM_SHARED))
+               return 0;
+       /*
+        * And if we have a fault or a nopfn routine, it's not an
+        * anonymous region.
+        */
+       return !vma->vm_ops ||
+               (!vma->vm_ops->fault && !vma->vm_ops->nopfn);
+}
+
 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                unsigned long start, int len, int write, int force,
                struct page **pages, struct vm_area_struct **vmas)
@@ -1112,8 +1139,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                foll_flags = FOLL_TOUCH;
                if (pages)
                        foll_flags |= FOLL_GET;
-               if (!write && !(vma->vm_flags & VM_LOCKED) &&
-                   (!vma->vm_ops || !vma->vm_ops->fault))
+               if (!write && use_zero_page(vma))
                        foll_flags |= FOLL_ANON;
 
                do {
@@ -1159,6 +1185,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
 
                                cond_resched();
                        }
+                       if (IS_ERR(page))
+                               return i ? i : PTR_ERR(page);
                        if (pages) {
                                pages[i] = page;
 
@@ -1757,7 +1785,6 @@ gotten:
        page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
        if (likely(pte_same(*page_table, orig_pte))) {
                if (old_page) {
-                       page_remove_rmap(old_page, vma);
                        if (!PageAnon(old_page)) {
                                dec_mm_counter(mm, file_rss);
                                inc_mm_counter(mm, anon_rss);
@@ -1779,6 +1806,32 @@ gotten:
                lru_cache_add_active(new_page);
                page_add_new_anon_rmap(new_page, vma, address);
 
+               if (old_page) {
+                       /*
+                        * Only after switching the pte to the new page may
+                        * we remove the mapcount here. Otherwise another
+                        * process may come and find the rmap count decremented
+                        * before the pte is switched to the new page, and
+                        * "reuse" the old page writing into it while our pte
+                        * here still points into it and can be read by other
+                        * threads.
+                        *
+                        * The critical issue is to order this
+                        * page_remove_rmap with the ptp_clear_flush above.
+                        * Those stores are ordered by (if nothing else,)
+                        * the barrier present in the atomic_add_negative
+                        * in page_remove_rmap.
+                        *
+                        * Then the TLB flush in ptep_clear_flush ensures that
+                        * no process can access the old page before the
+                        * decremented mapcount is visible. And the old page
+                        * cannot be reused until after the decremented
+                        * mapcount is visible. So transitively, TLBs to
+                        * old page will be flushed before it can be reused.
+                        */
+                       page_remove_rmap(old_page, vma);
+               }
+
                /* Free the old page.. */
                new_page = old_page;
                ret |= VM_FAULT_WRITE;
index 449d77d409f52622bbf825b7fd17d43df7ff5fbf..112bcaeaa1046076af8618b7f06b2cfbc32faf8a 100644 (file)
@@ -865,6 +865,11 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
                        goto set_status;
 
                page = follow_page(vma, pp->addr, FOLL_GET);
+
+               err = PTR_ERR(page);
+               if (IS_ERR(page))
+                       goto set_status;
+
                err = -ENOENT;
                if (!page)
                        goto set_status;
@@ -928,6 +933,11 @@ static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm)
                        goto set_status;
 
                page = follow_page(vma, pm->addr, 0);
+
+               err = PTR_ERR(page);
+               if (IS_ERR(page))
+                       goto set_status;
+
                err = -ENOENT;
                /* Use PageReserved to check for zero page */
                if (!page || PageReserved(page))
index 06236e4ddc1b99686d64683865ca648ed2f79864..046607f05f3eb16414538201836c6e605135b0e8 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3263,9 +3263,12 @@ retry:
 
                if (cpuset_zone_allowed_hardwall(zone, flags) &&
                        cache->nodelists[nid] &&
-                       cache->nodelists[nid]->free_objects)
+                       cache->nodelists[nid]->free_objects) {
                                obj = ____cache_alloc_node(cache,
                                        flags | GFP_THISNODE, nid);
+                               if (obj)
+                                       break;
+               }
        }
 
        if (!obj) {
index 68d8df0992abfd425c517fc8b9df3d6a40fe71ff..fca23a3bf12c1b5b14d6430ff07abbecbd749cc4 100644 (file)
@@ -454,7 +454,7 @@ static int netdev_boot_setup_add(char *name, struct ifmap *map)
        for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
                if (s[i].name[0] == '\0' || s[i].name[0] == ' ') {
                        memset(s[i].name, 0, sizeof(s[i].name));
-                       strcpy(s[i].name, name);
+                       strlcpy(s[i].name, name, IFNAMSIZ);
                        memcpy(&s[i].map, map, sizeof(s[i].map));
                        break;
                }
@@ -479,7 +479,7 @@ int netdev_boot_setup_check(struct net_device *dev)
 
        for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) {
                if (s[i].name[0] != '\0' && s[i].name[0] != ' ' &&
-                   !strncmp(dev->name, s[i].name, strlen(s[i].name))) {
+                   !strcmp(dev->name, s[i].name)) {
                        dev->irq        = s[i].map.irq;
                        dev->base_addr  = s[i].map.base_addr;
                        dev->mem_start  = s[i].map.mem_start;
@@ -2077,6 +2077,10 @@ int netif_receive_skb(struct sk_buff *skb)
 
        rcu_read_lock();
 
+       /* Don't receive packets in an exiting network namespace */
+       if (!net_alive(dev_net(skb->dev)))
+               goto out;
+
 #ifdef CONFIG_NET_CLS_ACT
        if (skb->tc_verd & TC_NCLS) {
                skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@ -2969,7 +2973,7 @@ EXPORT_SYMBOL(dev_unicast_delete);
 /**
  *     dev_unicast_add         - add a secondary unicast address
  *     @dev: device
- *     @addr: address to delete
+ *     @addr: address to add
  *     @alen: length of @addr
  *
  *     Add a secondary unicast address to the device or increase
index e3e9ab0f74e33caf9e0df3a8d0829359f86eefe7..277a2302eb3abb666574a5b3b7dc2714f45ef7c4 100644 (file)
@@ -226,7 +226,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 
        ops = lookup_rules_ops(net, frh->family);
        if (ops == NULL) {
-               err = EAFNOSUPPORT;
+               err = -EAFNOSUPPORT;
                goto errout;
        }
 
@@ -365,7 +365,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
 
        ops = lookup_rules_ops(net, frh->family);
        if (ops == NULL) {
-               err = EAFNOSUPPORT;
+               err = -EAFNOSUPPORT;
                goto errout;
        }
 
index 4f8369729a4e8d15347a00cfeac2b56aea40b112..df37443558395a01780f725e744a920fb1664872 100644 (file)
@@ -68,7 +68,6 @@ static inline void *load_pointer(struct sk_buff *skb, int k,
  *     sk_filter - run a packet through a socket filter
  *     @sk: sock associated with &sk_buff
  *     @skb: buffer to filter
- *     @needlock: set to 1 if the sock is not locked by caller.
  *
  * Run the filter code and then cut skb->data to correct size returned by
  * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller
index 72b4c184dd84a4d583a20ef0ed5dbd06618f5757..7c52fe277b62441966f758b25fad9acef18a10d0 100644 (file)
@@ -140,6 +140,9 @@ static void cleanup_net(struct work_struct *work)
        struct pernet_operations *ops;
        struct net *net;
 
+       /* Be very certain incoming network packets will not find us */
+       rcu_barrier();
+
        net = container_of(work, struct net, work);
 
        mutex_lock(&net_mutex);
index 1e556d31211742d41acb39cbc2c1cd8460e2d3b0..366621610e76d5a91ae72522d38d0b60e3df45d9 100644 (file)
@@ -1292,12 +1292,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
 {
        unsigned int nr_pages = spd->nr_pages;
        unsigned int poff, plen, len, toff, tlen;
-       int headlen, seg;
+       int headlen, seg, error = 0;
 
        toff = *offset;
        tlen = *total_len;
-       if (!tlen)
+       if (!tlen) {
+               error = 1;
                goto err;
+       }
 
        /*
         * if the offset is greater than the linear part, go directly to
@@ -1339,7 +1341,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
                 * just jump directly to update and return, no point
                 * in going over fragments when the output is full.
                 */
-               if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb))
+               error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb);
+               if (error)
                        goto done;
 
                tlen -= plen;
@@ -1369,7 +1372,8 @@ map_frag:
                if (!plen)
                        break;
 
-               if (spd_fill_page(spd, f->page, plen, poff, skb))
+               error = spd_fill_page(spd, f->page, plen, poff, skb);
+               if (error)
                        break;
 
                tlen -= plen;
@@ -1382,7 +1386,10 @@ done:
                return 0;
        }
 err:
-       return 1;
+       /* update the offset to reflect the linear part skip, if any */
+       if (!error)
+               *offset = toff;
+       return error;
 }
 
 /*
index 4ed429bd5951542401130f16e3a4f0341ded3920..0546a0bc97ea37bdc1b9bef0c22d6b82ec190abf 100644 (file)
@@ -192,14 +192,21 @@ EXPORT_SYMBOL(inet_frag_evictor);
 
 static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf,
                struct inet_frag_queue *qp_in, struct inet_frags *f,
-               unsigned int hash, void *arg)
+               void *arg)
 {
        struct inet_frag_queue *qp;
 #ifdef CONFIG_SMP
        struct hlist_node *n;
 #endif
+       unsigned int hash;
 
        write_lock(&f->lock);
+       /*
+        * While we stayed w/o the lock other CPU could update
+        * the rnd seed, so we need to re-calculate the hash
+        * chain. Fortunatelly the qp_in can be used to get one.
+        */
+       hash = f->hashfn(qp_in);
 #ifdef CONFIG_SMP
        /* With SMP race we have to recheck hash table, because
         * such entry could be created on other cpu, while we
@@ -247,7 +254,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
 }
 
 static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf,
-               struct inet_frags *f, void *arg, unsigned int hash)
+               struct inet_frags *f, void *arg)
 {
        struct inet_frag_queue *q;
 
@@ -255,7 +262,7 @@ static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf,
        if (q == NULL)
                return NULL;
 
-       return inet_frag_intern(nf, q, f, hash, arg);
+       return inet_frag_intern(nf, q, f, arg);
 }
 
 struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
@@ -264,7 +271,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
        struct inet_frag_queue *q;
        struct hlist_node *n;
 
-       read_lock(&f->lock);
        hlist_for_each_entry(q, n, &f->hash[hash], list) {
                if (q->net == nf && f->match(q, key)) {
                        atomic_inc(&q->refcnt);
@@ -274,6 +280,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
        }
        read_unlock(&f->lock);
 
-       return inet_frag_create(nf, f, key, hash);
+       return inet_frag_create(nf, f, key);
 }
 EXPORT_SYMBOL(inet_frag_find);
index 4a4d49fca1f2518a12eebbfbae02211eace06a19..cfd034a2b96ed7926f5139aeb161a58ba1820b2f 100644 (file)
@@ -383,8 +383,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb,
 out2: /* send aggregated SKBs to stack */
        lro_flush(lro_mgr, lro_desc);
 
-out:  /* Original SKB has to be posted to stack */
-       skb->ip_summed = lro_mgr->ip_summed;
+out:
        return 1;
 }
 
index cd6ce6ac635843e4598e5332c32256bb0ff93926..37221f65915960a8a5173b4862fcace1591fdec9 100644 (file)
@@ -229,6 +229,8 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
 
        arg.iph = iph;
        arg.user = user;
+
+       read_lock(&ip4_frags.lock);
        hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
 
        q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
index fc54a48fde1e6a6b07a157b1cc551427d226099b..850825dc86e6dc55ea72ce8b669c4bf16f3ee876 100644 (file)
 #include <linux/socket.h>
 #include <linux/random.h>
 #include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
 #include <linux/cache.h>
 #include <linux/err.h>
 #include <linux/crypto.h>
@@ -2620,7 +2622,7 @@ __setup("thash_entries=", set_thash_entries);
 void __init tcp_init(void)
 {
        struct sk_buff *skb = NULL;
-       unsigned long limit;
+       unsigned long nr_pages, limit;
        int order, i, max_share;
 
        BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
@@ -2689,8 +2691,9 @@ void __init tcp_init(void)
         * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
         * memory, with a floor of 128 pages.
         */
-       limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
-       limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
+       nr_pages = totalram_pages - totalhigh_pages;
+       limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
+       limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
        limit = max(limit, 128UL);
        sysctl_tcp_mem[0] = limit / 4 * 3;
        sysctl_tcp_mem[1] = limit;
index 12695be2c255a2ac4baeb5aa049dd16f41fb7bf9..ffe869ac1bcf15b51abd801b3b3b4533da0b530e 100644 (file)
@@ -2291,7 +2291,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
        }
 
        seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
-                       "%08X %5d %8d %lu %d %p %u %u %u %u %d%n",
+                       "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n",
                i, src, srcp, dest, destp, sk->sk_state,
                tp->write_seq - tp->snd_una,
                sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog :
@@ -2303,8 +2303,8 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
                icsk->icsk_probes_out,
                sock_i_ino(sk),
                atomic_read(&sk->sk_refcnt), sk,
-               icsk->icsk_rto,
-               icsk->icsk_ack.ato,
+               jiffies_to_clock_t(icsk->icsk_rto),
+               jiffies_to_clock_t(icsk->icsk_ack.ato),
                (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
                tp->snd_cwnd,
                tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh,
index 4e5c8615832c61d88034910422db16722151de05..17eb48b8e329af87498a1482dd0cfc64dad83789 100644 (file)
@@ -102,6 +102,15 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        if (hdr->version != 6)
                goto err;
 
+       /*
+        * RFC4291 2.5.3
+        * A packet received on an interface with a destination address
+        * of loopback must be dropped.
+        */
+       if (!(dev->flags & IFF_LOOPBACK) &&
+           ipv6_addr_loopback(&hdr->daddr))
+               goto err;
+
        skb->transport_header = skb->network_header + sizeof(*hdr);
        IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
 
index c042ce19bd141f04982820b0b7375f5c0e148fad..86e28a75267f4dac4a72a4c02413ab6c99945a60 100644 (file)
@@ -345,18 +345,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
        case IPV6_DSTOPTS:
        {
                struct ipv6_txoptions *opt;
+
+               /* remove any sticky options header with a zero option
+                * length, per RFC3542.
+                */
                if (optlen == 0)
                        optval = NULL;
+               else if (optlen < sizeof(struct ipv6_opt_hdr) ||
+                        optlen & 0x7 || optlen > 8 * 255)
+                       goto e_inval;
 
                /* hop-by-hop / destination options are privileged option */
                retv = -EPERM;
                if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
                        break;
 
-               if (optlen < sizeof(struct ipv6_opt_hdr) ||
-                   optlen & 0x7 || optlen > 8 * 255)
-                       goto e_inval;
-
                opt = ipv6_renew_options(sk, np->opt, optname,
                                         (struct ipv6_opt_hdr __user *)optval,
                                         optlen);
index 27a5e8b48d93a27fababd4d79fb998903d039422..f405cea21a8b89687558c83deb094d7c1940631e 100644 (file)
@@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
                .priority       = NF_IP6_PRI_MANGLE,
        },
        {
-               .hook           = ip6t_local_hook,
+               .hook           = ip6t_route_hook,
                .owner          = THIS_MODULE,
                .pf             = PF_INET6,
                .hooknum        = NF_INET_LOCAL_IN,
index e65e26e210ee3a66873f6d472fdca708559fb0a2..cf20bc4fd60db346eab94b35ec3b84ee255dd265 100644 (file)
@@ -207,9 +207,10 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
        arg.id = id;
        arg.src = src;
        arg.dst = dst;
+
+       read_lock_bh(&nf_frags.lock);
        hash = ip6qhashfn(id, src, dst);
 
-       local_bh_disable();
        q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
        local_bh_enable();
        if (q == NULL)
index 798cabc7535b747d9193ce20e1dce1907e18eb8f..a60d7d1297137880de4294999966f3cb487ec16c 100644 (file)
@@ -247,6 +247,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
        arg.id = id;
        arg.src = src;
        arg.dst = dst;
+
+       read_lock(&ip6_frags.lock);
        hash = ip6qhashfn(id, src, dst);
 
        q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
index d1f3e19b06c79ade99a6b34eb385ee15753c6c77..7ff687020fa9ee780042ddeeb080e3ebb20f8199 100644 (file)
@@ -240,7 +240,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr)
 static inline struct rt6_info *rt6_device_match(struct net *net,
                                                    struct rt6_info *rt,
                                                    int oif,
-                                                   int strict)
+                                                   int flags)
 {
        struct rt6_info *local = NULL;
        struct rt6_info *sprt;
@@ -253,7 +253,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
                        if (dev->flags & IFF_LOOPBACK) {
                                if (sprt->rt6i_idev == NULL ||
                                    sprt->rt6i_idev->dev->ifindex != oif) {
-                                       if (strict && oif)
+                                       if (flags & RT6_LOOKUP_F_IFACE && oif)
                                                continue;
                                        if (local && (!oif ||
                                                      local->rt6i_idev->dev->ifindex == oif))
@@ -266,7 +266,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
                if (local)
                        return local;
 
-               if (strict)
+               if (flags & RT6_LOOKUP_F_IFACE)
                        return net->ipv6.ip6_null_entry;
        }
        return rt;
index cb46749d4c326a3e7133537b70ed3cccce82eb9d..40ea9c36d24bff0426a807a9f200b0de08362c39 100644 (file)
@@ -2036,7 +2036,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
 
        seq_printf(seq,
                   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
-                  "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n",
+                  "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n",
                   i,
                   src->s6_addr32[0], src->s6_addr32[1],
                   src->s6_addr32[2], src->s6_addr32[3], srcp,
@@ -2052,8 +2052,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
                   icsk->icsk_probes_out,
                   sock_i_ino(sp),
                   atomic_read(&sp->sk_refcnt), sp,
-                  icsk->icsk_rto,
-                  icsk->icsk_ack.ato,
+                  jiffies_to_clock_t(icsk->icsk_rto),
+                  jiffies_to_clock_t(icsk->icsk_ack.ato),
                   (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong,
                   tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh
                   );
index 150d66dbda9d22de6ca0b94c48eab7e70c3f733f..220e83be3ef4a3dad7331f451bb95021d7c04701 100644 (file)
@@ -380,6 +380,15 @@ void ieee80211_key_free(struct ieee80211_key *key)
        if (!key)
                return;
 
+       if (!key->sdata) {
+               /* The key has not been linked yet, simply free it
+                * and don't Oops */
+               if (key->conf.alg == ALG_CCMP)
+                       ieee80211_aes_key_free(key->u.ccmp.tfm);
+               kfree(key);
+               return;
+       }
+
        spin_lock_irqsave(&key->sdata->local->key_lock, flags);
        __ieee80211_key_free(key);
        spin_unlock_irqrestore(&key->sdata->local->key_lock, flags);
index 28d8bd53bd3a9f3ccf01e56c5df5bcffd87d1908..c80d5899f27903c23080c419e808fddc323d521e 100644 (file)
@@ -1132,7 +1132,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
        ieee80211_tx_handler *handler;
        struct ieee80211_tx_data tx;
        ieee80211_tx_result res = TX_DROP, res_prepare;
-       int ret, i;
+       int ret, i, retries = 0;
 
        WARN_ON(__ieee80211_queue_pending(local, control->queue));
 
@@ -1216,6 +1216,13 @@ retry:
                if (!__ieee80211_queue_stopped(local, control->queue)) {
                        clear_bit(IEEE80211_LINK_STATE_PENDING,
                                  &local->state[control->queue]);
+                       retries++;
+                       /*
+                        * Driver bug, it's rejecting packets but
+                        * not stopping queues.
+                        */
+                       if (WARN_ON_ONCE(retries > 5))
+                               goto drop;
                        goto retry;
                }
                memcpy(&store->control, control,
index 6106cb79060c928f65e7d5a5d2154f280b55bf5f..e8404212ad57ecdfda2df597a9725c73278627b4 100644 (file)
@@ -95,6 +95,13 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr,
                        }
                }
 
+               if (alg == ALG_WEP &&
+                       key_len != LEN_WEP40 && key_len != LEN_WEP104) {
+                       ieee80211_key_free(key);
+                       err = -EINVAL;
+                       goto out_unlock;
+               }
+
                ieee80211_key_link(key, sdata, sta);
 
                if (set_tx_key || (!sta && !sdata->default_key && key))
index 635b996c8c350c52c5f9cef6747c3408e3e40711..5d09e8698b57584cb66bbc83e96295955c68c360 100644 (file)
@@ -323,8 +323,7 @@ static void wme_qdiscop_destroy(struct Qdisc* qd)
        struct ieee80211_hw *hw = &local->hw;
        int queue;
 
-       tcf_destroy_chain(q->filter_list);
-       q->filter_list = NULL;
+       tcf_destroy_chain(&q->filter_list);
 
        for (queue=0; queue < hw->queues; queue++) {
                skb_queue_purge(&q->requeued[queue]);
index ba94004fe323182b6a527507548a1e54e1099321..271cd01d57aed49192d94dc7a98a066d884a9a7b 100644 (file)
@@ -331,12 +331,13 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph)
 
    I.   Upper bound for valid data:    seq <= sender.td_maxend
    II.  Lower bound for valid data:    seq + len >= sender.td_end - receiver.td_maxwin
-   III.        Upper bound for valid ack:      sack <= receiver.td_end
-   IV. Lower bound for valid ack:      ack >= receiver.td_end - MAXACKWINDOW
+   III.        Upper bound for valid (s)ack:   sack <= receiver.td_end
+   IV. Lower bound for valid (s)ack:   sack >= receiver.td_end - MAXACKWINDOW
 
-   where sack is the highest right edge of sack block found in the packet.
+   where sack is the highest right edge of sack block found in the packet
+   or ack in the case of packet without SACK option.
 
-   The upper bound limit for a valid ack is not ignored -
+   The upper bound limit for a valid (s)ack is not ignored -
    we doesn't have to deal with fragments.
 */
 
@@ -606,12 +607,12 @@ static bool tcp_in_window(const struct nf_conn *ct,
                 before(seq, sender->td_maxend + 1),
                 after(end, sender->td_end - receiver->td_maxwin - 1),
                 before(sack, receiver->td_end + 1),
-                after(ack, receiver->td_end - MAXACKWINDOW(sender)));
+                after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
 
        if (before(seq, sender->td_maxend + 1) &&
            after(end, sender->td_end - receiver->td_maxwin - 1) &&
            before(sack, receiver->td_end + 1) &&
-           after(ack, receiver->td_end - MAXACKWINDOW(sender))) {
+           after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
                /*
                 * Take into account window scaling (RFC 1323).
                 */
index 0099da5b2591e5295429b7578688fa6949db3db1..52b2611a6eb6625f8d1d329bea03d03e7ad460ac 100644 (file)
@@ -1534,7 +1534,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
                }
        }
        list_for_each_entry_rcu(addr6, &iface->addr6_list, list) {
-               if (addr6->valid || iter_addr6++ < skip_addr6)
+               if (!addr6->valid || iter_addr6++ < skip_addr6)
                        continue;
                if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
                                           iface,
index 9b97f8006c9c6edfd0dea0dde522b6a7e64c171f..349aba189558669c9ddd8ac82ad585d1fb23d557 100644 (file)
@@ -886,7 +886,7 @@ retry:
                return netlink_unicast_kernel(sk, skb);
 
        if (sk_filter(sk, skb)) {
-               int err = skb->len;
+               err = skb->len;
                kfree_skb(skb);
                sock_put(sk);
                return err;
index 47bbf45ae5d7905e05487955d77832e03915f215..2d106cfe1d276bf5e234195753eb091cba7b7f1e 100644 (file)
@@ -132,6 +132,7 @@ errout:
  * @maxtype: maximum attribute type to be expected
  * @head: head of attribute stream
  * @len: length of attribute stream
+ * @policy: validation policy
  *
  * Parses a stream of attributes and stores a pointer to each attribute in
  * the tb array accessable via the attribute type. Attributes with a type
@@ -194,7 +195,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
 /**
  * nla_strlcpy - Copy string attribute payload into a sized buffer
  * @dst: where to copy the string to
- * @src: attribute to copy the string from
+ * @nla: attribute to copy the string from
  * @dstsize: size of destination buffer
  *
  * Copies at most dstsize - 1 bytes into the destination buffer.
@@ -340,9 +341,9 @@ struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen)
 }
 
 /**
- * nla_reserve - reserve room for attribute without header
+ * nla_reserve_nohdr - reserve room for attribute without header
  * @skb: socket buffer to reserve room on
- * @len: length of attribute payload
+ * @attrlen: length of attribute payload
  *
  * Reserves room for attribute payload without a header.
  *
index 82adfe6447d7db004c7108731e0ad4c7b87f8657..9437b27ff84de101b88b3cbe08675f002e562238 100644 (file)
@@ -106,17 +106,6 @@ config NET_SCH_PRIO
          To compile this code as a module, choose M here: the
          module will be called sch_prio.
 
-config NET_SCH_RR
-       tristate "Multi Band Round Robin Queuing (RR)"
-       select NET_SCH_PRIO
-       ---help---
-         Say Y here if you want to use an n-band round robin packet
-         scheduler.
-
-         The module uses sch_prio for its framework and is aliased as
-         sch_rr, so it will load sch_prio, although it is referred
-         to using sch_rr.
-
 config NET_SCH_RED
        tristate "Random Early Detection (RED)"
        ---help---
index c40773cdbe45466c8bead7bfd58c0fde73fc6c76..10f01ad043800589f9d2eebd994c7f8de86ce19b 100644 (file)
@@ -1252,12 +1252,12 @@ void tcf_destroy(struct tcf_proto *tp)
        kfree(tp);
 }
 
-void tcf_destroy_chain(struct tcf_proto *fl)
+void tcf_destroy_chain(struct tcf_proto **fl)
 {
        struct tcf_proto *tp;
 
-       while ((tp = fl) != NULL) {
-               fl = tp->next;
+       while ((tp = *fl) != NULL) {
+               *fl = tp->next;
                tcf_destroy(tp);
        }
 }
index 33527341638427c3bf9e97385a7f7d5ba37f07d8..db0e23ae85f8fb048c81e654ecbe8524fbf08f43 100644 (file)
@@ -160,7 +160,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
        *prev = flow->next;
        pr_debug("atm_tc_put: qdisc %p\n", flow->q);
        qdisc_destroy(flow->q);
-       tcf_destroy_chain(flow->filter_list);
+       tcf_destroy_chain(&flow->filter_list);
        if (flow->sock) {
                pr_debug("atm_tc_put: f_count %d\n",
                        file_count(flow->sock->file));
@@ -586,10 +586,11 @@ static void atm_tc_destroy(struct Qdisc *sch)
        struct atm_flow_data *flow;
 
        pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
+       for (flow = p->flows; flow; flow = flow->next)
+               tcf_destroy_chain(&flow->filter_list);
+
        /* races ? */
        while ((flow = p->flows)) {
-               tcf_destroy_chain(flow->filter_list);
-               flow->filter_list = NULL;
                if (flow->ref > 1)
                        printk(KERN_ERR "atm_destroy: %p->ref = %d\n", flow,
                               flow->ref);
index 09969c1fbc08f287cb8b6bbc749e8a360fb9ea26..2a3c97f7dc630a7a44864f3af7b0c15d0186791b 100644 (file)
@@ -1704,7 +1704,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl)
 
        BUG_TRAP(!cl->filters);
 
-       tcf_destroy_chain(cl->filter_list);
+       tcf_destroy_chain(&cl->filter_list);
        qdisc_destroy(cl->q);
        qdisc_put_rtab(cl->R_tab);
        gen_kill_estimator(&cl->bstats, &cl->rate_est);
@@ -1728,10 +1728,8 @@ cbq_destroy(struct Qdisc* sch)
         * be bound to classes which have been destroyed already. --TGR '04
         */
        for (h = 0; h < 16; h++) {
-               for (cl = q->classes[h]; cl; cl = cl->next) {
-                       tcf_destroy_chain(cl->filter_list);
-                       cl->filter_list = NULL;
-               }
+               for (cl = q->classes[h]; cl; cl = cl->next)
+                       tcf_destroy_chain(&cl->filter_list);
        }
        for (h = 0; h < 16; h++) {
                struct cbq_class *next;
index 64465bacbe79e62c9515150b4baa44fa2d6bcff3..c4c1317cd47db91c56310db02bf933f3b521e722 100644 (file)
@@ -416,7 +416,7 @@ static void dsmark_destroy(struct Qdisc *sch)
 
        pr_debug("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p);
 
-       tcf_destroy_chain(p->filter_list);
+       tcf_destroy_chain(&p->filter_list);
        qdisc_destroy(p->q);
        kfree(p->mask);
 }
index d355e5e47fe3a71aca1d151db1ce72429a069297..13afa7214392a74998ebbad3576ae4bb7a6d4638 100644 (file)
@@ -468,7 +468,7 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
 
        return sch;
 errout:
-       return ERR_PTR(-err);
+       return ERR_PTR(err);
 }
 
 struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops,
index fdfaa3fcc16d861ed2b14dc3511bea66cf206611..e817aa00441d4a7b5a647450405e202f485bdc88 100644 (file)
@@ -1123,7 +1123,7 @@ hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl)
 {
        struct hfsc_sched *q = qdisc_priv(sch);
 
-       tcf_destroy_chain(cl->filter_list);
+       tcf_destroy_chain(&cl->filter_list);
        qdisc_destroy(cl->qdisc);
        gen_kill_estimator(&cl->bstats, &cl->rate_est);
        if (cl != &q->root)
@@ -1540,6 +1540,10 @@ hfsc_destroy_qdisc(struct Qdisc *sch)
        struct hfsc_class *cl, *next;
        unsigned int i;
 
+       for (i = 0; i < HFSC_HSIZE; i++) {
+               list_for_each_entry(cl, &q->clhash[i], hlist)
+                       tcf_destroy_chain(&cl->filter_list);
+       }
        for (i = 0; i < HFSC_HSIZE; i++) {
                list_for_each_entry_safe(cl, next, &q->clhash[i], hlist)
                        hfsc_destroy_class(sch, cl);
index 6807c97985a54adac52ceb42d4b3847e0beebdd2..3fb58f428f724ca9a8fd8c6cd9a41450df567c4d 100644 (file)
@@ -1238,7 +1238,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
        qdisc_put_rtab(cl->rate);
        qdisc_put_rtab(cl->ceil);
 
-       tcf_destroy_chain(cl->filter_list);
+       tcf_destroy_chain(&cl->filter_list);
 
        while (!list_empty(&cl->children))
                htb_destroy_class(sch, list_entry(cl->children.next,
@@ -1267,7 +1267,7 @@ static void htb_destroy(struct Qdisc *sch)
           and surprisingly it worked in 2.4. But it must precede it
           because filter need its target class alive to be able to call
           unbind_filter on it (without Oops). */
-       tcf_destroy_chain(q->filter_list);
+       tcf_destroy_chain(&q->filter_list);
 
        while (!list_empty(&q->root))
                htb_destroy_class(sch, list_entry(q->root.next,
index 274b1ddb160c3956da169dd1bbc7da5e5f482637..956c80ad59654caa20fe7a805418f02992209465 100644 (file)
@@ -104,7 +104,7 @@ static void ingress_destroy(struct Qdisc *sch)
 {
        struct ingress_qdisc_data *p = qdisc_priv(sch);
 
-       tcf_destroy_chain(p->filter_list);
+       tcf_destroy_chain(&p->filter_list);
 }
 
 static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
index 4aa2b45dad0a80232ed1d1d1c2fbabf33b19ec8f..5532f1031ab52fd3276f37b383967986de070ea9 100644 (file)
@@ -219,7 +219,7 @@ prio_destroy(struct Qdisc* sch)
        int prio;
        struct prio_sched_data *q = qdisc_priv(sch);
 
-       tcf_destroy_chain(q->filter_list);
+       tcf_destroy_chain(&q->filter_list);
        for (prio=0; prio<q->bands; prio++)
                qdisc_destroy(q->queues[prio]);
 }
index f0463d757a98489f5b12138c0026d1b91742fd9d..6a97afbfb95245cc019f371606f36884e4e63b25 100644 (file)
@@ -520,7 +520,7 @@ static void sfq_destroy(struct Qdisc *sch)
 {
        struct sfq_sched_data *q = qdisc_priv(sch);
 
-       tcf_destroy_chain(q->filter_list);
+       tcf_destroy_chain(&q->filter_list);
        q->perturb_period = 0;
        del_timer_sync(&q->perturb_timer);
 }
index e7e3baf7009ed7d8bca62e4353eebd62b70be7ba..0dbcde6758ea3158216e37af50df35ea56c37135 100644 (file)
@@ -4401,7 +4401,9 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
        if (copy_from_user(&getaddrs, optval, len))
                return -EFAULT;
 
-       if (getaddrs.addr_num <= 0) return -EINVAL;
+       if (getaddrs.addr_num <= 0 ||
+           getaddrs.addr_num >= (INT_MAX / sizeof(union sctp_addr)))
+               return -EINVAL;
        /*
         *  For UDP-style sockets, id specifies the association to query.
         *  If the id field is set to the value '0' then the locally bound
index 657835f227d342a2eadc4498c6076b7c435839ac..783317dacd3090f7d602b3c56e82859f3cc22a46 100644 (file)
@@ -487,8 +487,8 @@ static int unix_socketpair(struct socket *, struct socket *);
 static int unix_accept(struct socket *, struct socket *, int);
 static int unix_getname(struct socket *, struct sockaddr *, int *, int);
 static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
-static unsigned int unix_datagram_poll(struct file *, struct socket *,
-                                      poll_table *);
+static unsigned int unix_dgram_poll(struct file *, struct socket *,
+                                   poll_table *);
 static int unix_ioctl(struct socket *, unsigned int, unsigned long);
 static int unix_shutdown(struct socket *, int);
 static int unix_stream_sendmsg(struct kiocb *, struct socket *,
@@ -534,7 +534,7 @@ static const struct proto_ops unix_dgram_ops = {
        .socketpair =   unix_socketpair,
        .accept =       sock_no_accept,
        .getname =      unix_getname,
-       .poll =         unix_datagram_poll,
+       .poll =         unix_dgram_poll,
        .ioctl =        unix_ioctl,
        .listen =       sock_no_listen,
        .shutdown =     unix_shutdown,
@@ -555,7 +555,7 @@ static const struct proto_ops unix_seqpacket_ops = {
        .socketpair =   unix_socketpair,
        .accept =       unix_accept,
        .getname =      unix_getname,
-       .poll =         unix_datagram_poll,
+       .poll =         unix_dgram_poll,
        .ioctl =        unix_ioctl,
        .listen =       unix_listen,
        .shutdown =     unix_shutdown,
@@ -1994,29 +1994,13 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
        return mask;
 }
 
-static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
-                                      poll_table *wait)
+static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
+                                   poll_table *wait)
 {
-       struct sock *sk = sock->sk, *peer;
-       unsigned int mask;
+       struct sock *sk = sock->sk, *other;
+       unsigned int mask, writable;
 
        poll_wait(file, sk->sk_sleep, wait);
-
-       peer = unix_peer_get(sk);
-       if (peer) {
-               if (peer != sk) {
-                       /*
-                        * Writability of a connected socket additionally
-                        * depends on the state of the receive queue of the
-                        * peer.
-                        */
-                       poll_wait(file, &unix_sk(peer)->peer_wait, wait);
-               } else {
-                       sock_put(peer);
-                       peer = NULL;
-               }
-       }
-
        mask = 0;
 
        /* exceptional events? */
@@ -2042,14 +2026,26 @@ static unsigned int unix_datagram_poll(struct file *file, struct socket *sock,
        }
 
        /* writable? */
-       if (unix_writable(sk) && !(peer && unix_recvq_full(peer)))
+       writable = unix_writable(sk);
+       if (writable) {
+               other = unix_peer_get(sk);
+               if (other) {
+                       if (unix_peer(other) != sk) {
+                               poll_wait(file, &unix_sk(other)->peer_wait,
+                                         wait);
+                               if (unix_recvq_full(other))
+                                       writable = 0;
+                       }
+
+                       sock_put(other);
+               }
+       }
+
+       if (writable)
                mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
        else
                set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
 
-       if (peer)
-               sock_put(peer);
-
        return mask;
 }
 
index 185488da246647c06bd85261f856a71fed182c34..855bff4b3250a0eb04b094b5fca6c5512ecb35b1 100644 (file)
@@ -80,6 +80,23 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = {
                                     IEEE80211_CHAN_RADAR),
 };
 
+static const struct ieee80211_channel_range ieee80211_EU_channels[] = {
+       /* IEEE 802.11b/g, channels 1..13 */
+       RANGE_PWR(2412, 2472, 20, 6, 0),
+       /* IEEE 802.11a, channel 36*/
+       RANGE_PWR(5180, 5180, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN),
+       /* IEEE 802.11a, channel 40*/
+       RANGE_PWR(5200, 5200, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN),
+       /* IEEE 802.11a, channel 44*/
+       RANGE_PWR(5220, 5220, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN),
+       /* IEEE 802.11a, channels 48..64 */
+       RANGE_PWR(5240, 5320, 23, 6, IEEE80211_CHAN_NO_IBSS |
+                                    IEEE80211_CHAN_RADAR),
+       /* IEEE 802.11a, channels 100..140 */
+       RANGE_PWR(5500, 5700, 30, 6, IEEE80211_CHAN_NO_IBSS |
+                                    IEEE80211_CHAN_RADAR),
+};
+
 #define REGDOM(_code)                                                  \
        {                                                               \
                .code = __stringify(_code),                             \
@@ -90,6 +107,7 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = {
 static const struct ieee80211_regdomain ieee80211_regdoms[] = {
        REGDOM(US),
        REGDOM(JP),
+       REGDOM(EU),
 };
 
 
index 91d14224f6b332de1119d89bc07bff76c00f37cc..73d4572d136bb893da5435ecc97313a52ccb7ba0 100644 (file)
@@ -925,7 +925,7 @@ static unsigned char als4000_saved_regs[] = {
 static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
 {
        unsigned char *val = chip->saved_regs;
-       snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
+       snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return);
        for (; num_regs; num_regs--)
                *val++ = snd_sbmixer_read(chip, *regs++);
 }
@@ -933,7 +933,7 @@ static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
 static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
 {
        unsigned char *val = chip->saved_regs;
-       snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
+       snd_assert(num_regs <= ARRAY_SIZE(chip->saved_regs), return);
        for (; num_regs; num_regs--)
                snd_sbmixer_write(chip, *regs++, *val++);
 }
index 56f87cd33c19fcef9f5afb08bc472042a04a89fa..3f00ddf450f81c287b198cdbdf4c8a17b180c4f8 100644 (file)
@@ -316,6 +316,8 @@ static int __devinit snd_aw2_create(struct snd_card *card,
                return -ENOMEM;
        }
 
+       /* (2) initialization of the chip hardware */
+       snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
 
        if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
                        IRQF_SHARED, "Audiowerk2", chip)) {
@@ -329,8 +331,6 @@ static int __devinit snd_aw2_create(struct snd_card *card,
        }
        chip->irq = pci->irq;
 
-       /* (2) initialization of the chip hardware */
-       snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
        if (err < 0) {
                free_irq(chip->irq, (void *)chip);
index 98778cb69c6ef923abb85a0dc464118a2d294dda..1dcf9f3d110717582db05ce3bc9f7f808a2e32ba 100644 (file)
@@ -269,28 +269,9 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
        }
 }
 
-static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector)
+static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi)
 {
-       int i;
-
-       for (i = 0; i < IOAPIC_NUM_PINS; i++)
-               if (ioapic->redirtbl[i].fields.vector == vector)
-                       return i;
-       return -1;
-}
-
-void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
-{
-       struct kvm_ioapic *ioapic = kvm->arch.vioapic;
        union ioapic_redir_entry *ent;
-       int gsi;
-
-       gsi = get_eoi_gsi(ioapic, vector);
-       if (gsi == -1) {
-               printk(KERN_WARNING "Can't find redir item for %d EOI\n",
-                      vector);
-               return;
-       }
 
        ent = &ioapic->redirtbl[gsi];
        ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
@@ -300,6 +281,16 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
                ioapic_deliver(ioapic, gsi);
 }
 
+void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
+{
+       struct kvm_ioapic *ioapic = kvm->arch.vioapic;
+       int i;
+
+       for (i = 0; i < IOAPIC_NUM_PINS; i++)
+               if (ioapic->redirtbl[i].fields.vector == vector)
+                       __kvm_ioapic_update_eoi(ioapic, i);
+}
+
 static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr)
 {
        struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private;