]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Sat, 3 Jun 2006 16:12:50 +0000 (09:12 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sat, 3 Jun 2006 16:12:50 +0000 (09:12 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
  [SCSI] scsi_lib.c: properly count the number of pages in scsi_req_map_sg()
  [SCSI] scsi_transport_sas: make write attrs writeable
  [SCSI] scsi_transport_sas; fix user_scan
  [SCSI] ppa: fix for machines with highmem
  [SCSI] mptspi: reset handler shouldn't be called for other bus protocols
  [SCSI] Blacklist entry for HP dat changer

309 files changed:
Documentation/dvb/get_dvb_firmware
Documentation/firmware_class/README
Documentation/firmware_class/firmware_sample_driver.c
Documentation/serial/driver
Documentation/watchdog/watchdog-api.txt
MAINTAINERS
Makefile
arch/arm/mach-ixp23xx/core.c
arch/arm/mach-pxa/mainstone.c
arch/arm/mach-s3c2410/sleep.S
arch/arm/mm/mm-armv.c
arch/arm/mm/proc-xsc3.S
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/apic.c
arch/i386/kernel/syscall_table.S
arch/i386/kernel/traps.c
arch/i386/mach-generic/probe.c
arch/i386/mm/init.c
arch/i386/power/cpu.c
arch/mips/Kconfig
arch/mips/au1000/common/irq.c
arch/mips/au1000/common/time.c
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/entry.S
arch/mips/kernel/gdb-low.S
arch/mips/kernel/proc.c
arch/mips/kernel/signal-common.h
arch/mips/kernel/syscall.c
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/mm/c-r4k.c
arch/mips/mm/pg-r4k.c
arch/mips/mm/tlbex.c
arch/mips/oprofile/common.c
arch/mips/oprofile/op_model_mipsxx.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/systbl.S
arch/powerpc/platforms/cell/spu_callbacks.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/setup.c
arch/ppc/kernel/asm-offsets.c
arch/ppc/platforms/mpc8272ads_setup.c
arch/ppc/syslib/pq2_devices.c
arch/ppc/syslib/pq2_sys.c
arch/s390/kernel/time.c
arch/sparc/kernel/systbls.S
arch/sparc64/kernel/head.S
arch/sparc64/kernel/pci_iommu.c
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/systbls.S
arch/x86_64/ia32/ia32_binfmt.c
arch/x86_64/kernel/e820.c
arch/x86_64/kernel/entry.S
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/pci-dma.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/pmtimer.c
arch/x86_64/kernel/setup.c
arch/x86_64/mm/srat.c
block/cfq-iosched.c
block/ll_rw_blk.c
drivers/base/firmware_class.c
drivers/base/power/suspend.c
drivers/char/agp/Kconfig
drivers/char/agp/amd64-agp.c
drivers/char/agp/via-agp.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/tpm/tpm_bios.c
drivers/char/tpm/tpm_tis.c
drivers/char/tty_io.c
drivers/char/vt.c
drivers/char/watchdog/i8xx_tco.c
drivers/char/watchdog/s3c2410_wdt.c
drivers/char/watchdog/sc1200wdt.c
drivers/i2c/busses/scx200_acb.c
drivers/ide/pci/sgiioc4.c
drivers/ide/ppc/pmac.c
drivers/infiniband/core/uverbs_mem.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_eeprom.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/infiniband/hw/ipath/ipath_ht400.c
drivers/infiniband/hw/ipath/ipath_init_chip.c
drivers/infiniband/hw/ipath/ipath_kernel.h
drivers/infiniband/hw/ipath/ipath_keys.c
drivers/infiniband/hw/ipath/ipath_layer.c
drivers/infiniband/hw/ipath/ipath_pe800.c
drivers/infiniband/hw/ipath/ipath_qp.c
drivers/infiniband/hw/ipath/ipath_rc.c
drivers/infiniband/hw/ipath/ipath_ruc.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/mthca/mthca_cmd.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/input/joystick/sidewinder.c
drivers/input/keyboard/corgikbd.c
drivers/input/keyboard/spitzkbd.c
drivers/input/misc/wistron_btns.c
drivers/input/mouse/alps.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/logips2pp.c
drivers/input/touchscreen/ads7846.c
drivers/isdn/i4l/isdn_tty.c
drivers/md/md.c
drivers/md/raid0.c
drivers/media/Kconfig
drivers/media/common/Kconfig
drivers/media/dvb/Kconfig
drivers/media/dvb/b2c2/Kconfig
drivers/media/dvb/bt8xx/Kconfig
drivers/media/dvb/bt8xx/dvb-bt8xx.c
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/frontends/cx24123.c
drivers/media/dvb/frontends/dvb-pll.c
drivers/media/dvb/pluto2/Kconfig
drivers/media/dvb/pluto2/Makefile
drivers/media/dvb/ttpci/Kconfig
drivers/media/dvb/ttpci/budget-av.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
drivers/media/radio/Kconfig
drivers/media/video/Kconfig
drivers/media/video/Makefile
drivers/media/video/bt8xx/Kconfig
drivers/media/video/bt8xx/Makefile
drivers/media/video/bt8xx/bttv-cards.c
drivers/media/video/bt8xx/bttv-risc.c
drivers/media/video/cx25840/cx25840-firmware.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-core.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/em28xx/Kconfig
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/et61x251/Kconfig
drivers/media/video/pwc/Kconfig
drivers/media/video/pwc/Makefile
drivers/media/video/saa7127.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-core.c
drivers/media/video/saa7134/saa7134-video.c
drivers/media/video/sn9c102/Kconfig
drivers/media/video/tuner-types.c
drivers/media/video/tveeprom.c
drivers/media/video/usbvideo/Kconfig
drivers/media/video/vivi.c
drivers/media/video/zc0301/Kconfig
drivers/mmc/au1xmmc.c
drivers/mmc/imxmmc.c
drivers/mmc/mmc.c
drivers/mmc/mmc_block.c
drivers/mmc/pxamci.c
drivers/mmc/wbsd.c
drivers/net/bnx2.c
drivers/net/e1000/e1000_main.c
drivers/net/forcedeth.c
drivers/net/irda/Kconfig
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcnet32.c
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/sky2.h
drivers/net/tg3.c
drivers/net/tulip/winbond-840.c
drivers/net/via-rhine.c
drivers/net/wireless/arlan-main.c
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/orinoco.c
drivers/net/wireless/wavelan.c
drivers/pci/pci-acpi.c
drivers/pcmcia/pd6729.c
drivers/rtc/rtc-dev.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-test.c
drivers/rtc/rtc-vr41xx.c
drivers/s390/net/ctcmain.c
drivers/s390/net/ctctty.c
drivers/s390/net/cu3088.c
drivers/s390/net/iucv.c
drivers/s390/net/iucv.h
drivers/s390/net/lcs.c
drivers/s390/net/lcs.h
drivers/s390/net/netiucv.c
drivers/s390/net/qeth.h
drivers/s390/net/qeth_eddp.c
drivers/s390/net/qeth_fs.h
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_mpc.h
drivers/s390/net/qeth_proc.c
drivers/s390/net/qeth_sys.c
drivers/s390/net/qeth_tso.h
drivers/scsi/libata-core.c
drivers/scsi/sata_mv.c
drivers/scsi/st.c
drivers/serial/cpm_uart/cpm_uart_core.c
drivers/serial/cpm_uart/cpm_uart_cpm2.c
drivers/serial/sunsu.c
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/pxa2xx_spi.c
drivers/spi/spi.c
drivers/spi/spi_butterfly.c
drivers/spi/spi_mpc83xx.c [new file with mode: 0644]
drivers/spi/spi_s3c24xx.c [new file with mode: 0644]
drivers/spi/spi_s3c24xx_gpio.c [new file with mode: 0644]
drivers/usb/input/hiddev.c
drivers/video/au1100fb.c
drivers/video/console/fbcon.c
drivers/video/i810/i810_main.c
drivers/video/matrox/g450_pll.c
drivers/video/matrox/matroxfb_DAC1064.h
drivers/video/matrox/matroxfb_base.h
drivers/video/maxinefb.c
fs/affs/namei.c
fs/binfmt_flat.c
fs/bio.c
fs/cifs/CHANGES
fs/cifs/cifsfs.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/compat.c
fs/exportfs/expfs.c
fs/ext3/resize.c
fs/inotify.c
fs/jfs/jfs_metapage.c
fs/nfsd/export.c
fs/nfsd/vfs.c
include/asm-alpha/termbits.h
include/asm-arm/arch-ixp23xx/memory.h
include/asm-arm/arch-pxa/pxa2xx_spi.h
include/asm-arm/arch-s3c2410/spi-gpio.h [new file with mode: 0644]
include/asm-arm/arch-s3c2410/spi.h [new file with mode: 0644]
include/asm-arm/spinlock.h
include/asm-arm/system.h
include/asm-generic/pgtable.h
include/asm-mips/cpu.h
include/asm-mips/futex.h
include/asm-mips/inst.h
include/asm-mips/mipsregs.h
include/asm-mips/pgtable.h
include/asm-mips/sigcontext.h
include/asm-powerpc/termbits.h
include/asm-powerpc/unistd.h
include/asm-sparc/unistd.h
include/asm-sparc64/dma-mapping.h
include/asm-sparc64/pci.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/unistd.h
include/asm-x86_64/elf.h
include/linux/firmware.h
include/linux/fs.h
include/linux/fsl_devices.h
include/linux/input.h
include/linux/mmc/mmc.h
include/linux/mmzone.h
include/linux/pci_ids.h
include/linux/syscalls.h
include/linux/videodev2.h
include/linux/vt_kern.h
include/net/compat.h
include/net/irda/irlmp.h
include/net/sctp/command.h
include/net/sctp/sctp.h
kernel/cpuset.c
kernel/hrtimer.c
kernel/sched.c
kernel/timer.c
lib/kobject.c
mm/memory_hotplug.c
mm/page_alloc.c
mm/slab.c
mm/sparse.c
net/bridge/br.c
net/core/dev.c
net/ipv4/ipcomp.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c
net/ipv4/netfilter/ip_conntrack_helper_pptp.c
net/ipv4/netfilter/ip_nat_snmp_basic.c
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
net/ipv4/tcp_highspeed.c
net/ipv4/xfrm4_policy.c
net/ipv6/ipcomp6.c
net/ipv6/route.c
net/irda/iriap.c
net/sctp/input.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sunrpc/cache.c
net/xfrm/xfrm_input.c
scripts/mod/modpost.c
scripts/mod/modpost.h
security/selinux/hooks.c
sound/drivers/mpu401/mpu401.c
sound/isa/es18xx.c
sound/oss/ad1848.c
sound/oss/nm256_audio.c

index 15fc8fbef67e3fa48a8d68365b1852103e501115..4820366b6ae899667cf0589b789661d990eda7cc 100644 (file)
@@ -259,9 +259,9 @@ sub dibusb {
 }
 
 sub nxt2002 {
-    my $sourcefile = "Broadband4PC_4_2_11.zip";
+    my $sourcefile = "Technisat_DVB-PC_4_4_COMPACT.zip";
     my $url = "http://www.bbti.us/download/windows/$sourcefile";
-    my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a";
+    my $hash = "476befae8c7c1bb9648954060b1eec1f";
     my $outfile = "dvb-fe-nxt2002.fw";
     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
 
@@ -269,8 +269,8 @@ sub nxt2002 {
 
     wgetfile($sourcefile, $url);
     unzip($sourcefile, $tmpdir);
-    verify("$tmpdir/SkyNETU.sys", $hash);
-    extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile);
+    verify("$tmpdir/SkyNET.sys", $hash);
+    extract("$tmpdir/SkyNET.sys", 331624, 5908, $outfile);
 
     $outfile;
 }
index 43e836c07ae89ee817ad75fe33e9cd37ea5b44ae..e9cc8bb26f7d0952b0226c66e6a43abe8e00a211 100644 (file)
    on the setup, so I think that the choice on what firmware to make
    persistent should be left to userspace.
 
- - Why register_firmware()+__init can be useful:
-       - For boot devices needing firmware.
-       - To make the transition easier:
-               The firmware can be declared __init and register_firmware()
-               called on module_init. Then the firmware is warranted to be
-               there even if "firmware hotplug userspace" is not there yet or
-               it doesn't yet provide the needed firmware.
-               Once the firmware is widely available in userspace, it can be
-               removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
-
-       In either case, if firmware hotplug support is there, it can move the
-       firmware out of kernel memory into the real filesystem for later
-       usage.
-
-       Note: If persistence is implemented on top of initramfs,
-       register_firmware() may not be appropriate.
-
index ad3edaba4533cf33d5452e5b4bb877455000c05b..87feccdb5c9f8f67b2739358edca07c76a9a24a1 100644 (file)
@@ -5,8 +5,6 @@
  *
  * Sample code on how to use request_firmware() from drivers.
  *
- * Note that register_firmware() is currently useless.
- *
  */
 
 #include <linux/module.h>
 
 #include "linux/firmware.h"
 
-#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-char __init inkernel_firmware[] = "let's say that this is firmware\n";
-#endif
-
 static struct device ghost_device = {
        .bus_id    = "ghost0",
 };
@@ -104,10 +97,6 @@ static void sample_probe_async(void)
 
 static int sample_init(void)
 {
-#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-       register_firmware("sample_driver_fw", inkernel_firmware,
-                         sizeof(inkernel_firmware));
-#endif
        device_initialize(&ghost_device);
        /* since there is no real hardware insertion I just call the
         * sample probe functions here */
index df82116a9f261c35998c3bb5a69eb1a38c8d83d1..88ad615dd338d75e2b282422c8f2d6f7f3af80b7 100644 (file)
@@ -214,12 +214,13 @@ hardware.
        The interaction of the iflag bits is as follows (parity error
        given as an example):
        Parity error    INPCK   IGNPAR
-       None            n/a     n/a     character received
-       Yes             n/a     0       character discarded
-       Yes             0       1       character received, marked as
+       n/a             0       n/a     character received, marked as
                                        TTY_NORMAL
-       Yes             1       1       character received, marked as
+       None            1       n/a     character received, marked as
+                                       TTY_NORMAL
+       Yes             1       0       character received, marked as
                                        TTY_PARITY
+       Yes             1       1       character discarded
 
        Other flags may be used (eg, xon/xoff characters) if your
        hardware supports hardware "soft" flow control.
index c5beb548cfc42b781fd825ff9345f411f087897d..21ed5117366240d2a33af5af7f5605733bd514c1 100644 (file)
@@ -36,6 +36,9 @@ timeout or margin.  The simplest way to ping the watchdog is to write
 some data to the device.  So a very simple watchdog daemon would look
 like this:
 
+#include <stdlib.h>
+#include <fcntl.h>
+
 int main(int argc, const char *argv[]) {
        int fd=open("/dev/watchdog",O_WRONLY);
        if (fd==-1) {
index 753584cf4e7e30a50224a8e908dc6fa695e2336f..74d71cafb17c313bf82a51b86495bfcaadf4dcf5 100644 (file)
@@ -40,11 +40,20 @@ trivial patch so apply some common sense.
        PLEASE document known bugs. If it doesn't work for everything
        or does something very odd once a month document it.
 
+       PLEASE remember that submissions must be made under the terms
+       of the OSDL certificate of contribution
+       (http://www.osdl.org/newsroom/press_releases/2004/2004_05_24_dco.html)
+       and should include a Signed-off-by: line.
+
 6.     Make sure you have the right to send any changes you make. If you
        do changes at work you may find your employer owns the patch
        not you.
 
-7.     Happy hacking.
+7.     When sending security related changes or reports to a maintainer
+       please Cc: security@kernel.org, especially if the maintainer
+       does not respond.
+
+8.     Happy hacking.
 
                -----------------------------------
 
@@ -556,7 +565,7 @@ BROADBAND PROCESSOR ARCHITECTURE
 P:     Arnd Bergmann
 M:     arnd@arndb.de
 L:     linuxppc-dev@ozlabs.org
-W:     http://linuxppc64.org
+W:     http://www.penguinppc.org/ppc64/
 S:     Supported
 
 BTTV VIDEO4LINUX DRIVER
@@ -969,7 +978,7 @@ S:  Maintained
 EXT3 FILE SYSTEM
 P:     Stephen Tweedie, Andrew Morton
 M:     sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com
-L:     ext3-users@redhat.com
+L:     ext2-devel@lists.sourceforge.net
 S:     Maintained
 
 F71805F HARDWARE MONITORING DRIVER
@@ -1530,12 +1539,28 @@ W:      http://jfs.sourceforge.net/
 T:     git kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git
 S:     Supported
 
+JOURNALLING LAYER FOR BLOCK DEVICS (JBD)
+P:     Stephen Tweedie, Andrew Morton
+M:     sct@redhat.com, akpm@osdl.org
+L:     ext2-devel@lists.sourceforge.net
+S:     Maintained
+
 KCONFIG
 P:     Roman Zippel
 M:     zippel@linux-m68k.org
 L:     kbuild-devel@lists.sourceforge.net
 S:     Maintained
 
+KDUMP
+P:     Vivek Goyal
+M:     vgoyal@in.ibm.com
+P:     Haren Myneni
+M:     hbabu@us.ibm.com
+L:     fastboot@lists.osdl.org
+L:     linux-kernel@vger.kernel.org
+W:     http://lse.sourceforge.net/kdump/
+S:     Maintained
+
 KERNEL AUTOMOUNTER (AUTOFS)
 P:     H. Peter Anvin
 M:     hpa@zytor.com
@@ -1691,7 +1716,7 @@ M:        paulus@au.ibm.com
 P:     Anton Blanchard
 M:     anton@samba.org
 M:     anton@au.ibm.com
-W:     http://linuxppc64.org
+W:     http://www.penguinppc.org/ppc64/
 L:     linuxppc-dev@ozlabs.org
 S:     Supported
 
@@ -1874,6 +1899,12 @@ M:       James.Bottomley@HansenPartnership.com
 L:     linux-scsi@vger.kernel.org
 S:     Maintained
 
+NETEM NETWORK EMULATOR
+P:     Stephen Hemminger
+M:     shemminger@osdl.org
+L:     netem@osdl.org
+S:     Maintained
+
 NETFILTER/IPTABLES/IPCHAINS
 P:     Rusty Russell
 P:     Marc Boucher
index 3494c17c9fb9fe437134057e01bac2f4ffc887aa..435d209f42d817381f6da6734c776a2066f276f7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 17
-EXTRAVERSION =-rc4
-NAME=Sliding Snow Leopard
+EXTRAVERSION =-rc5
+NAME=Lordi Rules
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
index 092ee12ced425dcfaaff125a4f8f4cc3324c85c3..affd1d5d744049c44c19d8214d74478317ccc672 100644 (file)
@@ -178,8 +178,12 @@ static int ixp23xx_irq_set_type(unsigned int irq, unsigned int type)
 
 static void ixp23xx_irq_mask(unsigned int irq)
 {
-       volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+       volatile unsigned long *intr_reg;
 
+       if (irq >= 56)
+               irq += 8;
+
+       intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
        *intr_reg &= ~(1 << (irq % 32));
 }
 
@@ -199,17 +203,25 @@ static void ixp23xx_irq_ack(unsigned int irq)
  */
 static void ixp23xx_irq_level_unmask(unsigned int irq)
 {
-       volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+       volatile unsigned long *intr_reg;
 
        ixp23xx_irq_ack(irq);
 
+       if (irq >= 56)
+               irq += 8;
+
+       intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
        *intr_reg |= (1 << (irq % 32));
 }
 
 static void ixp23xx_irq_edge_unmask(unsigned int irq)
 {
-       volatile unsigned long *intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
+       volatile unsigned long *intr_reg;
+
+       if (irq >= 56)
+               irq += 8;
 
+       intr_reg = IXP23XX_INTR_EN1 + (irq / 32);
        *intr_reg |= (1 << (irq % 32));
 }
 
index 98356f810007fad31d4fdc2cc39bea2e9b1b5c68..02e188d98e7d6d8565c4d06a2ddf9988776126e1 100644 (file)
@@ -95,7 +95,10 @@ static void __init mainstone_init_irq(void)
        for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
                set_irq_chip(irq, &mainstone_irq_chip);
                set_irq_handler(irq, do_level_IRQ);
-               set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+               if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14))
+                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
+               else
+                       set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
        }
        set_irq_flags(MAINSTONE_IRQ(8), 0);
        set_irq_flags(MAINSTONE_IRQ(12), 0);
index 832fb86a03b430343dd26e9e5be83168ab644c17..73de2eaca22a1c136db339177eb95d1acc4a7610 100644 (file)
@@ -59,8 +59,7 @@ ENTRY(s3c2410_cpu_suspend)
        mrc     p15, 0, r5, c13, c0, 0  @ PID
        mrc     p15, 0, r6, c3, c0, 0   @ Domain ID
        mrc     p15, 0, r7, c2, c0, 0   @ translation table base address
-       mrc     p15, 0, r8, c2, c0, 0   @ auxiliary control register
-       mrc     p15, 0, r9, c1, c0, 0   @ control register
+       mrc     p15, 0, r8, c1, c0, 0   @ control register
 
        stmia   r0, { r4 - r13 }
 
@@ -165,7 +164,6 @@ ENTRY(s3c2410_cpu_resume)
        mcr     p15, 0, r5, c13, c0, 0          @ PID
        mcr     p15, 0, r6, c3, c0, 0           @ Domain ID
        mcr     p15, 0, r7, c2, c0, 0           @ translation table base
-       mcr     p15, 0, r8, c1, c1, 0           @ auxilliary control
 
 #ifdef CONFIG_DEBUG_RESUME
        mov     r3, #'R'
@@ -173,7 +171,7 @@ ENTRY(s3c2410_cpu_resume)
 #endif
 
        ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, etc
+       mcr     p15, 0, r8, c1, c0, 0           @ turn on MMU, etc
        nop                                     @ second-to-last before mmu
        mov     pc, r2                          @ go back to virtual address
 
index f14b2d0f3690a002cf396bfa521c57eae068a242..95273de4f772515780e2eac97ed2ae892ac52a0d 100644 (file)
@@ -376,7 +376,7 @@ void __init build_mem_type_table(void)
                ecc_mask = 0;
        }
 
-       if (cpu_arch <= CPU_ARCH_ARMv5TEJ) {
+       if (cpu_arch <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) {
                for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
                        if (mem_types[i].prot_l1)
                                mem_types[i].prot_l1 |= PMD_BIT4;
@@ -631,7 +631,7 @@ void setup_mm_for_reboot(char mode)
                pgd = init_mm.pgd;
 
        base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
-       if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ)
+       if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
                base_pmdval |= PMD_BIT4;
 
        for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) {
index 80873b36c3f7a562657a32d9de47e790972cb2d9..8d32e21fe151a919630dc866205974888b624e3a 100644 (file)
@@ -427,12 +427,13 @@ __xsc3_setup:
 #endif
        mcr     p15, 0, r0, c1, c0, 1           @ set auxiliary control reg
        mrc     p15, 0, r0, c1, c0, 0           @ get control register
-       bic     r0, r0, #0x0200                 @ .... ..R. .... ....
        bic     r0, r0, #0x0002                 @ .... .... .... ..A.
        orr     r0, r0, #0x0005                 @ .... .... .... .C.M
 #if BTB_ENABLE
+       bic     r0, r0, #0x0200                 @ .... ..R. .... ....
        orr     r0, r0, #0x3900                 @ ..VI Z..S .... ....
 #else
+       bic     r0, r0, #0x0a00                 @ .... Z.R. .... ....
        orr     r0, r0, #0x3100                 @ ..VI ...S .... ....
 #endif
 #if L2_CACHE_ENABLE
index daee69579b1c6cd6dba672b79c48a2197453f56a..40e5aba3ad3d425f1545ff7e199e1356a56e38d8 100644 (file)
@@ -1066,14 +1066,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
                     DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
                     },
         },
-       {
-        .callback = disable_acpi_pci,
-        .ident = "HP xw9300",
-        .matches = {
-                   DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                   DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"),
-                   },
-       },
        {}
 };
 
index 013b85df18c658a87e408fd137fb7b30e32c9c26..3d4b2f3d116a796ffad8ef911353b6a71a2f43b7 100644 (file)
@@ -1341,6 +1341,14 @@ int __init APIC_init_uniprocessor (void)
 
        connect_bsp_APIC();
 
+       /*
+        * Hack: In case of kdump, after a crash, kernel might be booting
+        * on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
+        * might be zero if read from MP tables. Get it from LAPIC.
+        */
+#ifdef CONFIG_CRASH_DUMP
+       boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
+#endif
        phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
 
        setup_local_APIC();
index f48bef15b4f0dd5de72d4bbcc39f8c4f881947b6..af56987f69b02503c82cdc2a48660f56db02153a 100644 (file)
@@ -315,3 +315,4 @@ ENTRY(sys_call_table)
        .long sys_splice
        .long sys_sync_file_range
        .long sys_tee                   /* 315 */
+       .long sys_vmsplice
index 2d22f5761b1dc51ac6bee90789e1e867ad62e779..0e498369f35e916e547485db5f8fed45e3d80055 100644 (file)
@@ -130,9 +130,8 @@ static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl,
        print_symbol("%s", addr);
 
        printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS;
-
        if (printed)
-               printk("  ");
+               printk(" ");
        else
                printk("\n");
 
@@ -212,7 +211,6 @@ static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
        }
 
        stack = esp;
-       printk(log_lvl);
        for(i = 0; i < kstack_depth_to_print; i++) {
                if (kstack_end(stack))
                        break;
index cea5b3ce4b5766c9747294090542e4eb063b75eb..d55fa7b187ab656f9c581b11c5dfc12f7186f82e 100644 (file)
@@ -93,9 +93,11 @@ int __init mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid
        int i;
        for (i = 0; apic_probe[i]; ++i) { 
                if (apic_probe[i]->mps_oem_check(mpc,oem,productid)) { 
-                       genapic = apic_probe[i];
-                       printk(KERN_INFO "Switched to APIC driver `%s'.\n", 
-                              genapic->name);
+                       if (!cmdline_apic) {
+                               genapic = apic_probe[i];
+                               printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+                                      genapic->name);
+                       }
                        return 1;
                } 
        } 
@@ -107,9 +109,11 @@ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
        int i;
        for (i = 0; apic_probe[i]; ++i) { 
                if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) { 
-                       genapic = apic_probe[i];
-                       printk(KERN_INFO "Switched to APIC driver `%s'.\n", 
-                              genapic->name);
+                       if (!cmdline_apic) {
+                               genapic = apic_probe[i];
+                               printk(KERN_INFO "Switched to APIC driver `%s'.\n",
+                                      genapic->name);
+                       }
                        return 1;
                } 
        } 
index ae6534ad816113d40b05cc514e2626adf26a5de6..3df1371d4520bb39a8346f6a26326dbce9f589ec 100644 (file)
@@ -651,7 +651,7 @@ void __init mem_init(void)
  * Specifically, in the case of x86, we will always add
  * memory to the highmem for now.
  */
-#ifdef CONFIG_HOTPLUG_MEMORY
+#ifdef CONFIG_MEMORY_HOTPLUG
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 int add_memory(u64 start, u64 size)
 {
index 50a0bef8c85f691bc135167e595dc5b6521a8ec0..79b2370c7facda90db18255983dc85b58523dab0 100644 (file)
@@ -92,7 +92,7 @@ void __restore_processor_state(struct saved_context *ctxt)
        write_cr4(ctxt->cr4);
        write_cr3(ctxt->cr3);
        write_cr2(ctxt->cr2);
-       write_cr2(ctxt->cr0);
+       write_cr0(ctxt->cr0);
 
        /*
         * now restore the descriptor tables to their proper values
index ee5fbb02b28f4f56caa06531d424b8136b0e6748..e8ff09fe73d9dc0f9163f3fcec821521a08ca9c1 100644 (file)
@@ -13,7 +13,7 @@ choice
        default SGI_IP22
 
 config MIPS_MTX1
-       bool "Support for 4G Systems MTX-1 board"
+       bool "4G Systems MTX-1 board"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select SOC_AU1500
@@ -120,7 +120,7 @@ config MIPS_MIRAGE
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config MIPS_COBALT
-       bool "Support for Cobalt Server"
+       bool "Cobalt Server"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select I8259
@@ -132,7 +132,7 @@ config MIPS_COBALT
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config MACH_DECSTATION
-       bool "Support for DECstations"
+       bool "DECstations"
        select BOOT_ELF32
        select DMA_NONCOHERENT
        select EARLY_PRINTK
@@ -158,7 +158,7 @@ config MACH_DECSTATION
          otherwise choose R3000.
 
 config MIPS_EV64120
-       bool "Support for Galileo EV64120 Evaluation board (EXPERIMENTAL)"
+       bool "Galileo EV64120 Evaluation board (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        select DMA_NONCOHERENT
        select HW_HAS_PCI
@@ -175,7 +175,7 @@ config MIPS_EV64120
          kernel for this platform.
 
 config MIPS_EV96100
-       bool "Support for Galileo EV96100 Evaluation board (EXPERIMENTAL)"
+       bool "Galileo EV96100 Evaluation board (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        select DMA_NONCOHERENT
        select HW_HAS_PCI
@@ -195,7 +195,7 @@ config MIPS_EV96100
          here if you wish to build a kernel for this platform.
 
 config MIPS_IVR
-       bool "Support for Globespan IVR board"
+       bool "Globespan IVR board"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select ITE_BOARD_GEN
@@ -211,7 +211,7 @@ config MIPS_IVR
          build a kernel for this platform.
 
 config MIPS_ITE8172
-       bool "Support for ITE 8172G board"
+       bool "ITE 8172G board"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select ITE_BOARD_GEN
@@ -228,7 +228,7 @@ config MIPS_ITE8172
          a kernel for this platform.
 
 config MACH_JAZZ
-       bool "Support for the Jazz family of machines"
+       bool "Jazz family of machines"
        select ARC
        select ARC32
        select ARCH_MAY_HAVE_PC_FDC
@@ -246,7 +246,7 @@ config MACH_JAZZ
         Olivetti M700-10 workstations.
 
 config LASAT
-       bool "Support for LASAT Networks platforms"
+       bool "LASAT Networks platforms"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select MIPS_GT64120
@@ -258,7 +258,7 @@ config LASAT
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config MIPS_ATLAS
-       bool "Support for MIPS Atlas board"
+       bool "MIPS Atlas board"
        select BOOT_ELF32
        select DMA_NONCOHERENT
        select IRQ_CPU
@@ -283,7 +283,7 @@ config MIPS_ATLAS
          board.
 
 config MIPS_MALTA
-       bool "Support for MIPS Malta board"
+       bool "MIPS Malta board"
        select ARCH_MAY_HAVE_PC_FDC
        select BOOT_ELF32
        select HAVE_STD_PC_SERIAL_PORT
@@ -311,7 +311,7 @@ config MIPS_MALTA
          board.
 
 config MIPS_SEAD
-       bool "Support for MIPS SEAD board (EXPERIMENTAL)"
+       bool "MIPS SEAD board (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        select IRQ_CPU
        select DMA_NONCOHERENT
@@ -328,7 +328,7 @@ config MIPS_SEAD
          board.
 
 config MIPS_SIM
-       bool 'Support for MIPS simulator (MIPSsim)'
+       bool 'MIPS simulator (MIPSsim)'
        select DMA_NONCOHERENT
        select IRQ_CPU
        select SYS_HAS_CPU_MIPS32_R1
@@ -341,7 +341,7 @@ config MIPS_SIM
          emulator.
 
 config MOMENCO_JAGUAR_ATX
-       bool "Support for Momentum Jaguar board"
+       bool "Momentum Jaguar board"
        select BOOT_ELF32
        select DMA_NONCOHERENT
        select HW_HAS_PCI
@@ -361,7 +361,7 @@ config MOMENCO_JAGUAR_ATX
          Momentum Computer <http://www.momenco.com/>.
 
 config MOMENCO_OCELOT
-       bool "Support for Momentum Ocelot board"
+       bool "Momentum Ocelot board"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -378,7 +378,7 @@ config MOMENCO_OCELOT
          Momentum Computer <http://www.momenco.com/>.
 
 config MOMENCO_OCELOT_3
-       bool "Support for Momentum Ocelot-3 board"
+       bool "Momentum Ocelot-3 board"
        select BOOT_ELF32
        select DMA_NONCOHERENT
        select HW_HAS_PCI
@@ -397,7 +397,7 @@ config MOMENCO_OCELOT_3
          PMC-Sierra Rm79000 core.
 
 config MOMENCO_OCELOT_C
-       bool "Support for Momentum Ocelot-C board"
+       bool "Momentum Ocelot-C board"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -414,7 +414,7 @@ config MOMENCO_OCELOT_C
          Momentum Computer <http://www.momenco.com/>.
 
 config MOMENCO_OCELOT_G
-       bool "Support for Momentum Ocelot-G board"
+       bool "Momentum Ocelot-G board"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -431,23 +431,23 @@ config MOMENCO_OCELOT_G
          Momentum Computer <http://www.momenco.com/>.
 
 config MIPS_XXS1500
-       bool "Support for MyCable XXS1500 board"
+       bool "MyCable XXS1500 board"
        select DMA_NONCOHERENT
        select SOC_AU1500
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config PNX8550_V2PCI
-       bool "Support for Philips PNX8550 based Viper2-PCI board"
+       bool "Philips PNX8550 based Viper2-PCI board"
        select PNX8550
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config PNX8550_JBS
-       bool "Support for Philips PNX8550 based JBS board"
+       bool "Philips PNX8550 based JBS board"
        select PNX8550
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config DDB5074
-       bool "Support for NEC DDB Vrc-5074 (EXPERIMENTAL)"
+       bool "NEC DDB Vrc-5074 (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        select DDB5XXX_COMMON
        select DMA_NONCOHERENT
@@ -465,7 +465,7 @@ config DDB5074
          evaluation board.
 
 config DDB5476
-       bool "Support for NEC DDB Vrc-5476"
+       bool "NEC DDB Vrc-5476"
        select DDB5XXX_COMMON
        select DMA_NONCOHERENT
        select HAVE_STD_PC_SERIAL_PORT
@@ -486,7 +486,7 @@ config DDB5476
          IDE controller, PS2 keyboard, PS2 mouse, etc.
 
 config DDB5477
-       bool "Support for NEC DDB Vrc-5477"
+       bool "NEC DDB Vrc-5477"
        select DDB5XXX_COMMON
        select DMA_NONCOHERENT
        select HW_HAS_PCI
@@ -504,13 +504,13 @@ config DDB5477
          ether port USB, AC97, PCI, etc.
 
 config MACH_VR41XX
-       bool "Support for NEC VR4100 series based machines"
+       bool "NEC VR41XX-based machines"
        select SYS_HAS_CPU_VR41XX
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
 
 config PMC_YOSEMITE
-       bool "Support for PMC-Sierra Yosemite eval board"
+       bool "PMC-Sierra Yosemite eval board"
        select DMA_COHERENT
        select HW_HAS_PCI
        select IRQ_CPU
@@ -527,7 +527,7 @@ config PMC_YOSEMITE
          manufactured by PMC-Sierra.
 
 config QEMU
-       bool "Support for Qemu"
+       bool "Qemu"
        select DMA_COHERENT
        select GENERIC_ISA_DMA
        select HAVE_STD_PC_SERIAL_PORT
@@ -547,7 +547,7 @@ config QEMU
          can be found at http://www.linux-mips.org/wiki/Qemu.
 
 config SGI_IP22
-       bool "Support for SGI IP22 (Indy/Indigo2)"
+       bool "SGI IP22 (Indy/Indigo2)"
        select ARC
        select ARC32
        select BOOT_ELF32
@@ -567,7 +567,7 @@ config SGI_IP22
          that runs on these, say Y here.
 
 config SGI_IP27
-       bool "Support for SGI IP27 (Origin200/2000)"
+       bool "SGI IP27 (Origin200/2000)"
        select ARC
        select ARC64
        select BOOT_ELF64
@@ -583,7 +583,7 @@ config SGI_IP27
          here.
 
 config SGI_IP32
-       bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
+       bool "SGI IP32 (O2) (EXPERIMENTAL)"
        depends on EXPERIMENTAL
        select ARC
        select ARC32
@@ -604,7 +604,7 @@ config SGI_IP32
          If you want this kernel to run on SGI O2 workstation, say Y here.
 
 config SIBYTE_BIGSUR
-       bool "Support for Sibyte BCM91480B-BigSur"
+       bool "Sibyte BCM91480B-BigSur"
        select BOOT_ELF32
        select DMA_COHERENT
        select PCI_DOMAINS
@@ -615,7 +615,7 @@ config SIBYTE_BIGSUR
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_SWARM
-       bool "Support for Sibyte BCM91250A-SWARM"
+       bool "Sibyte BCM91250A-SWARM"
        select BOOT_ELF32
        select DMA_COHERENT
        select SIBYTE_SB1250
@@ -626,7 +626,7 @@ config SIBYTE_SWARM
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_SENTOSA
-       bool "Support for Sibyte BCM91250E-Sentosa"
+       bool "Sibyte BCM91250E-Sentosa"
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
@@ -637,7 +637,7 @@ config SIBYTE_SENTOSA
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_RHONE
-       bool "Support for Sibyte BCM91125E-Rhone"
+       bool "Sibyte BCM91125E-Rhone"
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
@@ -648,7 +648,7 @@ config SIBYTE_RHONE
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_CARMEL
-       bool "Support for Sibyte BCM91120x-Carmel"
+       bool "Sibyte BCM91120x-Carmel"
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
@@ -659,7 +659,7 @@ config SIBYTE_CARMEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_PTSWARM
-       bool "Support for Sibyte BCM91250PT-PTSWARM"
+       bool "Sibyte BCM91250PT-PTSWARM"
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
@@ -671,7 +671,7 @@ config SIBYTE_PTSWARM
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_LITTLESUR
-       bool "Support for Sibyte BCM91250C2-LittleSur"
+       bool "Sibyte BCM91250C2-LittleSur"
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
@@ -683,7 +683,7 @@ config SIBYTE_LITTLESUR
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_CRHINE
-       bool "Support for Sibyte BCM91120C-CRhine"
+       bool "Sibyte BCM91120C-CRhine"
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
@@ -694,7 +694,7 @@ config SIBYTE_CRHINE
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SIBYTE_CRHONE
-       bool "Support for Sibyte BCM91125C-CRhone"
+       bool "Sibyte BCM91125C-CRhone"
        depends on EXPERIMENTAL
        select BOOT_ELF32
        select DMA_COHERENT
@@ -706,7 +706,7 @@ config SIBYTE_CRHONE
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
 config SNI_RM200_PCI
-       bool "Support for SNI RM200 PCI"
+       bool "SNI RM200 PCI"
        select ARC
        select ARC32
        select ARCH_MAY_HAVE_PC_FDC
@@ -732,7 +732,7 @@ config SNI_RM200_PCI
          support this machine type.
 
 config TOSHIBA_JMR3927
-       bool "Support for Toshiba JMR-TX3927 board"
+       bool "Toshiba JMR-TX3927 board"
        select DMA_NONCOHERENT
        select HW_HAS_PCI
        select MIPS_TX3927
@@ -743,7 +743,7 @@ config TOSHIBA_JMR3927
        select TOSHIBA_BOARDS
 
 config TOSHIBA_RBTX4927
-       bool "Support for Toshiba TBTX49[23]7 board"
+       bool "Toshiba TBTX49[23]7 board"
        select DMA_NONCOHERENT
        select HAS_TXX9_SERIAL
        select HW_HAS_PCI
@@ -760,7 +760,7 @@ config TOSHIBA_RBTX4927
          support this machine type
 
 config TOSHIBA_RBTX4938
-       bool "Support for Toshiba RBTX4938 board"
+       bool "Toshiba RBTX4938 board"
        select HAVE_STD_PC_SERIAL_PORT
        select DMA_NONCOHERENT
        select GENERIC_ISA_DMA
@@ -1411,13 +1411,12 @@ config PAGE_SIZE_8KB
 
 config PAGE_SIZE_16KB
        bool "16kB"
-       depends on EXPERIMENTAL && !CPU_R3000 && !CPU_TX39XX
+       depends on !CPU_R3000 && !CPU_TX39XX
        help
          Using 16kB page size will result in higher performance kernel at
          the price of higher memory consumption.  This option is available on
-         all non-R3000 family processor.  Not that at the time of this
-         writing this option is still high experimental; there are also
-         issues with compatibility of user applications.
+         all non-R3000 family processors.  Note that you will need a suitable
+         Linux distribution to support this.
 
 config PAGE_SIZE_64KB
        bool "64kB"
@@ -1426,8 +1425,7 @@ config PAGE_SIZE_64KB
          Using 64kB page size will result in higher performance kernel at
          the price of higher memory consumption.  This option is available on
          all non-R3000 family processor.  Not that at the time of this
-         writing this option is still high experimental; there are also
-         issues with compatibility of user applications.
+         writing this option is still high experimental.
 
 endchoice
 
index da61de7761549d89c3e5bc08204ebbdfdea5cd2a..afe05ec12c27d31326d73937081eb7e0631d1c33 100644 (file)
@@ -68,6 +68,7 @@
 
 extern void set_debug_traps(void);
 extern irq_cpustat_t irq_stat [NR_CPUS];
+extern void mips_timer_interrupt(struct pt_regs *regs);
 
 static void setup_local_irq(unsigned int irq, int type, int int_req);
 static unsigned int startup_irq(unsigned int irq);
index f85f1524b36639a1c9c2e9bf0e7ef8673afb4c97..f74d66a58a21a51c8dc2915c8e741fc0b500440a 100644 (file)
@@ -116,6 +116,7 @@ void mips_timer_interrupt(struct pt_regs *regs)
 
 null:
        ack_r4ktimer(0);
+       irq_exit();
 }
 
 #ifdef CONFIG_PM
index 92b28b674d6f615be8ab8894ea117e06018f44d1..0facfaf4e9508d7a2d827cfff7e612323d2c9cc5 100644 (file)
@@ -272,8 +272,8 @@ void output_sc_defines(void)
        text("/* Linux sigcontext offsets. */");
        offset("#define SC_REGS       ", struct sigcontext, sc_regs);
        offset("#define SC_FPREGS     ", struct sigcontext, sc_fpregs);
-       offset("#define SC_MDHI       ", struct sigcontext, sc_hi);
-       offset("#define SC_MDLO       ", struct sigcontext, sc_lo);
+       offset("#define SC_MDHI       ", struct sigcontext, sc_mdhi);
+       offset("#define SC_MDLO       ", struct sigcontext, sc_mdlo);
        offset("#define SC_PC         ", struct sigcontext, sc_pc);
        offset("#define SC_FPC_CSR    ", struct sigcontext, sc_fpc_csr);
        linefeed;
index 58b3b14873cb572a10d9a87e2b57cece1fc061b8..bef3e2dc7c52674c120433257bfeb04b93e0ac42 100644 (file)
@@ -121,6 +121,7 @@ static inline void check_wait(void)
        case CPU_24K:
        case CPU_25KF:
        case CPU_34K:
+       case CPU_74K:
        case CPU_PR4450:
                cpu_wait = r4k_wait;
                printk(" available.\n");
@@ -432,6 +433,15 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c)
                             MIPS_CPU_LLSC;
                c->tlbsize = 64;
                break;
+       case PRID_IMP_R14000:
+               c->cputype = CPU_R14000;
+               c->isa_level = MIPS_CPU_ISA_IV;
+               c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
+                            MIPS_CPU_FPU | MIPS_CPU_32FPR |
+                            MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
+                            MIPS_CPU_LLSC;
+               c->tlbsize = 64;
+               break;
        }
 }
 
@@ -593,6 +603,9 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c)
        case PRID_IMP_34K:
                c->cputype = CPU_34K;
                break;
+       case PRID_IMP_74K:
+               c->cputype = CPU_74K;
+               break;
        }
 }
 
index d101d2fb24caab6f8283647a20a5c37768f30c05..a9c6de1b954257e8e30e73518009f7cf3d1444ae 100644 (file)
@@ -101,7 +101,7 @@ FEXPORT(restore_all)                        # restore full frame
        EMT
 1:
        mfc0    v1, CP0_TCSTATUS
-       /* We set IXMT above, XOR should cler it here */
+       /* We set IXMT above, XOR should clear it here */
        xori    v1, v1, TCSTATUS_IXMT
        or      v1, v0, v1
        mtc0    v1, CP0_TCSTATUS
index 10f28fb9f008a92fc89b68c89734233297e8472b..5fd7a8af0c6256bc720c7fa232ee14d551be3e63 100644 (file)
                 */
                mfc0    k0, CP0_CAUSE
                andi    k0, k0, 0x7c
-               add     k1, k1, k0
-               PTR_L   k0, saved_vectors(k1)
-               jr      k0
+#ifdef CONFIG_64BIT
+               dsll    k0, k0, 1
+#endif
+               PTR_L   k1, saved_vectors(k0)
+               jr      k1
                nop
 1:
                move    k0, sp
index 84ab959f924ac57d1b05edc73aa48ce84c2da04f..9def554f335b8f430dd0483dcca482b83c083d07 100644 (file)
@@ -42,6 +42,7 @@ static const char *cpu_name[] = {
        [CPU_R8000]     = "R8000",
        [CPU_R10000]    = "R10000",
        [CPU_R12000]    = "R12000",
+       [CPU_R14000]    = "R14000",
        [CPU_R4300]     = "R4300",
        [CPU_R4650]     = "R4650",
        [CPU_R4700]     = "R4700",
@@ -74,6 +75,7 @@ static const char *cpu_name[] = {
        [CPU_24K]       = "MIPS 24K",
        [CPU_25KF]      = "MIPS 25Kf",
        [CPU_34K]       = "MIPS 34K",
+       [CPU_74K]       = "MIPS 74K",
        [CPU_VR4111]    = "NEC VR4111",
        [CPU_VR4121]    = "NEC VR4121",
        [CPU_VR4122]    = "NEC VR4122",
index 3ca786215d48c172fe0948c450c359d16e3f3c20..ce6cb915c0a7a703ab6c49a2e269d4de1256db38 100644 (file)
@@ -31,7 +31,6 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
        save_gp_reg(31);
 #undef save_gp_reg
 
-#ifdef CONFIG_32BIT
        err |= __put_user(regs->hi, &sc->sc_mdhi);
        err |= __put_user(regs->lo, &sc->sc_mdlo);
        if (cpu_has_dsp) {
@@ -43,20 +42,6 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
                err |= __put_user(mflo3(), &sc->sc_lo3);
                err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
        }
-#endif
-#ifdef CONFIG_64BIT
-       err |= __put_user(regs->hi, &sc->sc_hi[0]);
-       err |= __put_user(regs->lo, &sc->sc_lo[0]);
-       if (cpu_has_dsp) {
-               err |= __put_user(mfhi1(), &sc->sc_hi[1]);
-               err |= __put_user(mflo1(), &sc->sc_lo[1]);
-               err |= __put_user(mfhi2(), &sc->sc_hi[2]);
-               err |= __put_user(mflo2(), &sc->sc_lo[2]);
-               err |= __put_user(mfhi3(), &sc->sc_hi[3]);
-               err |= __put_user(mflo3(), &sc->sc_lo[3]);
-               err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
-       }
-#endif
 
        err |= __put_user(!!used_math(), &sc->sc_used_math);
 
@@ -92,7 +77,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
        err |= __get_user(regs->cp0_epc, &sc->sc_pc);
-#ifdef CONFIG_32BIT
        err |= __get_user(regs->hi, &sc->sc_mdhi);
        err |= __get_user(regs->lo, &sc->sc_mdlo);
        if (cpu_has_dsp) {
@@ -104,20 +88,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
                err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
                err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
        }
-#endif
-#ifdef CONFIG_64BIT
-       err |= __get_user(regs->hi, &sc->sc_hi[0]);
-       err |= __get_user(regs->lo, &sc->sc_lo[0]);
-       if (cpu_has_dsp) {
-               err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg);
-               err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg);
-               err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg);
-               err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg);
-               err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg);
-               err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg);
-               err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
-       }
-#endif
 
 #define restore_gp_reg(i) do {                                         \
        err |= __get_user(regs->regs[i], &sc->sc_regs[i]);              \
index 2aeaa2fd4b322a1ebec61d1861eda4aab1ad4e0a..8f4fdd94dbd02ccd464fc4c05e2c69fe94378ad8 100644 (file)
@@ -280,27 +280,6 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
        char    __user *name;
 
        switch(cmd) {
-       case SETNAME: {
-               char nodename[__NEW_UTS_LEN + 1];
-
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-
-               name = (char __user *) arg1;
-
-               len = strncpy_from_user(nodename, name, __NEW_UTS_LEN);
-               if (len < 0)
-                       return -EFAULT;
-
-               down_write(&uts_sem);
-               strncpy(system_utsname.nodename, nodename, len);
-               nodename[__NEW_UTS_LEN] = '\0';
-               strlcpy(system_utsname.nodename, nodename,
-                       sizeof(system_utsname.nodename));
-               up_write(&uts_sem);
-               return 0;
-       }
-
        case MIPS_ATOMIC_SET:
                printk(KERN_CRIT "How did I get here?\n");
                return -EINVAL;
@@ -313,9 +292,6 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
        case FLUSH_CACHE:
                __flush_cache_all();
                return 0;
-
-       case MIPS_RDNVRAM:
-               return -EIO;
        }
 
        return -EINVAL;
index 4901f0a37fca2b3ddb2de93dcf998873b10e6643..35cb08da3820ff729e4fa6071a5032352090b5db 100644 (file)
@@ -902,6 +902,7 @@ static inline void parity_protection_init(void)
 {
        switch (current_cpu_data.cputype) {
        case CPU_24K:
+       case CPU_34K:
        case CPU_5KC:
                write_c0_ecc(0x80000000);
                back_to_back_c0_hazard();
index 14fa00e3cdfa6007332e58fbd84fc9eba3c4d1ac..b84d1f9ce28ef169e0fbb633ba184c5341e03e40 100644 (file)
@@ -151,23 +151,13 @@ SECTIONS
 
   /* This is the MIPS specific mdebug section.  */
   .mdebug : { *(.mdebug) }
-  /* These are needed for ELF backends which have not yet been
-     converted to the new style linker.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  /* DWARF debug sections.
-     Symbols in the .debug DWARF section are relative to the beginning of the
-     section so we begin .debug at 0.  It's not clear yet what needs to happen
-     for the others.   */
-  .debug          0 : { *(.debug) }
-  .debug_srcinfo  0 : { *(.debug_srcinfo) }
-  .debug_aranges  0 : { *(.debug_aranges) }
-  .debug_pubnames 0 : { *(.debug_pubnames) }
-  .debug_sfnames  0 : { *(.debug_sfnames) }
-  .line           0 : { *(.line) }
+
+  STABS_DEBUG
+
+  DWARF_DEBUG
+
   /* These must appear regardless of  .  */
   .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
   .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
-  .comment : { *(.comment) }
   .note : { *(.note) }
 }
index 4182e1176faeaeb1181af9fe7d12094b42db1fc4..6b35417696027882026d30ffaef1c3dd2146d6ca 100644 (file)
 #include <asm/war.h>
 #include <asm/cacheflush.h> /* for run_uncached() */
 
+
+/*
+ * Special Variant of smp_call_function for use by cache functions:
+ *
+ *  o No return value
+ *  o collapses to normal function call on UP kernels
+ *  o collapses to normal function call on systems with a single shared
+ *    primary cache.
+ */
+static inline void r4k_on_each_cpu(void (*func) (void *info), void *info,
+                                   int retry, int wait)
+{
+       preempt_disable();
+
+#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
+       smp_call_function(func, info, retry, wait);
+#endif
+       func(info);
+       preempt_enable();
+}
+
 /*
  * Must die.
  */
@@ -299,7 +320,7 @@ static void r4k_flush_cache_all(void)
        if (!cpu_has_dc_aliases)
                return;
 
-       on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_all, NULL, 1, 1);
 }
 
 static inline void local_r4k___flush_cache_all(void * args)
@@ -314,13 +335,14 @@ static inline void local_r4k___flush_cache_all(void * args)
        case CPU_R4400MC:
        case CPU_R10000:
        case CPU_R12000:
+       case CPU_R14000:
                r4k_blast_scache();
        }
 }
 
 static void r4k___flush_cache_all(void)
 {
-       on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1);
+       r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1);
 }
 
 static inline void local_r4k_flush_cache_range(void * args)
@@ -341,7 +363,7 @@ static inline void local_r4k_flush_cache_range(void * args)
 static void r4k_flush_cache_range(struct vm_area_struct *vma,
        unsigned long start, unsigned long end)
 {
-       on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1);
 }
 
 static inline void local_r4k_flush_cache_mm(void * args)
@@ -370,7 +392,7 @@ static void r4k_flush_cache_mm(struct mm_struct *mm)
        if (!cpu_has_dc_aliases)
                return;
 
-       on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
 }
 
 struct flush_cache_page_args {
@@ -461,7 +483,7 @@ static void r4k_flush_cache_page(struct vm_area_struct *vma,
        args.addr = addr;
        args.pfn = pfn;
 
-       on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_page, &args, 1, 1);
 }
 
 static inline void local_r4k_flush_data_cache_page(void * addr)
@@ -471,7 +493,7 @@ static inline void local_r4k_flush_data_cache_page(void * addr)
 
 static void r4k_flush_data_cache_page(unsigned long addr)
 {
-       on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_data_cache_page, (void *) addr, 1, 1);
 }
 
 struct flush_icache_range_args {
@@ -514,7 +536,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
        args.start = start;
        args.end = end;
 
-       on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_icache_range, &args, 1, 1);
        instruction_hazard();
 }
 
@@ -590,7 +612,7 @@ static void r4k_flush_icache_page(struct vm_area_struct *vma,
        args.vma = vma;
        args.page = page;
 
-       on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1);
 }
 
 
@@ -689,7 +711,7 @@ static void local_r4k_flush_cache_sigtramp(void * arg)
 
 static void r4k_flush_cache_sigtramp(unsigned long addr)
 {
-       on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1, 1);
+       r4k_on_each_cpu(local_r4k_flush_cache_sigtramp, (void *) addr, 1, 1);
 }
 
 static void r4k_flush_icache_all(void)
@@ -812,6 +834,7 @@ static void __init probe_pcache(void)
 
        case CPU_R10000:
        case CPU_R12000:
+       case CPU_R14000:
                icache_size = 1 << (12 + ((config & R10K_CONF_IC) >> 29));
                c->icache.linesz = 64;
                c->icache.ways = 2;
@@ -965,9 +988,11 @@ static void __init probe_pcache(void)
                c->dcache.flags |= MIPS_CACHE_PINDEX;
        case CPU_R10000:
        case CPU_R12000:
+       case CPU_R14000:
        case CPU_SB1:
                break;
        case CPU_24K:
+       case CPU_34K:
                if (!(read_c0_config7() & (1 << 16)))
        default:
                        if (c->dcache.waysize > PAGE_SIZE)
@@ -1091,6 +1116,7 @@ static void __init setup_scache(void)
 
        case CPU_R10000:
        case CPU_R12000:
+       case CPU_R14000:
                scache_size = 0x80000 << ((config & R10K_CONF_SS) >> 16);
                c->scache.linesz = 64 << ((config >> 13) & 1);
                c->scache.ways = 2;
index e4390dc3eb48e29d9b9a950d5a020d27af32676e..b7c749232ffef80bb50c131f2853965aa7e72396 100644 (file)
@@ -357,6 +357,7 @@ void __init build_clear_page(void)
 
                case CPU_R10000:
                case CPU_R12000:
+               case CPU_R14000:
                        pref_src_mode = Pref_LoadStreamed;
                        pref_dst_mode = Pref_StoreStreamed;
                        break;
index 053dbacac56bdf4d5a797b0d115ddb1951297aa0..54507be2ab5bb07f967f23e9c8305ab5f2ddf48a 100644 (file)
@@ -875,6 +875,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
 
        case CPU_R10000:
        case CPU_R12000:
+       case CPU_R14000:
        case CPU_4KC:
        case CPU_SB1:
        case CPU_SB1A:
@@ -906,6 +907,7 @@ static __init void build_tlb_write_entry(u32 **p, struct label **l,
        case CPU_4KEC:
        case CPU_24K:
        case CPU_34K:
+       case CPU_74K:
                i_ehb(p);
                tlbw(p);
                break;
index f2b4862aaae505fbcb8e902214633b6078d64fe4..91b799d2cd88f2ad6fa21fccf5d76e49c71a61fa 100644 (file)
@@ -80,6 +80,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        case CPU_24K:
        case CPU_25KF:
        case CPU_34K:
+       case CPU_74K:
        case CPU_SB1:
        case CPU_SB1A:
                lmodel = &op_model_mipsxx;
index 95d488ca075473be4d4e0a3e0d032a0c413eaf27..e7ce923913037713feca02eb61c5f166adfd0a2d 100644 (file)
@@ -205,6 +205,10 @@ static int __init mipsxx_init(void)
        case CPU_34K:
                op_model_mipsxx.cpu_type = "mips/34K";
                break;
+
+       case CPU_74K:
+               op_model_mipsxx.cpu_type = "mips/74K";
+               break;
 #endif
 
        case CPU_5KC:
index 2d80653aa2af54e866eee220d8193dde6d663c49..41e9ab40cd543f3f0b7b320384c993a121c7b777 100644 (file)
@@ -2057,10 +2057,45 @@ static void __init flatten_device_tree(void)
 
 }
 
-
-static void __init fixup_device_tree(void)
+#ifdef CONFIG_PPC_MAPLE
+/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges property.
+ * The values are bad, and it doesn't even have the right number of cells. */
+static void __init fixup_device_tree_maple(void)
 {
+       phandle isa;
+       u32 isa_ranges[6];
+
+       isa = call_prom("finddevice", 1, 1, ADDR("/ht@0/isa@4"));
+       if (!PHANDLE_VALID(isa))
+               return;
+
+       if (prom_getprop(isa, "ranges", isa_ranges, sizeof(isa_ranges))
+               == PROM_ERROR)
+               return;
+
+       if (isa_ranges[0] != 0x1 ||
+               isa_ranges[1] != 0xf4000000 ||
+               isa_ranges[2] != 0x00010000)
+               return;
+
+       prom_printf("fixing up bogus ISA range on Maple...\n");
+
+       isa_ranges[0] = 0x1;
+       isa_ranges[1] = 0x0;
+       isa_ranges[2] = 0x01002000; /* IO space; PCI device = 4 */
+       isa_ranges[3] = 0x0;
+       isa_ranges[4] = 0x0;
+       isa_ranges[5] = 0x00010000;
+       prom_setprop(isa, "/ht@0/isa@4", "ranges",
+                       isa_ranges, sizeof(isa_ranges));
+}
+#else
+#define fixup_device_tree_maple()
+#endif
+
 #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
+static void __init fixup_device_tree_pmac(void)
+{
        phandle u3, i2c, mpic;
        u32 u3_rev;
        u32 interrupts[2];
@@ -2097,9 +2132,16 @@ static void __init fixup_device_tree(void)
        parent = (u32)mpic;
        prom_setprop(i2c, "/u3@0,f8000000/i2c@f8001000", "interrupt-parent",
                     &parent, sizeof(parent));
-#endif
 }
+#else
+#define fixup_device_tree_pmac()
+#endif
 
+static void __init fixup_device_tree(void)
+{
+       fixup_device_tree_maple();
+       fixup_device_tree_pmac();
+}
 
 static void __init prom_find_boot_cpu(void)
 {
index cf56a1d499ff740b5ee56efa4f22844e679a7359..26ed1f5ef16e12e8cde5e955b3ced3592f34bc54 100644 (file)
@@ -338,6 +338,8 @@ SYSCALL(symlinkat)
 SYSCALL(readlinkat)
 SYSCALL(fchmodat)
 SYSCALL(faccessat)
+COMPAT_SYS(get_robust_list)
+COMPAT_SYS(set_robust_list)
 
 /*
  * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c
index 95b36430aa0fa4b495ee08342bee9b9756065c2d..b47fcc5ddb7867636acc0acbed6613ae266215b0 100644 (file)
@@ -258,6 +258,7 @@ void *spu_syscall_table[] = {
        [__NR_futex]                    sys_futex,
        [__NR_sched_setaffinity]        sys_sched_setaffinity,
        [__NR_sched_getaffinity]        sys_sched_getaffinity,
+       [224]                           sys_ni_syscall,
        [__NR_tuxcall]                  sys_ni_syscall,
        [226]                           sys_ni_syscall,
        [__NR_io_setup]                 sys_io_setup,
@@ -332,19 +333,21 @@ void *spu_syscall_table[] = {
        [__NR_readlinkat]               sys_readlinkat,
        [__NR_fchmodat]                 sys_fchmodat,
        [__NR_faccessat]                sys_faccessat,
+       [__NR_get_robust_list]          sys_get_robust_list,
+       [__NR_set_robust_list]          sys_set_robust_list,
 };
 
 long spu_sys_callback(struct spu_syscall_block *s)
 {
        long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
 
-       syscall = spu_syscall_table[s->nr_ret];
-
        if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) {
                pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret);
                return -ENOSYS;
        }
 
+       syscall = spu_syscall_table[s->nr_ret];
+
 #ifdef DEBUG
        print_symbol(KERN_DEBUG "SPU-syscall %s:", (unsigned long)syscall);
        printk("syscall%ld(%lx, %lx, %lx, %lx, %lx, %lx)\n",
index df2343e1956bc266cc634ac88a217dd51f86d9ce..c896ce83d412917da2820292c32c9b6e4c32dcd1 100644 (file)
@@ -1157,6 +1157,7 @@ EXPORT_SYMBOL_GPL(pmac_i2c_xfer);
 /* some quirks for platform function decoding */
 enum {
        pmac_i2c_quirk_invmask = 0x00000001u,
+       pmac_i2c_quirk_skip = 0x00000002u,
 };
 
 static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
@@ -1172,6 +1173,15 @@ static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
                /* XXX Study device-tree's & apple drivers are get the quirks
                 * right !
                 */
+               /* Workaround: It seems that running the clockspreading
+                * properties on the eMac will cause lockups during boot.
+                * The machine seems to work fine without that. So for now,
+                * let's make sure i2c-hwclock doesn't match about "imic"
+                * clocks and we'll figure out if we really need to do
+                * something special about those later.
+                */
+               { "i2c-hwclock", "imic5002", pmac_i2c_quirk_skip },
+               { "i2c-hwclock", "imic5003", pmac_i2c_quirk_skip },
                { "i2c-hwclock", NULL, pmac_i2c_quirk_invmask },
                { "i2c-cpu-voltage", NULL, 0},
                {  "temp-monitor", NULL, 0 },
@@ -1198,6 +1208,8 @@ static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
                                if (p->compatible &&
                                    !device_is_compatible(np, p->compatible))
                                        continue;
+                               if (p->quirks & pmac_i2c_quirk_skip)
+                                       break;
                                callback(np, p->quirks);
                                break;
                        }
index 4d15e396655c1a095ab8c4a5df6600e054ab4c99..b9200fb078157f3498e16f4be98e92a5b8d8194d 100644 (file)
@@ -463,11 +463,23 @@ static int pmac_pm_finish(suspend_state_t state)
        return 0;
 }
 
+static int pmac_pm_valid(suspend_state_t state)
+{
+       switch (state) {
+       case PM_SUSPEND_DISK:
+               return 1;
+       /* can't do any other states via generic mechanism yet */
+       default:
+               return 0;
+       }
+}
+
 static struct pm_ops pmac_pm_ops = {
        .pm_disk_mode   = PM_DISK_SHUTDOWN,
        .prepare        = pmac_pm_prepare,
        .enter          = pmac_pm_enter,
        .finish         = pmac_pm_finish,
+       .valid          = pmac_pm_valid,
 };
 
 #endif /* CONFIG_SOFTWARE_SUSPEND */
index cc7c4aea939751a42985f5bc944614290993ffad..2f5c5e1576175ffb5bc4e3a7e9868dda7bc1caf7 100644 (file)
@@ -134,7 +134,7 @@ main(void)
        DEFINE(TI_TASK, offsetof(struct thread_info, task));
        DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
        DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
-       DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, flags));
+       DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
        DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
        DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
 
index e62b75707f7a3f0551575f936d6258b6c97eb0d8..abb7154de2c7fcba30125b5b1971da761a2a59df 100644 (file)
@@ -279,11 +279,11 @@ static int mpc8272ads_platform_notify(struct device *dev)
        static const struct platform_notify_dev_map dev_map[] = {
                {
                        .bus_id = "fsl-cpm-fcc",
-                       .rtn = mpc8272ads_fixup_enet_pdata
+                       .rtn = mpc8272ads_fixup_enet_pdata,
                },
                {
                        .bus_id = "fsl-cpm-scc:uart",
-                       .rtn = mpc
+                       .rtn = mpc8272ads_fixup_uart_pdata,
                },
                {
                        .bus_id = NULL
@@ -335,15 +335,15 @@ struct platform_device* early_uart_get_pdev(int index)
        struct platform_device* pdev = NULL;
        if(index) { /*assume SCC4 here*/
                pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC4];
-               pinfo = &mpc8272<F12>_uart_pdata[1];
+               pinfo = &mpc8272_uart_pdata[fsid_scc4_uart];
        } else { /*over SCC1*/
                pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC1];
-               pinfo = &mpc8272_uart_pdata[0];
+               pinfo = &mpc8272_uart_pdata[fsid_scc1_uart];
        }
 
        pinfo->uart_clk = bd->bi_intfreq;
        pdev->dev.platform_data = pinfo;
-       ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
+       ppc_sys_fixup_mem_resource(pdev, CPM_MAP_ADDR);
        return NULL;
 }
 
index 0636aed7b8271b2f9357c27a6cb9da1a9a63c31b..8692d00c08c42d7e3c33e59b57abbd7f75a6c5fb 100644 (file)
@@ -121,13 +121,13 @@ struct platform_device ppc_sys_platform_devices[] = {
                .num_resources   = 3,
                .resource = (struct resource[]) {
                        {
-                               .name   = "scc_mem",
+                               .name   = "regs",
                                .start  = 0x11A00,
                                .end    = 0x11A1F,
                                .flags  = IORESOURCE_MEM,
                        },
                        {
-                               .name   = "scc_pram",
+                               .name   = "pram",
                                .start  = 0x8000,
                                .end    = 0x80ff,
                                .flags  = IORESOURCE_MEM,
@@ -145,13 +145,13 @@ struct platform_device ppc_sys_platform_devices[] = {
                .num_resources   = 3,
                .resource = (struct resource[]) {
                        {
-                               .name   = "scc_mem",
+                               .name   = "regs",
                                .start  = 0x11A20,
                                .end    = 0x11A3F,
                                .flags  = IORESOURCE_MEM,
                        },
                        {
-                               .name   = "scc_pram",
+                               .name   = "pram",
                                .start  = 0x8100,
                                .end    = 0x81ff,
                                .flags  = IORESOURCE_MEM,
@@ -169,13 +169,13 @@ struct platform_device ppc_sys_platform_devices[] = {
                .num_resources   = 3,
                .resource = (struct resource[]) {
                        {
-                               .name   = "scc_mem",
+                               .name   = "regs",
                                .start  = 0x11A40,
                                .end    = 0x11A5F,
                                .flags  = IORESOURCE_MEM,
                        },
                        {
-                               .name   = "scc_pram",
+                               .name   = "pram",
                                .start  = 0x8200,
                                .end    = 0x82ff,
                                .flags  = IORESOURCE_MEM,
@@ -193,13 +193,13 @@ struct platform_device ppc_sys_platform_devices[] = {
                .num_resources   = 3,
                .resource = (struct resource[]) {
                        {
-                               .name   = "scc_mem",
+                               .name   = "regs",
                                .start  = 0x11A60,
                                .end    = 0x11A7F,
                                .flags  = IORESOURCE_MEM,
                        },
                        {
-                               .name   = "scc_pram",
+                               .name   = "pram",
                                .start  = 0x8300,
                                .end    = 0x83ff,
                                .flags  = IORESOURCE_MEM,
index 433b0fa203e110029aa103fa639ca340560f23af..fee8948162b9a49a7c9767cd6e389db223065ef3 100644 (file)
@@ -139,13 +139,13 @@ struct ppc_sys_spec ppc_sys_specs[] = {
                .ppc_sys_name   = "8272",
                .mask           = 0x0000ff00,
                .value          = 0x00000c00,
-               .num_devices    = 11,
+               .num_devices    = 12,
                .device_list = (enum ppc_sys_devices[])
                {
                        MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
-                       MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SMC1,
-                       MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
-                       MPC82xx_CPM_USB, MPC82xx_SEC1,
+                       MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
+                       MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
+                       MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
                },
        },
        /* below is a list of the 8280 family of processors */
index 029f09901b851fbd561e18d3be858e805df2bcb8..2a6c6efb68653db8880853d09648d86f21af60b9 100644 (file)
@@ -272,7 +272,7 @@ static inline void stop_hz_timer(void)
        next = next_timer_interrupt();
        do {
                seq = read_seqbegin_irqsave(&xtime_lock, flags);
-               timer = (__u64)(next - jiffies) + jiffies_64;
+               timer = ((__u64) next) - ((__u64) jiffies) + jiffies_64;
        } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
        todval = -1ULL;
        /* Be careful about overflows. */
index 6e1135cc03b08a42e4def9f77511ef0322bd09bc..2856551bddf1b7451aab44512f84cd4aae0f7eab 100644 (file)
@@ -79,6 +79,7 @@ sys_call_table:
 /*285*/        .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
 /*290*/        .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
 /*295*/        .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
+/*300*/        .long sys_set_robust_list, sys_get_robust_list
 
 #ifdef CONFIG_SUNOS_EMUL
        /* Now the SunOS syscall table. */
@@ -190,6 +191,6 @@ sunos_sys_table:
 /*290*/        .long sunos_nosys, sunos_nosys, sunos_nosys
        .long sunos_nosys, sunos_nosys, sunos_nosys
        .long sunos_nosys, sunos_nosys, sunos_nosys
-       .long sunos_nosys
+       .long sunos_nosys, sunos_nosys, sunos_nosys
 
 #endif
index 3eadac5e171e489e157ffbb902609274a017ce17..31c5892f5acc49669c4326bf5162a42ebceb36ea 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/errno.h>
+#include <linux/threads.h>
 #include <asm/thread_info.h>
 #include <asm/asi.h>
 #include <asm/pstate.h>
@@ -493,6 +494,35 @@ tlb_fixup_done:
        call    prom_init
         mov    %l7, %o0                        ! OpenPROM cif handler
 
+       /* Initialize current_thread_info()->cpu as early as possible.
+        * In order to do that accurately we have to patch up the get_cpuid()
+        * assembler sequences.  And that, in turn, requires that we know
+        * if we are on a Starfire box or not.  While we're here, patch up
+        * the sun4v sequences as well.
+        */
+       call    check_if_starfire
+        nop
+       call    per_cpu_patch
+        nop
+       call    sun4v_patch
+        nop
+
+#ifdef CONFIG_SMP
+       call    hard_smp_processor_id
+        nop
+       cmp     %o0, NR_CPUS
+       blu,pt  %xcc, 1f
+        nop
+       call    boot_cpu_id_too_large
+        nop
+       /* Not reached... */
+
+1:
+#else
+       mov     0, %o0
+#endif
+       stb     %o0, [%g6 + TI_CPU]
+
        /* Off we go.... */
        call    start_kernel
         nop
index 8efbc139769d22d45990266d941055a7fef4a0c6..82e5455134c67719c9cafbdf7dc107a187c56302 100644 (file)
@@ -218,7 +218,7 @@ static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx)
  * DMA for PCI device PDEV.  Return non-NULL cpu-side address if
  * successful and set *DMA_ADDRP to the PCI side dma address.
  */
-static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
+static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp)
 {
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
@@ -232,7 +232,7 @@ static void *pci_4u_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr
        if (order >= 10)
                return NULL;
 
-       first_page = __get_free_pages(GFP_ATOMIC, order);
+       first_page = __get_free_pages(gfp, order);
        if (first_page == 0UL)
                return NULL;
        memset((char *)first_page, 0, PAGE_SIZE << order);
index 9e94db2573a2f83f8c1d58072d8e2d28cd0035d4..2b7a1f316a937e56622e9241de9690c7c8f77c45 100644 (file)
@@ -154,7 +154,7 @@ static void pci_arena_free(struct pci_iommu_arena *arena, unsigned long base, un
                __clear_bit(i, arena->map);
 }
 
-static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp)
+static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_addrp, gfp_t gfp)
 {
        struct pcidev_cookie *pcp;
        struct pci_iommu *iommu;
@@ -169,7 +169,7 @@ static void *pci_4v_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr
 
        npages = size >> IO_PAGE_SHIFT;
 
-       first_page = __get_free_pages(GFP_ATOMIC, order);
+       first_page = __get_free_pages(gfp, order);
        if (unlikely(first_page == 0UL))
                return NULL;
 
index 005167f82419b475cb7ae1e4ef109610ba61a5dd..9cf1c88cd774ffbcbe3b58da0574986c4e6860ff 100644 (file)
@@ -220,7 +220,7 @@ char reboot_command[COMMAND_LINE_SIZE];
 
 static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 };
 
-static void __init per_cpu_patch(void)
+void __init per_cpu_patch(void)
 {
        struct cpuid_patch_entry *p;
        unsigned long ver;
@@ -280,7 +280,7 @@ static void __init per_cpu_patch(void)
        }
 }
 
-static void __init sun4v_patch(void)
+void __init sun4v_patch(void)
 {
        struct sun4v_1insn_patch_entry *p1;
        struct sun4v_2insn_patch_entry *p2;
@@ -315,6 +315,15 @@ static void __init sun4v_patch(void)
        }
 }
 
+#ifdef CONFIG_SMP
+void __init boot_cpu_id_too_large(int cpu)
+{
+       prom_printf("Serious problem, boot cpu id (%d) >= NR_CPUS (%d)\n",
+                   cpu, NR_CPUS);
+       prom_halt();
+}
+#endif
+
 void __init setup_arch(char **cmdline_p)
 {
        /* Initialize PROM console and command line. */
@@ -332,16 +341,6 @@ void __init setup_arch(char **cmdline_p)
        conswitchp = &prom_con;
 #endif
 
-       /* Work out if we are starfire early on */
-       check_if_starfire();
-
-       /* Now we know enough to patch the get_cpuid sequences
-        * used by trap code.
-        */
-       per_cpu_patch();
-
-       sun4v_patch();
-
        boot_flags_init(*cmdline_p);
 
        idprom_init();
index 90eaca3ec9a628c40ba90f27c2a89e825afdf736..4e8cd79156e0e0adc4a737265290f1e7cf496871 100644 (file)
@@ -1264,7 +1264,6 @@ void __init smp_tick_init(void)
        boot_cpu_id = hard_smp_processor_id();
        current_tick_offset = timer_tick_offset;
 
-       cpu_set(boot_cpu_id, cpu_online_map);
        prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1;
 }
 
@@ -1345,18 +1344,6 @@ void __init smp_setup_cpu_possible_map(void)
 
 void __devinit smp_prepare_boot_cpu(void)
 {
-       int cpu = hard_smp_processor_id();
-
-       if (cpu >= NR_CPUS) {
-               prom_printf("Serious problem, boot cpu id >= NR_CPUS\n");
-               prom_halt();
-       }
-
-       current_thread_info()->cpu = cpu;
-       __local_per_cpu_offset = __per_cpu_offset(cpu);
-
-       cpu_set(smp_processor_id(), cpu_online_map);
-       cpu_set(smp_processor_id(), phys_cpu_present_map);
 }
 
 int __devinit __cpu_up(unsigned int cpu)
@@ -1433,4 +1420,7 @@ void __init setup_per_cpu_areas(void)
 
        for (i = 0; i < NR_CPUS; i++, ptr += size)
                memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+
+       /* Setup %g5 for the boot cpu.  */
+       __local_per_cpu_offset = __per_cpu_offset(smp_processor_id());
 }
index d4b39cd30310047356858a500f696f234ce01509..1136fc465e37555431f2ebebd927aa32f61e41e3 100644 (file)
@@ -78,8 +78,9 @@ sys_call_table32:
        .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
 /*280*/        .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
        .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64
-/*285*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
+/*290*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
        .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
+/*300*/        .word compat_sys_set_robust_list, compat_sys_get_robust_list
 
 #endif /* CONFIG_COMPAT */
 
@@ -147,8 +148,9 @@ sys_call_table:
        .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
 /*280*/        .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
        .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
-/*285*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
+/*290*/        .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
        .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
+/*300*/        .word sys_set_robust_list, sys_get_robust_list
 
 #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
     defined(CONFIG_SOLARIS_EMUL_MODULE)
@@ -261,5 +263,5 @@ sunos_sys_table:
 /*290*/        .word sunos_nosys, sunos_nosys, sunos_nosys
        .word sunos_nosys, sunos_nosys, sunos_nosys
        .word sunos_nosys, sunos_nosys, sunos_nosys
-       .word sunos_nosys
+       .word sunos_nosys, sunos_nosys, sunos_nosys
 #endif
index e776139afb2019e804d65ddd468a834ee04d6ed1..926c4743d13b27220cd00494a99f3eb2d74a1ff1 100644 (file)
@@ -339,7 +339,7 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top,
        struct mm_struct *mm = current->mm;
        int i, ret;
 
-       stack_base = IA32_STACK_TOP - MAX_ARG_PAGES * PAGE_SIZE;
+       stack_base = stack_top - MAX_ARG_PAGES * PAGE_SIZE;
        mm->arg_start = bprm->p + stack_base;
 
        bprm->p += stack_base;
@@ -357,7 +357,7 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top,
        {
                mpnt->vm_mm = mm;
                mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
-               mpnt->vm_end = IA32_STACK_TOP;
+               mpnt->vm_end = stack_top;
                if (executable_stack == EXSTACK_ENABLE_X)
                        mpnt->vm_flags = VM_STACK_FLAGS |  VM_EXEC;
                else if (executable_stack == EXSTACK_DISABLE_X)
index 222b5b46d2b2df6546ab01e67be1d1b92d713667..1ef6028f721ea843936b4994581c67dfa7e1b9c6 100644 (file)
@@ -149,7 +149,7 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi
                        addr = start;
                if (addr > ei->addr + ei->size) 
                        continue; 
-               while (bad_addr(&addr, size) && addr+size < ei->addr + ei->size)
+               while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
                        ;
                last = addr + size;
                if (last > ei->addr + ei->size)
index c946e4fe67a7937ab15eba697246602c7dc67dbd..586b34c00c489a2d3d495a904c00b158a1abfba4 100644 (file)
@@ -281,12 +281,7 @@ tracesys:
        ja  1f
        movq %r10,%rcx  /* fixup for C */
        call *sys_call_table(,%rax,8)
-       movq %rax,RAX-ARGOFFSET(%rsp)
-1:     SAVE_REST
-       movq %rsp,%rdi
-       call syscall_trace_leave
-       RESTORE_TOP_OF_STACK %rbx
-       RESTORE_REST
+1:     movq %rax,RAX-ARGOFFSET(%rsp)
        /* Use IRET because user could have changed frame */
        jmp int_ret_from_sys_call
        CFI_ENDPROC
index 1eaa5dae6174ff57b514a56828f07e6f8ed0a149..fa1d19ca700ae82a23df77f068bee660e47f80f2 100644 (file)
@@ -514,13 +514,13 @@ static void __kprobes resume_execution(struct kprobe *p,
                *tos = orig_rip + (*tos - copy_rip);
                break;
        case 0xff:
-               if ((*insn & 0x30) == 0x10) {
+               if ((insn[1] & 0x30) == 0x10) {
                        /* call absolute, indirect */
                        /* Fix return addr; rip is correct. */
                        next_rip = regs->rip;
                        *tos = orig_rip + (*tos - copy_rip);
-               } else if (((*insn & 0x31) == 0x20) ||  /* jmp near, absolute indirect */
-                          ((*insn & 0x31) == 0x21)) {  /* jmp far, absolute indirect */
+               } else if (((insn[1] & 0x31) == 0x20) ||        /* jmp near, absolute indirect */
+                          ((insn[1] & 0x31) == 0x21)) {        /* jmp far, absolute indirect */
                        /* rip is correct. */
                        next_rip = regs->rip;
                }
index af035ede70cd43386f240438e2192cb343cab750..a9275c9557cf432ea3187f806c15fb369d72b312 100644 (file)
@@ -54,6 +54,10 @@ dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order)
        else
 #endif
                node = numa_node_id();
+
+       if (node < first_node(node_online_map))
+               node = first_node(node_online_map);
+
        page = alloc_pages_node(node, gfp, order);
        return page ? page_address(page) : NULL;
 }
index 2480d3f08a470865b90f1dd8cb35e2c6c30a9e1a..82a7c9bfdfa0f3e0bd1945225fd0f86df67b1c96 100644 (file)
@@ -631,10 +631,8 @@ static int __init pci_iommu_init(void)
                printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n");
                if (end_pfn > MAX_DMA32_PFN) {
                        printk(KERN_ERR "WARNING more than 4GB of memory "
-                                       "but IOMMU not compiled in.\n"
-                              KERN_ERR "WARNING 32bit PCI may malfunction.\n"
-                              KERN_ERR "You might want to enable "
-                                       "CONFIG_GART_IOMMU\n");
+                                       "but IOMMU not available.\n"
+                              KERN_ERR "WARNING 32bit PCI may malfunction.\n");
                }
                return -1;
        }
index b0444a415bd60670a2314d9e0f9c0c54641a7e56..bf421ed26808cec48cc9ca1207865bcee52f0f07 100644 (file)
@@ -68,7 +68,7 @@ int pmtimer_mark_offset(void)
        offset_delay = delta % (USEC_PER_SEC / HZ);
 
        rdtscll(tsc);
-       vxtime.last_tsc = tsc - offset_delay * cpu_khz;
+       vxtime.last_tsc = tsc - offset_delay * (u64)cpu_khz / 1000;
 
        /* don't calculate delay for first run,
           or if we've got less then a tick */
index f0870bef24d114b521f625952b79e973ed2a5e1c..655b9192eeb3727d85a8921d10cdd4049c2a5232 100644 (file)
@@ -1051,7 +1051,7 @@ static void srat_detect_node(void)
           for now. */
        node = apicid_to_node[hard_smp_processor_id()];
        if (node == NUMA_NO_NODE)
-               node = 0;
+               node = first_node(node_online_map);
        numa_set_node(cpu, node);
 
        if (acpi_numa > 0)
index e1513532df293447a529cd7477b6bbca67363e18..474df22c6ed20fb7aa0f2b6e503dc232d0ec3050 100644 (file)
@@ -399,8 +399,10 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
        /* First clean up the node list */
        for (i = 0; i < MAX_NUMNODES; i++) {
                cutoff_node(i, start, end);
-               if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE)
+               if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) {
                        unparse_node(i);
+                       node_set_offline(i);
+               }
        }
 
        if (acpi_numa <= 0)
index 2540dfaa3e385def27a44284bf3e552f986ee15d..8e9d84825e1c519500288da6602b208fcec33995 100644 (file)
@@ -33,7 +33,7 @@ static int cfq_slice_idle = HZ / 70;
 
 #define CFQ_KEY_ASYNC          (0)
 
-static DEFINE_RWLOCK(cfq_exit_lock);
+static DEFINE_SPINLOCK(cfq_exit_lock);
 
 /*
  * for the hash of cfqq inside the cfqd
@@ -133,6 +133,7 @@ struct cfq_data {
        mempool_t *crq_pool;
 
        int rq_in_driver;
+       int hw_tag;
 
        /*
         * schedule slice state info
@@ -500,10 +501,13 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
 
        /*
         * if queue was preempted, just add to front to be fair. busy_rr
-        * isn't sorted.
+        * isn't sorted, but insert at the back for fairness.
         */
        if (preempted || list == &cfqd->busy_rr) {
-               list_add(&cfqq->cfq_list, list);
+               if (preempted)
+                       list = list->prev;
+
+               list_add_tail(&cfqq->cfq_list, list);
                return;
        }
 
@@ -664,6 +668,15 @@ static void cfq_activate_request(request_queue_t *q, struct request *rq)
        struct cfq_data *cfqd = q->elevator->elevator_data;
 
        cfqd->rq_in_driver++;
+
+       /*
+        * If the depth is larger 1, it really could be queueing. But lets
+        * make the mark a little higher - idling could still be good for
+        * low queueing, and a low queueing number could also just indicate
+        * a SCSI mid layer like behaviour where limit+1 is often seen.
+        */
+       if (!cfqd->hw_tag && cfqd->rq_in_driver > 4)
+               cfqd->hw_tag = 1;
 }
 
 static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
@@ -878,6 +891,13 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd)
        if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1)
                cfqq = list_entry_cfqq(cfqd->cur_rr.next);
 
+       /*
+        * If no new queues are available, check if the busy list has some
+        * before falling back to idle io.
+        */
+       if (!cfqq && !list_empty(&cfqd->busy_rr))
+               cfqq = list_entry_cfqq(cfqd->busy_rr.next);
+
        /*
         * if we have idle queues and no rt or be queues had pending
         * requests, either allow immediate service if the grace period
@@ -1284,7 +1304,7 @@ static void cfq_exit_io_context(struct io_context *ioc)
        /*
         * put the reference this task is holding to the various queues
         */
-       read_lock_irqsave(&cfq_exit_lock, flags);
+       spin_lock_irqsave(&cfq_exit_lock, flags);
 
        n = rb_first(&ioc->cic_root);
        while (n != NULL) {
@@ -1294,7 +1314,7 @@ static void cfq_exit_io_context(struct io_context *ioc)
                n = rb_next(n);
        }
 
-       read_unlock_irqrestore(&cfq_exit_lock, flags);
+       spin_unlock_irqrestore(&cfq_exit_lock, flags);
 }
 
 static struct cfq_io_context *
@@ -1400,17 +1420,17 @@ static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
        struct cfq_io_context *cic;
        struct rb_node *n;
 
-       write_lock(&cfq_exit_lock);
+       spin_lock(&cfq_exit_lock);
 
        n = rb_first(&ioc->cic_root);
        while (n != NULL) {
                cic = rb_entry(n, struct cfq_io_context, rb_node);
+
                changed_ioprio(cic);
                n = rb_next(n);
        }
 
-       write_unlock(&cfq_exit_lock);
+       spin_unlock(&cfq_exit_lock);
 
        return 0;
 }
@@ -1458,7 +1478,8 @@ retry:
                 * set ->slice_left to allow preemption for a new process
                 */
                cfqq->slice_left = 2 * cfqd->cfq_slice_idle;
-               cfq_mark_cfqq_idle_window(cfqq);
+               if (!cfqd->hw_tag)
+                       cfq_mark_cfqq_idle_window(cfqq);
                cfq_mark_cfqq_prio_changed(cfqq);
                cfq_init_prio_data(cfqq);
        }
@@ -1475,9 +1496,10 @@ out:
 static void
 cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic)
 {
-       read_lock(&cfq_exit_lock);
+       spin_lock(&cfq_exit_lock);
        rb_erase(&cic->rb_node, &ioc->cic_root);
-       read_unlock(&cfq_exit_lock);
+       list_del_init(&cic->queue_list);
+       spin_unlock(&cfq_exit_lock);
        kmem_cache_free(cfq_ioc_pool, cic);
        atomic_dec(&ioc_count);
 }
@@ -1545,11 +1567,11 @@ restart:
                        BUG();
        }
 
-       read_lock(&cfq_exit_lock);
+       spin_lock(&cfq_exit_lock);
        rb_link_node(&cic->rb_node, parent, p);
        rb_insert_color(&cic->rb_node, &ioc->cic_root);
        list_add(&cic->queue_list, &cfqd->cic_list);
-       read_unlock(&cfq_exit_lock);
+       spin_unlock(&cfq_exit_lock);
 }
 
 /*
@@ -1648,7 +1670,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 {
        int enable_idle = cfq_cfqq_idle_window(cfqq);
 
-       if (!cic->ioc->task || !cfqd->cfq_slice_idle)
+       if (!cic->ioc->task || !cfqd->cfq_slice_idle || cfqd->hw_tag)
                enable_idle = 0;
        else if (sample_valid(cic->ttime_samples)) {
                if (cic->ttime_mean > cfqd->cfq_slice_idle)
@@ -1739,14 +1761,24 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
 
        cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq);
 
+       cic = crq->io_context;
+
        /*
         * we never wait for an async request and we don't allow preemption
         * of an async request. so just return early
         */
-       if (!cfq_crq_is_sync(crq))
+       if (!cfq_crq_is_sync(crq)) {
+               /*
+                * sync process issued an async request, if it's waiting
+                * then expire it and kick rq handling.
+                */
+               if (cic == cfqd->active_cic &&
+                   del_timer(&cfqd->idle_slice_timer)) {
+                       cfq_slice_expired(cfqd, 0);
+                       cfq_start_queueing(cfqd, cfqq);
+               }
                return;
-
-       cic = crq->io_context;
+       }
 
        cfq_update_io_thinktime(cfqd, cic);
        cfq_update_io_seektime(cfqd, cic, crq);
@@ -2164,10 +2196,9 @@ static void cfq_idle_class_timer(unsigned long data)
         * race with a non-idle queue, reset timer
         */
        end = cfqd->last_end_request + CFQ_IDLE_GRACE;
-       if (!time_after_eq(jiffies, end)) {
-               cfqd->idle_class_timer.expires = end;
-               add_timer(&cfqd->idle_class_timer);
-       } else
+       if (!time_after_eq(jiffies, end))
+               mod_timer(&cfqd->idle_class_timer, end);
+       else
                cfq_schedule_dispatch(cfqd);
 
        spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
@@ -2187,7 +2218,7 @@ static void cfq_exit_queue(elevator_t *e)
 
        cfq_shutdown_timer_wq(cfqd);
 
-       write_lock(&cfq_exit_lock);
+       spin_lock(&cfq_exit_lock);
        spin_lock_irq(q->queue_lock);
 
        if (cfqd->active_queue)
@@ -2210,7 +2241,7 @@ static void cfq_exit_queue(elevator_t *e)
        }
 
        spin_unlock_irq(q->queue_lock);
-       write_unlock(&cfq_exit_lock);
+       spin_unlock(&cfq_exit_lock);
 
        cfq_shutdown_timer_wq(cfqd);
 
index eac48bec14791533a594af0e2909b7ed5347c091..7eb36c53f4b7868247141a105ef82e8be3e2d96f 100644 (file)
@@ -3452,7 +3452,12 @@ void end_that_request_last(struct request *req, int uptodate)
        if (unlikely(laptop_mode) && blk_fs_request(req))
                laptop_io_completion();
 
-       if (disk && blk_fs_request(req)) {
+       /*
+        * Account IO completion.  bar_rq isn't accounted as a normal
+        * IO on queueing nor completion.  Accounting the containing
+        * request is enough.
+        */
+       if (disk && blk_fs_request(req) && req != &req->q->bar_rq) {
                unsigned long duration = jiffies - req->start_time;
                const int rw = rq_data_dir(req);
 
index 472318205236162eaca67da28be8b3ece20b50bc..0c99ae6a340728bb55efc503aca6b9bb92e26860 100644 (file)
@@ -86,18 +86,9 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count)
 static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
 
 static void  fw_class_dev_release(struct class_device *class_dev);
-int firmware_class_uevent(struct class_device *dev, char **envp,
-                          int num_envp, char *buffer, int buffer_size);
 
-static struct class firmware_class = {
-       .name           = "firmware",
-       .uevent = firmware_class_uevent,
-       .release        = fw_class_dev_release,
-};
-
-int
-firmware_class_uevent(struct class_device *class_dev, char **envp,
-                      int num_envp, char *buffer, int buffer_size)
+static int firmware_class_uevent(struct class_device *class_dev, char **envp,
+                                int num_envp, char *buffer, int buffer_size)
 {
        struct firmware_priv *fw_priv = class_get_devdata(class_dev);
        int i = 0, len = 0;
@@ -116,6 +107,12 @@ firmware_class_uevent(struct class_device *class_dev, char **envp,
        return 0;
 }
 
+static struct class firmware_class = {
+       .name           = "firmware",
+       .uevent         = firmware_class_uevent,
+       .release        = fw_class_dev_release,
+};
+
 static ssize_t
 firmware_loading_show(struct class_device *class_dev, char *buf)
 {
@@ -493,25 +490,6 @@ release_firmware(const struct firmware *fw)
        }
 }
 
-/**
- * register_firmware: - provide a firmware image for later usage
- * @name: name of firmware image file
- * @data: buffer pointer for the firmware image
- * @size: size of the data buffer area
- *
- *     Make sure that @data will be available by requesting firmware @name.
- *
- *     Note: This will not be possible until some kind of persistence
- *     is available.
- **/
-void
-register_firmware(const char *name, const u8 *data, size_t size)
-{
-       /* This is meaningless without firmware caching, so until we
-        * decide if firmware caching is reasonable just leave it as a
-        * noop */
-}
-
 /* Async support */
 struct firmware_work {
        struct work_struct work;
@@ -630,4 +608,3 @@ module_exit(firmware_class_exit);
 EXPORT_SYMBOL(release_firmware);
 EXPORT_SYMBOL(request_firmware);
 EXPORT_SYMBOL(request_firmware_nowait);
-EXPORT_SYMBOL(register_firmware);
index 662209d3f42d6a551c7001ab5adb62406abfcfb0..2a769cc6f5f9f8181580b6657c0d0625e9c937dd 100644 (file)
@@ -8,7 +8,6 @@
  *
  */
 
-#include <linux/vt_kern.h>
 #include <linux/device.h>
 #include <linux/kallsyms.h>
 #include <linux/pm.h>
@@ -66,6 +65,7 @@ int suspend_device(struct device * dev, pm_message_t state)
        return error;
 }
 
+
 /**
  *     device_suspend - Save state and stop all devices in system.
  *     @state:         Power state to put each device in.
@@ -85,9 +85,6 @@ int device_suspend(pm_message_t state)
 {
        int error = 0;
 
-       if (!is_console_suspend_safe())
-               return -EINVAL;
-
        down(&dpm_sem);
        down(&dpm_list_sem);
        while (!list_empty(&dpm_active) && error == 0) {
index 0b9cf9c59a213af2aa42f3f9eec0332ee823520f..7c88c060a9e6b3ab908660b6676aef4423488a35 100644 (file)
@@ -86,7 +86,7 @@ config AGP_NVIDIA
 
 config AGP_SIS
        tristate "SiS chipset support"
-       depends on AGP && X86_32
+       depends on AGP
        help
          This option gives you AGP support for the GLX component of
          X on Silicon Integrated Systems [SiS] chipsets.
index 36517d4d1ad9da6fdd80dd2f1180a7269abd7437..ac3c33a2e37d7b7ed7d1b3da0c7428f0e448dec8 100644 (file)
@@ -617,6 +617,9 @@ static int agp_amd64_resume(struct pci_dev *pdev)
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
 
+       if (pdev->vendor == PCI_VENDOR_ID_NVIDIA)
+               nforce3_agp_init(pdev);
+
        return amd_8151_configure();
 }
 
index 97b0a890ba7f828310342e585e866af36e101136..b8ec25d174787d56c4df0d07294a76f7a4328ff5 100644 (file)
@@ -345,6 +345,12 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
                .chipset_name   = "PT880",
        },
 
+       /* PT880 Ultra */
+       {
+               .device_id      = PCI_DEVICE_ID_VIA_PT880ULTRA,
+               .chipset_name   = "PT880 Ultra",
+       },
+
        /* PT890 */
        {
                .device_id      = PCI_DEVICE_ID_VIA_8783_0,
@@ -511,6 +517,7 @@ static struct pci_device_id agp_via_pci_table[] = {
        ID(PCI_DEVICE_ID_VIA_8763_0),
        ID(PCI_DEVICE_ID_VIA_8378_0),
        ID(PCI_DEVICE_ID_VIA_PT880),
+       ID(PCI_DEVICE_ID_VIA_PT880ULTRA),
        ID(PCI_DEVICE_ID_VIA_8783_0),
        ID(PCI_DEVICE_ID_VIA_PX8X0_0),
        ID(PCI_DEVICE_ID_VIA_3269_0),
index b36eef0e9d199ff2751ddba5b77d812bacf489cb..02a7dd7a8a55571cbf261e63a9dcdf3cf7fbb969 100644 (file)
@@ -1184,20 +1184,20 @@ static void port_outl(struct si_sm_io *io, unsigned int offset,
 static void port_cleanup(struct smi_info *info)
 {
        unsigned int addr = info->io.addr_data;
-       int          mapsize;
+       int          idx;
 
        if (addr) {
-               mapsize = ((info->io_size * info->io.regspacing)
-                          - (info->io.regspacing - info->io.regsize));
-
-               release_region (addr, mapsize);
+               for (idx = 0; idx < info->io_size; idx++) {
+                       release_region(addr + idx * info->io.regspacing,
+                                      info->io.regsize);
+               }
        }
 }
 
 static int port_setup(struct smi_info *info)
 {
        unsigned int addr = info->io.addr_data;
-       int          mapsize;
+       int          idx;
 
        if (!addr)
                return -ENODEV;
@@ -1225,16 +1225,22 @@ static int port_setup(struct smi_info *info)
                return -EINVAL;
        }
 
-       /* Calculate the total amount of memory to claim.  This is an
-        * unusual looking calculation, but it avoids claiming any
-        * more memory than it has to.  It will claim everything
-        * between the first address to the end of the last full
-        * register. */
-       mapsize = ((info->io_size * info->io.regspacing)
-                  - (info->io.regspacing - info->io.regsize));
-
-       if (request_region(addr, mapsize, DEVICE_NAME) == NULL)
-               return -EIO;
+       /* Some BIOSes reserve disjoint I/O regions in their ACPI
+        * tables.  This causes problems when trying to register the
+        * entire I/O region.  Therefore we must register each I/O
+        * port separately.
+        */
+       for (idx = 0; idx < info->io_size; idx++) {
+               if (request_region(addr + idx * info->io.regspacing,
+                                  info->io.regsize, DEVICE_NAME) == NULL) {
+                       /* Undo allocations */
+                       while (idx--) {
+                               release_region(addr + idx * info->io.regspacing,
+                                              info->io.regsize);
+                       }
+                       return -EIO;
+               }
+       }
        return 0;
 }
 
index e45f0d3d12de5427cf708585d08e3c615d8e087e..a611972024e65942edb58b23d8d176ec6ae456cb 100644 (file)
@@ -105,6 +105,12 @@ static const char* tcpa_event_type_strings[] = {
        "Non-Host Info"
 };
 
+struct tcpa_pc_event {
+       u32 event_id;
+       u32 event_size;
+       u8 event_data[0];
+};
+
 enum tcpa_pc_event_ids {
        SMBIOS = 1,
        BIS_CERT,
@@ -114,14 +120,15 @@ enum tcpa_pc_event_ids {
        NVRAM,
        OPTION_ROM_EXEC,
        OPTION_ROM_CONFIG,
-       OPTION_ROM_MICROCODE,
+       OPTION_ROM_MICROCODE = 10,
        S_CRTM_VERSION,
        S_CRTM_CONTENTS,
        POST_CONTENTS,
+       HOST_TABLE_OF_DEVICES,
 };
 
 static const char* tcpa_pc_event_id_strings[] = {
-       ""
+       "",
        "SMBIOS",
        "BIS Certificate",
        "POST BIOS ",
@@ -130,11 +137,12 @@ static const char* tcpa_pc_event_id_strings[] = {
        "NVRAM",
        "Option ROM",
        "Option ROM config",
-       "Option ROM microcode",
+       "",
+       "Option ROM microcode ",
        "S-CRTM Version",
-       "S-CRTM Contents",
-       "S-CRTM POST Contents",
-       "POST Contents",
+       "S-CRTM Contents ",
+       "POST Contents ",
+       "Table of Devices",
 };
 
 /* returns pointer to start of pos. entry of tcg log */
@@ -206,7 +214,7 @@ static int get_event_name(char *dest, struct tcpa_event *event,
        const char *name = "";
        char data[40] = "";
        int i, n_len = 0, d_len = 0;
-       u32 event_id;
+       struct tcpa_pc_event *pc_event;
 
        switch(event->event_type) {
        case PREBOOT:
@@ -235,31 +243,32 @@ static int get_event_name(char *dest, struct tcpa_event *event,
                }
                break;
        case EVENT_TAG:
-               event_id = be32_to_cpu(*((u32 *)event_entry));
+               pc_event = (struct tcpa_pc_event *)event_entry;
 
                /* ToDo Row data -> Base64 */
 
-               switch (event_id) {
+               switch (pc_event->event_id) {
                case SMBIOS:
                case BIS_CERT:
                case CMOS:
                case NVRAM:
                case OPTION_ROM_EXEC:
                case OPTION_ROM_CONFIG:
-               case OPTION_ROM_MICROCODE:
                case S_CRTM_VERSION:
-               case S_CRTM_CONTENTS:
-               case POST_CONTENTS:
-                       name = tcpa_pc_event_id_strings[event_id];
+                       name = tcpa_pc_event_id_strings[pc_event->event_id];
                        n_len = strlen(name);
                        break;
+               /* hash data */
                case POST_BIOS_ROM:
                case ESCD:
-                       name = tcpa_pc_event_id_strings[event_id];
+               case OPTION_ROM_MICROCODE:
+               case S_CRTM_CONTENTS:
+               case POST_CONTENTS:
+                       name = tcpa_pc_event_id_strings[pc_event->event_id];
                        n_len = strlen(name);
                        for (i = 0; i < 20; i++)
-                               d_len += sprintf(data, "%02x",
-                                               event_entry[8 + i]);
+                               d_len += sprintf(&data[2*i], "%02x",
+                                               pc_event->event_data[i]);
                        break;
                default:
                        break;
@@ -275,53 +284,13 @@ static int get_event_name(char *dest, struct tcpa_event *event,
 
 static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
 {
+       struct tcpa_event *event = v;
+       char *data = v;
+       int i;
 
-       char *eventname;
-       char data[4];
-       u32 help;
-       int i, len;
-       struct tcpa_event *event = (struct tcpa_event *) v;
-       unsigned char *event_entry =
-           (unsigned char *) (v + sizeof(struct tcpa_event));
-
-       eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
-       if (!eventname) {
-               printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
-                      __func__);
-               return -ENOMEM;
-       }
-
-       /* 1st: PCR used is in little-endian format (4 bytes) */
-       help = le32_to_cpu(event->pcr_index);
-       memcpy(data, &help, 4);
-       for (i = 0; i < 4; i++)
-               seq_putc(m, data[i]);
-
-       /* 2nd: SHA1 (20 bytes) */
-       for (i = 0; i < 20; i++)
-               seq_putc(m, event->pcr_value[i]);
-
-       /* 3rd: event type identifier (4 bytes) */
-       help = le32_to_cpu(event->event_type);
-       memcpy(data, &help, 4);
-       for (i = 0; i < 4; i++)
+       for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
                seq_putc(m, data[i]);
 
-       len = 0;
-
-       len += get_event_name(eventname, event, event_entry);
-
-       /* 4th:  filename <= 255 + \'0' delimiter */
-       if (len > TCG_EVENT_NAME_LEN_MAX)
-               len = TCG_EVENT_NAME_LEN_MAX;
-
-       for (i = 0; i < len; i++)
-               seq_putc(m, eventname[i]);
-
-       /* 5th: delimiter */
-       seq_putc(m, '\0');
-
-       kfree(eventname);
        return 0;
 }
 
index f621168f38aec754a418cf4390d9460506a08dec..8ea70625f7ea08bbf2714933cf2e58acd1da44bf 100644 (file)
@@ -457,10 +457,6 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
        }
 
        vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
-       if ((vendor & 0xFFFF) == 0xFFFF) {
-               rc = -ENODEV;
-               goto out_err;
-       }
 
        /* Default timeouts */
        chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
index f07637a8f88fd038bac53f44c7181ea901c2ec51..a88b94a82b140f42b24d68409f651392805e0465 100644 (file)
@@ -398,7 +398,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty,
        while (unlikely(size > copied));
        return copied;
 }
-EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags);
+EXPORT_SYMBOL(tty_insert_flip_string_flags);
 
 void tty_schedule_flip(struct tty_struct *tty)
 {
index acc5d47844eb49a53578f688949f04e039c04962..6c94879e0b99b6f6a369d69a188b347436abe550 100644 (file)
@@ -3238,14 +3238,6 @@ void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
        }
 }
 
-int is_console_suspend_safe(void)
-{
-       /* It is unsafe to suspend devices while X has control of the
-        * hardware. Make sure we are running on a kernel-controlled console.
-        */
-       return vc_cons[fg_console].d->vc_mode == KD_TEXT;
-}
-
 /*
  *     Visible symbols for modules
  */
index a13395e2c372a9b27355040c9c94eae21040992b..fa2ba9ebe42aacf3478212143547c460d877402e 100644 (file)
  *     82801E   (C-ICH)  : document number 273599-001, 273645-002,
  *     82801EB  (ICH5)   : document number 252516-001, 252517-003,
  *     82801ER  (ICH5R)  : document number 252516-001, 252517-003,
- *     82801FB  (ICH6)   : document number 301473-002, 301474-007,
- *     82801FR  (ICH6R)  : document number 301473-002, 301474-007,
- *     82801FBM (ICH6-M) : document number 301473-002, 301474-007,
- *     82801FW  (ICH6W)  : document number 301473-001, 301474-007,
- *     82801FRW (ICH6RW) : document number 301473-001, 301474-007
  *
  *  20000710 Nils Faerber
  *     Initial Version 0.01
  *  20050807 Wim Van Sebroeck <wim@iguana.be>
  *     0.08 Make sure that the watchdog is only "armed" when started.
  *          (Kernel Bug 4251)
+ *  20060416 Wim Van Sebroeck <wim@iguana.be>
+ *     0.09 Remove support for the ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW and
+ *          ICH7 chipsets. (See Kernel Bug 6031 - other code will support these
+ *          chipsets)
  */
 
 /*
@@ -90,7 +89,7 @@
 #include "i8xx_tco.h"
 
 /* Module and version information */
-#define TCO_VERSION "0.08"
+#define TCO_VERSION "0.09"
 #define TCO_MODULE_NAME "i8xx TCO timer"
 #define TCO_DRIVER_NAME   TCO_MODULE_NAME ", v" TCO_VERSION
 #define PFX TCO_MODULE_NAME ": "
@@ -391,11 +390,6 @@ static struct pci_device_id i8xx_tco_pci_tbl[] = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,  PCI_ANY_ID, PCI_ANY_ID, },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_0,    PCI_ANY_ID, PCI_ANY_ID, },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,   PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0,      PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,      PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2,      PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,      PCI_ANY_ID, PCI_ANY_ID, },
-       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,      PCI_ANY_ID, PCI_ANY_ID, },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1,       PCI_ANY_ID, PCI_ANY_ID, },
        { 0, },                 /* End of list */
 };
index 9dc54736e4eb627d5e843bda4e2bc2a243aa0840..1ea04e9b2b0b0938cfc2cbfa04b2eed12b4da01b 100644 (file)
@@ -423,6 +423,12 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
        if (tmr_atboot && started == 0) {
                printk(KERN_INFO PFX "Starting Watchdog Timer\n");
                s3c2410wdt_start();
+       } else if (!tmr_atboot) {
+               /* if we're not enabling the watchdog, then ensure it is
+                * disabled if it has been left running from the bootloader
+                * or other source */
+
+               s3c2410wdt_stop();
        }
 
        return 0;
index 515ce757204996c188589e74ce29341f8b41ab76..20b88f9b7be20d9081c58a72e217a89a394661f2 100644 (file)
@@ -377,7 +377,7 @@ static int __init sc1200wdt_init(void)
 {
        int ret;
 
-       printk(banner);
+       printk("%s\n", banner);
 
        spin_lock_init(&sc1200wdt_lock);
        sema_init(&open_sem, 1);
index a140e4536a4ee277fb7fe89e46fa9fdac847debf..766cc969c4d0c784abd0ef926363f2c37c7d735f 100644 (file)
@@ -491,7 +491,7 @@ static struct pci_device_id divil_pci[] = {
 
 #define MSR_LBAR_SMB           0x5140000B
 
-static int scx200_add_cs553x(void)
+static __init int scx200_add_cs553x(void)
 {
        u32     low, hi;
        u32     smb_base;
index 43b96e298363ac9d441235206c33020ab133269a..27c9eb989a9a087196804e1de14aed5a1e7a2d3a 100644 (file)
@@ -345,17 +345,17 @@ sgiioc4_resetproc(ide_drive_t * drive)
 static u8
 sgiioc4_INB(unsigned long port)
 {
-       u8 reg = (u8) inb(port);
+       u8 reg = (u8) readb((void __iomem *) port);
 
        if ((port & 0xFFF) == 0x11C) {  /* Status register of IOC4 */
                if (reg & 0x51) {       /* Not busy...check for interrupt */
                        unsigned long other_ir = port - 0x110;
-                       unsigned int intr_reg = (u32) inl(other_ir);
+                       unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
 
                        /* Clear the Interrupt, Error bits on the IOC4 */
                        if (intr_reg & 0x03) {
-                               outl(0x03, other_ir);
-                               intr_reg = (u32) inl(other_ir);
+                               writel(0x03, (void __iomem *) other_ir);
+                               intr_reg = (u32) readl((void __iomem *) other_ir);
                        }
                }
        }
@@ -606,6 +606,12 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
        hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off;
        hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
        hwif->ide_dma_timeout = &__ide_dma_timeout;
+
+       /*
+        * The IOC4 uses MMIO rather than Port IO.
+        * It also needs special workarounds for INB.
+        */
+       default_hwif_mmiops(hwif);
        hwif->INB = &sgiioc4_INB;
 }
 
@@ -743,6 +749,6 @@ ioc4_ide_exit(void)
 module_init(ioc4_ide_init);
 module_exit(ioc4_ide_exit);
 
-MODULE_AUTHOR("Aniket Malatpure - Silicon Graphics Inc. (SGI)");
+MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon");
 MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card");
 MODULE_LICENSE("GPL");
index 78e30f80367129e34fa983fb97fd091acc8d6bf1..ffca8b63ee79af28a1363df86c359fbcde1e12ef 100644 (file)
@@ -553,6 +553,8 @@ pmac_ide_init_hwif_ports(hw_regs_t *hw,
 
        if (irq != NULL)
                *irq = pmac_ide[ix].irq;
+
+       hw->dev = &pmac_ide[ix].mdev->ofdev.dev;
 }
 
 #define PMAC_IDE_REG(x) ((void __iomem *)(IDE_DATA_REG+(x)))
index 36a32c315668cebbc7e34be30704b0c4851bcf66..efe147dbeb42137e695298e19c525e1acf027a07 100644 (file)
@@ -211,8 +211,10 @@ void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem)
         */
 
        work = kmalloc(sizeof *work, GFP_KERNEL);
-       if (!work)
+       if (!work) {
+               mmput(mm);
                return;
+       }
 
        INIT_WORK(&work->work, ib_umem_account, work);
        work->mm   = mm;
index 3697edafd6d25f7caf05fe202e92cf7f591cb34c..dddcdae736ac89151d659a65e8521e98523890fb 100644 (file)
@@ -1905,19 +1905,19 @@ static void __exit infinipath_cleanup(void)
                        } else
                                ipath_dbg("irq is 0, not doing free_irq "
                                          "for unit %u\n", dd->ipath_unit);
-                       dd->pcidev = NULL;
-               }
 
-               /*
-                * we check for NULL here, because it's outside the kregbase
-                * check, and we need to call it after the free_irq.  Thus
-                * it's possible that the function pointers were never
-                * initialized.
-                */
-               if (dd->ipath_f_cleanup)
-                       /* clean up chip-specific stuff */
-                       dd->ipath_f_cleanup(dd);
+                       /*
+                        * we check for NULL here, because it's outside
+                        * the kregbase check, and we need to call it
+                        * after the free_irq.  Thus it's possible that
+                        * the function pointers were never initialized.
+                        */
+                       if (dd->ipath_f_cleanup)
+                               /* clean up chip-specific stuff */
+                               dd->ipath_f_cleanup(dd);
 
+                       dd->pcidev = NULL;
+               }
                spin_lock_irqsave(&ipath_devs_lock, flags);
        }
 
index f11a900e8cd7dcd41ce421cb4b78050d6fd10c53..a2f1ceafcca9f67360d1187b8c58e9e5a813f3a0 100644 (file)
@@ -505,11 +505,10 @@ static u8 flash_csum(struct ipath_flash *ifp, int adjust)
  * ipath_get_guid - get the GUID from the i2c device
  * @dd: the infinipath device
  *
- * When we add the multi-chip support, we will probably have to add
- * the ability to use the number of guids field, and get the guid from
- * the first chip's flash, to use for all of them.
+ * We have the capability to use the ipath_nguid field, and get
+ * the guid from the first chip's flash, to use for all of them.
  */
-void ipath_get_guid(struct ipath_devdata *dd)
+void ipath_get_eeprom_info(struct ipath_devdata *dd)
 {
        void *buf;
        struct ipath_flash *ifp;
index c347191f02bf67ba7fa520e6b29e1e23d4ef8fea..ada267e41f6c749901b53f898a9c39df891c7061 100644 (file)
@@ -139,7 +139,7 @@ static int ipath_get_base_info(struct ipath_portdata *pd,
        kinfo->spi_piosize = dd->ipath_ibmaxlen;
        kinfo->spi_mtu = dd->ipath_ibmaxlen;    /* maxlen, not ibmtu */
        kinfo->spi_port = pd->port_port;
-       kinfo->spi_sw_version = IPATH_USER_SWVERSION;
+       kinfo->spi_sw_version = IPATH_KERN_SWVERSION;
        kinfo->spi_hw_version = dd->ipath_revision;
 
        if (copy_to_user(ubase, kinfo, sizeof(*kinfo)))
@@ -1224,6 +1224,10 @@ static unsigned int ipath_poll(struct file *fp,
 
        if (tail == head) {
                set_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag);
+               if(dd->ipath_rhdrhead_intr_off) /* arm rcv interrupt */
+                       (void)ipath_write_ureg(dd, ur_rcvhdrhead,
+                                              dd->ipath_rhdrhead_intr_off
+                                              | head, pd->port_port);
                poll_wait(fp, &pd->port_wait, pt);
 
                if (test_bit(IPATH_PORT_WAITING_RCV, &pd->port_flag)) {
index 4652435998f35fde8020b1ceb3e124ff320d4cf8..fac0a2b74de2e3d08d054322157b773bc5b79967 100644 (file)
@@ -607,7 +607,12 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
        case 4:         /* Ponderosa is one of the bringup boards */
                n = "Ponderosa";
                break;
-       case 5:         /* HT-460 original production board */
+       case 5:
+               /*
+                * HT-460 original production board; two production levels, with
+                * different serial number ranges.   See ipath_ht_early_init() for
+                * case where we enable IPATH_GPIO_INTR for later serial # range.
+                */
                n = "InfiniPath_HT-460";
                break;
        case 6:
@@ -642,7 +647,7 @@ static int ipath_ht_boardname(struct ipath_devdata *dd, char *name,
        if (n)
                snprintf(name, namelen, "%s", n);
 
-       if (dd->ipath_majrev != 3 || dd->ipath_minrev != 2) {
+       if (dd->ipath_majrev != 3 || (dd->ipath_minrev < 2 || dd->ipath_minrev > 3)) {
                /*
                 * This version of the driver only supports the HT-400
                 * Rev 3.2
@@ -1520,6 +1525,18 @@ static int ipath_ht_early_init(struct ipath_devdata *dd)
         */
        ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl,
                         INFINIPATH_S_ABORT);
+
+       ipath_get_eeprom_info(dd);
+       if(dd->ipath_boardrev == 5 && dd->ipath_serial[0] == '1' &&
+               dd->ipath_serial[1] == '2' && dd->ipath_serial[2] == '8') {
+               /*
+                * Later production HT-460 has same changes as HT-465, so
+                * can use GPIO interrupts.  They have serial #'s starting
+                * with 128, rather than 112.
+                */
+               dd->ipath_flags |= IPATH_GPIO_INTR;
+               dd->ipath_flags &= ~IPATH_POLL_RX_INTR;
+       }
        return 0;
 }
 
index 16f640e1c16e2bbd3638f6b8250f42c0f7cbfdc9..dc83250d26a6a1dc3bf31f92385be816b6b7aca4 100644 (file)
@@ -879,7 +879,6 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit)
 
 done:
        if (!ret) {
-               ipath_get_guid(dd);
                *dd->ipath_statusp |= IPATH_STATUS_CHIP_PRESENT;
                if (!dd->ipath_f_intrsetup(dd)) {
                        /* now we can enable all interrupts from the chip */
index e6507f8115bc65b042bdb3f7596934b8560fb1f4..5d92d57b6f5479310a8206812d6d2516e526f71b 100644 (file)
@@ -650,7 +650,7 @@ u32 __iomem *ipath_getpiobuf(struct ipath_devdata *, u32 *);
 void ipath_init_pe800_funcs(struct ipath_devdata *);
 /* init HT-400-specific func */
 void ipath_init_ht400_funcs(struct ipath_devdata *);
-void ipath_get_guid(struct ipath_devdata *);
+void ipath_get_eeprom_info(struct ipath_devdata *);
 u64 ipath_snap_cntr(struct ipath_devdata *, ipath_creg);
 
 /*
index aa33b0e9f2f6330aeba82f2ad85d4621b940aecd..5ae8761f9dd2e8b3ed5dc86430ac9617c251aab9 100644 (file)
@@ -136,9 +136,7 @@ int ipath_lkey_ok(struct ipath_lkey_table *rkt, struct ipath_sge *isge,
                ret = 1;
                goto bail;
        }
-       spin_lock(&rkt->lock);
        mr = rkt->table[(sge->lkey >> (32 - ib_ipath_lkey_table_size))];
-       spin_unlock(&rkt->lock);
        if (unlikely(mr == NULL || mr->lkey != sge->lkey)) {
                ret = 0;
                goto bail;
@@ -184,8 +182,6 @@ bail:
  * @acc: access flags
  *
  * Return 1 if successful, otherwise 0.
- *
- * The QP r_rq.lock should be held.
  */
 int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
                  u32 len, u64 vaddr, u32 rkey, int acc)
@@ -196,9 +192,7 @@ int ipath_rkey_ok(struct ipath_ibdev *dev, struct ipath_sge_state *ss,
        size_t off;
        int ret;
 
-       spin_lock(&rkt->lock);
        mr = rkt->table[(rkey >> (32 - ib_ipath_lkey_table_size))];
-       spin_unlock(&rkt->lock);
        if (unlikely(mr == NULL || mr->lkey != rkey)) {
                ret = 0;
                goto bail;
index 9cb5258ffed95330f9f739100840c139588c3d33..9ec4ac77b87f88df622d5b1d3bc3acf421d3c9b1 100644 (file)
@@ -872,12 +872,13 @@ static void copy_io(u32 __iomem *piobuf, struct ipath_sge_state *ss,
                update_sge(ss, len);
                length -= len;
        }
+       /* Update address before sending packet. */
+       update_sge(ss, length);
        /* must flush early everything before trigger word */
        ipath_flush_wc();
        __raw_writel(last, piobuf);
        /* be sure trigger word is written */
        ipath_flush_wc();
-       update_sge(ss, length);
 }
 
 /**
@@ -943,17 +944,18 @@ int ipath_verbs_send(struct ipath_devdata *dd, u32 hdrwords,
        if (likely(ss->num_sge == 1 && len <= ss->sge.length &&
                   !((unsigned long)ss->sge.vaddr & (sizeof(u32) - 1)))) {
                u32 w;
+               u32 *addr = (u32 *) ss->sge.vaddr;
 
+               /* Update address before sending packet. */
+               update_sge(ss, len);
                /* Need to round up for the last dword in the packet. */
                w = (len + 3) >> 2;
-               __iowrite32_copy(piobuf, ss->sge.vaddr, w - 1);
+               __iowrite32_copy(piobuf, addr, w - 1);
                /* must flush early everything before trigger word */
                ipath_flush_wc();
-               __raw_writel(((u32 *) ss->sge.vaddr)[w - 1],
-                            piobuf + w - 1);
+               __raw_writel(addr[w - 1], piobuf + w - 1);
                /* be sure trigger word is written */
                ipath_flush_wc();
-               update_sge(ss, len);
                ret = 0;
                goto bail;
        }
index 6318067ab5ec751dd755108c7750bcfc89402e53..02e8c75b24f6d175ebde6b42a52da54429d0459b 100644 (file)
@@ -1180,6 +1180,8 @@ static int ipath_pe_early_init(struct ipath_devdata *dd)
         */
        dd->ipath_rhdrhead_intr_off = 1ULL<<32;
 
+       ipath_get_eeprom_info(dd);
+
        return 0;
 }
 
index 18890716db1ed3bf5812968d8945f71905cdfd3a..9f8855d970c87483d0f16faf358630e4bb73068f 100644 (file)
@@ -375,10 +375,10 @@ static void ipath_error_qp(struct ipath_qp *qp)
 
        spin_lock(&dev->pending_lock);
        /* XXX What if its already removed by the timeout code? */
-       if (qp->timerwait.next != LIST_POISON1)
-               list_del(&qp->timerwait);
-       if (qp->piowait.next != LIST_POISON1)
-               list_del(&qp->piowait);
+       if (!list_empty(&qp->timerwait))
+               list_del_init(&qp->timerwait);
+       if (!list_empty(&qp->piowait))
+               list_del_init(&qp->piowait);
        spin_unlock(&dev->pending_lock);
 
        wc.status = IB_WC_WR_FLUSH_ERR;
@@ -427,6 +427,7 @@ static void ipath_error_qp(struct ipath_qp *qp)
 int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                    int attr_mask)
 {
+       struct ipath_ibdev *dev = to_idev(ibqp->device);
        struct ipath_qp *qp = to_iqp(ibqp);
        enum ib_qp_state cur_state, new_state;
        unsigned long flags;
@@ -443,6 +444,19 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                                attr_mask))
                goto inval;
 
+       if (attr_mask & IB_QP_AV)
+               if (attr->ah_attr.dlid == 0 ||
+                   attr->ah_attr.dlid >= IPS_MULTICAST_LID_BASE)
+                       goto inval;
+
+       if (attr_mask & IB_QP_PKEY_INDEX)
+               if (attr->pkey_index >= ipath_layer_get_npkeys(dev->dd))
+                       goto inval;
+
+       if (attr_mask & IB_QP_MIN_RNR_TIMER)
+               if (attr->min_rnr_timer > 31)
+                       goto inval;
+
        switch (new_state) {
        case IB_QPS_RESET:
                ipath_reset_qp(qp);
@@ -457,13 +471,8 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 
        }
 
-       if (attr_mask & IB_QP_PKEY_INDEX) {
-               struct ipath_ibdev *dev = to_idev(ibqp->device);
-
-               if (attr->pkey_index >= ipath_layer_get_npkeys(dev->dd))
-                       goto inval;
+       if (attr_mask & IB_QP_PKEY_INDEX)
                qp->s_pkey_index = attr->pkey_index;
-       }
 
        if (attr_mask & IB_QP_DEST_QPN)
                qp->remote_qpn = attr->dest_qp_num;
@@ -479,12 +488,8 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
        if (attr_mask & IB_QP_ACCESS_FLAGS)
                qp->qp_access_flags = attr->qp_access_flags;
 
-       if (attr_mask & IB_QP_AV) {
-               if (attr->ah_attr.dlid == 0 ||
-                   attr->ah_attr.dlid >= IPS_MULTICAST_LID_BASE)
-                       goto inval;
+       if (attr_mask & IB_QP_AV)
                qp->remote_ah_attr = attr->ah_attr;
-       }
 
        if (attr_mask & IB_QP_PATH_MTU)
                qp->path_mtu = attr->path_mtu;
@@ -499,11 +504,8 @@ int ipath_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
                qp->s_rnr_retry_cnt = qp->s_rnr_retry;
        }
 
-       if (attr_mask & IB_QP_MIN_RNR_TIMER) {
-               if (attr->min_rnr_timer > 31)
-                       goto inval;
+       if (attr_mask & IB_QP_MIN_RNR_TIMER)
                qp->s_min_rnr_timer = attr->min_rnr_timer;
-       }
 
        if (attr_mask & IB_QP_QKEY)
                qp->qkey = attr->qkey;
@@ -710,10 +712,8 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
                             init_attr->qp_type == IB_QPT_RC ?
                             ipath_do_rc_send : ipath_do_uc_send,
                             (unsigned long)qp);
-               qp->piowait.next = LIST_POISON1;
-               qp->piowait.prev = LIST_POISON2;
-               qp->timerwait.next = LIST_POISON1;
-               qp->timerwait.prev = LIST_POISON2;
+               INIT_LIST_HEAD(&qp->piowait);
+               INIT_LIST_HEAD(&qp->timerwait);
                qp->state = IB_QPS_RESET;
                qp->s_wq = swq;
                qp->s_size = init_attr->cap.max_send_wr + 1;
@@ -734,7 +734,7 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd,
                ipath_reset_qp(qp);
 
                /* Tell the core driver that the kernel SMA is present. */
-               if (qp->ibqp.qp_type == IB_QPT_SMI)
+               if (init_attr->qp_type == IB_QPT_SMI)
                        ipath_layer_set_verbs_flags(dev->dd,
                                                    IPATH_VERBS_KERNEL_SMA);
                break;
@@ -783,10 +783,10 @@ int ipath_destroy_qp(struct ib_qp *ibqp)
 
        /* Make sure the QP isn't on the timeout list. */
        spin_lock_irqsave(&dev->pending_lock, flags);
-       if (qp->timerwait.next != LIST_POISON1)
-               list_del(&qp->timerwait);
-       if (qp->piowait.next != LIST_POISON1)
-               list_del(&qp->piowait);
+       if (!list_empty(&qp->timerwait))
+               list_del_init(&qp->timerwait);
+       if (!list_empty(&qp->piowait))
+               list_del_init(&qp->piowait);
        spin_unlock_irqrestore(&dev->pending_lock, flags);
 
        /*
@@ -855,10 +855,10 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc)
 
        spin_lock(&dev->pending_lock);
        /* XXX What if its already removed by the timeout code? */
-       if (qp->timerwait.next != LIST_POISON1)
-               list_del(&qp->timerwait);
-       if (qp->piowait.next != LIST_POISON1)
-               list_del(&qp->piowait);
+       if (!list_empty(&qp->timerwait))
+               list_del_init(&qp->timerwait);
+       if (!list_empty(&qp->piowait))
+               list_del_init(&qp->piowait);
        spin_unlock(&dev->pending_lock);
 
        ipath_cq_enter(to_icq(qp->ibqp.send_cq), wc, 1);
index a4055ca0061427ed7b658b657af110e6cc2cc138..493b1821a93426e8b69e09c54e1e4277edeba410 100644 (file)
@@ -57,7 +57,7 @@ static void ipath_init_restart(struct ipath_qp *qp, struct ipath_swqe *wqe)
        qp->s_len = wqe->length - len;
        dev = to_idev(qp->ibqp.device);
        spin_lock(&dev->pending_lock);
-       if (qp->timerwait.next == LIST_POISON1)
+       if (list_empty(&qp->timerwait))
                list_add_tail(&qp->timerwait,
                              &dev->pending[dev->pending_index]);
        spin_unlock(&dev->pending_lock);
@@ -356,7 +356,7 @@ static inline int ipath_make_rc_req(struct ipath_qp *qp,
                if ((int)(qp->s_psn - qp->s_next_psn) > 0)
                        qp->s_next_psn = qp->s_psn;
                spin_lock(&dev->pending_lock);
-               if (qp->timerwait.next == LIST_POISON1)
+               if (list_empty(&qp->timerwait))
                        list_add_tail(&qp->timerwait,
                                      &dev->pending[dev->pending_index]);
                spin_unlock(&dev->pending_lock);
@@ -726,8 +726,8 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
         */
        dev = to_idev(qp->ibqp.device);
        spin_lock(&dev->pending_lock);
-       if (qp->timerwait.next != LIST_POISON1)
-               list_del(&qp->timerwait);
+       if (!list_empty(&qp->timerwait))
+               list_del_init(&qp->timerwait);
        spin_unlock(&dev->pending_lock);
 
        if (wqe->wr.opcode == IB_WR_RDMA_READ)
@@ -886,8 +886,8 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
         * just won't find anything to restart if we ACK everything.
         */
        spin_lock(&dev->pending_lock);
-       if (qp->timerwait.next != LIST_POISON1)
-               list_del(&qp->timerwait);
+       if (!list_empty(&qp->timerwait))
+               list_del_init(&qp->timerwait);
        spin_unlock(&dev->pending_lock);
 
        /*
@@ -1194,8 +1194,7 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
                     IB_WR_RDMA_READ))
                goto ack_done;
        spin_lock(&dev->pending_lock);
-       if (qp->s_rnr_timeout == 0 &&
-           qp->timerwait.next != LIST_POISON1)
+       if (qp->s_rnr_timeout == 0 && !list_empty(&qp->timerwait))
                list_move_tail(&qp->timerwait,
                               &dev->pending[dev->pending_index]);
        spin_unlock(&dev->pending_lock);
index eb81424b3c5bb9bcb112e392d10c58a78f2530a2..d38f4f3cfd1dd291dd33e17d3780fc9b7ed1d17e 100644 (file)
@@ -435,7 +435,7 @@ void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&dev->pending_lock, flags);
-       if (qp->piowait.next == LIST_POISON1)
+       if (list_empty(&qp->piowait))
                list_add_tail(&qp->piowait, &dev->piowait);
        spin_unlock_irqrestore(&dev->pending_lock, flags);
        /*
index cb9e387c301f2b15320d19f1e79e9522ce40b72d..28fdbdaa789db8acecceb4d72192cd3a5aea19bd 100644 (file)
@@ -464,7 +464,7 @@ static void ipath_ib_timer(void *arg)
        last = &dev->pending[dev->pending_index];
        while (!list_empty(last)) {
                qp = list_entry(last->next, struct ipath_qp, timerwait);
-               list_del(&qp->timerwait);
+               list_del_init(&qp->timerwait);
                qp->timer_next = resend;
                resend = qp;
                atomic_inc(&qp->refcount);
@@ -474,7 +474,7 @@ static void ipath_ib_timer(void *arg)
                qp = list_entry(last->next, struct ipath_qp, timerwait);
                if (--qp->s_rnr_timeout == 0) {
                        do {
-                               list_del(&qp->timerwait);
+                               list_del_init(&qp->timerwait);
                                tasklet_hi_schedule(&qp->s_task);
                                if (list_empty(last))
                                        break;
@@ -554,7 +554,7 @@ static int ipath_ib_piobufavail(void *arg)
        while (!list_empty(&dev->piowait)) {
                qp = list_entry(dev->piowait.next, struct ipath_qp,
                                piowait);
-               list_del(&qp->piowait);
+               list_del_init(&qp->piowait);
                tasklet_hi_schedule(&qp->s_task);
        }
        spin_unlock_irqrestore(&dev->pending_lock, flags);
@@ -951,6 +951,7 @@ static void *ipath_register_ib_device(int unit, struct ipath_devdata *dd)
        idev->dd = dd;
 
        strlcpy(dev->name, "ipath%d", IB_DEVICE_NAME_MAX);
+       dev->owner = THIS_MODULE;
        dev->node_guid = ipath_layer_get_guid(dd);
        dev->uverbs_abi_ver = IPATH_UVERBS_ABI_VERSION;
        dev->uverbs_cmd_mask =
index 1985b5dfa481bdb91efaf5611bba73f83de3a1b1..798e13e14faf826695d8b64a0493a5580e24bd73 100644 (file)
@@ -182,7 +182,7 @@ struct mthca_cmd_context {
        u8                status;
 };
 
-static int fw_cmd_doorbell = 1;
+static int fw_cmd_doorbell = 0;
 module_param(fw_cmd_doorbell, int, 0644);
 MODULE_PARM_DESC(fw_cmd_doorbell, "post FW commands through doorbell page if nonzero "
                 "(and supported by FW)");
index 19765f6f8d5868eca6845d2319819bccdf181e64..07c13be07a4a5da858a975fe6d11059b0da3a35b 100644 (file)
@@ -1727,23 +1727,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
 
        ind = qp->rq.next_ind;
 
-       for (nreq = 0; wr; ++nreq, wr = wr->next) {
-               if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
-                       nreq = 0;
-
-                       doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
-                       doorbell[1] = cpu_to_be32(qp->qpn << 8);
-
-                       wmb();
-
-                       mthca_write64(doorbell,
-                                     dev->kar + MTHCA_RECEIVE_DOORBELL,
-                                     MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
-
-                       qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
-                       size0 = 0;
-               }
-
+       for (nreq = 0; wr; wr = wr->next) {
                if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
                        mthca_err(dev, "RQ %06x full (%u head, %u tail,"
                                        " %d max, %d nreq)\n", qp->qpn,
@@ -1797,6 +1781,23 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                ++ind;
                if (unlikely(ind >= qp->rq.max))
                        ind -= qp->rq.max;
+
+               ++nreq;
+               if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
+                       nreq = 0;
+
+                       doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
+                       doorbell[1] = cpu_to_be32(qp->qpn << 8);
+
+                       wmb();
+
+                       mthca_write64(doorbell,
+                                     dev->kar + MTHCA_RECEIVE_DOORBELL,
+                                     MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+
+                       qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
+                       size0 = 0;
+               }
        }
 
 out:
index 1ea433291fa71883e06fa0743c3f9fd443fe55bd..b292fefa3b411924ea29d693da19f75bf5187ffd 100644 (file)
@@ -490,26 +490,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
 
        first_ind = srq->first_free;
 
-       for (nreq = 0; wr; ++nreq, wr = wr->next) {
-               if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
-                       nreq = 0;
-
-                       doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
-                       doorbell[1] = cpu_to_be32(srq->srqn << 8);
-
-                       /*
-                        * Make sure that descriptors are written
-                        * before doorbell is rung.
-                        */
-                       wmb();
-
-                       mthca_write64(doorbell,
-                                     dev->kar + MTHCA_RECEIVE_DOORBELL,
-                                     MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
-
-                       first_ind = srq->first_free;
-               }
-
+       for (nreq = 0; wr; wr = wr->next) {
                ind = srq->first_free;
 
                if (ind < 0) {
@@ -569,6 +550,26 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
 
                srq->wrid[ind]  = wr->wr_id;
                srq->first_free = next_ind;
+
+               ++nreq;
+               if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
+                       nreq = 0;
+
+                       doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
+                       doorbell[1] = cpu_to_be32(srq->srqn << 8);
+
+                       /*
+                        * Make sure that descriptors are written
+                        * before doorbell is rung.
+                        */
+                       wmb();
+
+                       mthca_write64(doorbell,
+                                     dev->kar + MTHCA_RECEIVE_DOORBELL,
+                                     MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+
+                       first_ind = srq->first_free;
+               }
        }
 
        if (likely(nreq)) {
index c32ce4348e1b817fd59c4c9425a07ca853881a49..9cbdffa08dc2bca6da821638efc0078b24792374 100644 (file)
@@ -340,7 +340,10 @@ static void srp_disconnect_target(struct srp_target_port *target)
        /* XXX should send SRP_I_LOGOUT request */
 
        init_completion(&target->done);
-       ib_send_cm_dreq(target->cm_id, NULL, 0);
+       if (ib_send_cm_dreq(target->cm_id, NULL, 0)) {
+               printk(KERN_DEBUG PFX "Sending CM DREQ failed\n");
+               return;
+       }
        wait_for_completion(&target->done);
 }
 
@@ -351,7 +354,6 @@ static void srp_remove_work(void *target_ptr)
        spin_lock_irq(target->scsi_host->host_lock);
        if (target->state != SRP_TARGET_DEAD) {
                spin_unlock_irq(target->scsi_host->host_lock);
-               scsi_host_put(target->scsi_host);
                return;
        }
        target->state = SRP_TARGET_REMOVED;
@@ -365,8 +367,6 @@ static void srp_remove_work(void *target_ptr)
        ib_destroy_cm_id(target->cm_id);
        srp_free_target_ib(target);
        scsi_host_put(target->scsi_host);
-       /* And another put to really free the target port... */
-       scsi_host_put(target->scsi_host);
 }
 
 static int srp_connect_target(struct srp_target_port *target)
@@ -1241,7 +1241,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
        list_for_each_entry_safe(req, tmp, &target->req_queue, list)
                if (req->scmnd->device == scmnd->device) {
                        req->scmnd->result = DID_RESET << 16;
-                       scmnd->scsi_done(scmnd);
+                       req->scmnd->scsi_done(req->scmnd);
                        srp_remove_req(target, req);
                }
 
index 2b2ec1057deeff1c9fc40f963da81cbbd7267de5..95c0de7964a0803f788764a7426cb66b75f79867 100644 (file)
@@ -589,7 +589,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
        struct sw *sw;
        struct input_dev *input_dev;
        int i, j, k, l;
-       int err;
+       int err = 0;
        unsigned char *buf = NULL;      /* [SW_LENGTH] */
        unsigned char *idbuf = NULL;    /* [SW_LENGTH] */
        unsigned char m = 1;
@@ -776,7 +776,10 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
                        goto fail4;
        }
 
-       return 0;
+ out:  kfree(buf);
+       kfree(idbuf);
+
+       return err;
 
  fail4:        input_free_device(sw->dev[i]);
  fail3:        while (--i >= 0)
@@ -784,9 +787,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
  fail2:        gameport_close(gameport);
  fail1:        gameport_set_drvdata(gameport, NULL);
        kfree(sw);
-       kfree(buf);
-       kfree(idbuf);
-       return err;
+       goto out;
 }
 
 static void sw_disconnect(struct gameport *gameport)
index 96c6bf77248ae7a67dc134ccfffb7f8465ffd974..1f0e720267d75312c0a52eaa44b5e5764eaf53ce 100644 (file)
@@ -245,9 +245,9 @@ static void corgikbd_hinge_timer(unsigned long data)
                if (hinge_count >= HINGE_STABLE_COUNT) {
                        spin_lock_irqsave(&corgikbd_data->lock, flags);
 
-                       input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
-                       input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
-                       input_report_switch(corgikbd_data->input, SW_2, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0));
+                       input_report_switch(corgikbd_data->input, SW_LID, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
+                       input_report_switch(corgikbd_data->input, SW_TABLET_MODE, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
+                       input_report_switch(corgikbd_data->input, SW_HEADPHONE_INSERT, (READ_GPIO_BIT(CORGI_GPIO_AK_INT) != 0));
                        input_sync(corgikbd_data->input);
 
                        spin_unlock_irqrestore(&corgikbd_data->lock, flags);
@@ -340,9 +340,9 @@ static int __init corgikbd_probe(struct platform_device *pdev)
        for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
                set_bit(corgikbd->keycode[i], input_dev->keybit);
        clear_bit(0, input_dev->keybit);
-       set_bit(SW_0, input_dev->swbit);
-       set_bit(SW_1, input_dev->swbit);
-       set_bit(SW_2, input_dev->swbit);
+       set_bit(SW_LID, input_dev->swbit);
+       set_bit(SW_TABLET_MODE, input_dev->swbit);
+       set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
 
        input_register_device(corgikbd->input);
 
index 1d238a9d52d68532d4d29e31f00d6e2be9ab6539..c5d03fb77bcb9a364ca16ea075d469425c671950 100644 (file)
@@ -299,9 +299,9 @@ static void spitzkbd_hinge_timer(unsigned long data)
        if (hinge_count >= HINGE_STABLE_COUNT) {
                spin_lock_irqsave(&spitzkbd_data->lock, flags);
 
-               input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
-               input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
-               input_report_switch(spitzkbd_data->input, SW_2, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0));
+               input_report_switch(spitzkbd_data->input, SW_LID, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
+               input_report_switch(spitzkbd_data->input, SW_TABLET_MODE, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
+               input_report_switch(spitzkbd_data->input, SW_HEADPHONE_INSERT, ((GPLR(SPITZ_GPIO_AK_INT) & GPIO_bit(SPITZ_GPIO_AK_INT)) != 0));
                input_sync(spitzkbd_data->input);
 
                spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
@@ -398,9 +398,9 @@ static int __init spitzkbd_probe(struct platform_device *dev)
        for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
                set_bit(spitzkbd->keycode[i], input_dev->keybit);
        clear_bit(0, input_dev->keybit);
-       set_bit(SW_0, input_dev->swbit);
-       set_bit(SW_1, input_dev->swbit);
-       set_bit(SW_2, input_dev->swbit);
+       set_bit(SW_LID, input_dev->swbit);
+       set_bit(SW_TABLET_MODE, input_dev->swbit);
+       set_bit(SW_HEADPHONE_INSERT, input_dev->swbit);
 
        input_register_device(input_dev);
 
index 36cd2e07fce8bf6be22b476a462ac375d698a1b5..e4e5be111c960b67834e2742a9475bbd73b2d42f 100644 (file)
@@ -318,6 +318,16 @@ static struct key_entry keymap_acer_travelmate_240[] = {
        { KE_END, 0 }
 };
 
+static struct key_entry keymap_aopen_1559as[] = {
+       { KE_KEY,  0x01, KEY_HELP },
+       { KE_KEY,  0x06, KEY_PROG3 },
+       { KE_KEY,  0x11, KEY_PROG1 },
+       { KE_KEY,  0x12, KEY_PROG2 },
+       { KE_WIFI, 0x30, 0 },
+       { KE_KEY,  0x31, KEY_MAIL },
+       { KE_KEY,  0x36, KEY_WWW },
+};
+
 /*
  * If your machine is not here (which is currently rather likely), please send
  * a list of buttons and their key codes (reported when loading this module
@@ -369,6 +379,15 @@ static struct dmi_system_id dmi_ids[] = {
                },
                .driver_data = keymap_acer_travelmate_240
        },
+        {
+               .callback = dmi_matched,
+               .ident = "AOpen 1559AS",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "E2U"),
+                       DMI_MATCH(DMI_BOARD_NAME, "E2U"),
+               },
+               .driver_data = keymap_aopen_1559as
+       },
        { NULL, }
 };
 
index 2141501e9f2e498246df66233623490ade12494a..a0e2e797c6d5a6c9e3cceeb6659a9299630c5af5 100644 (file)
@@ -100,8 +100,8 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
        }
 
        if (priv->i->flags & ALPS_OLDPROTO) {
-               left = packet[2] & 0x08;
-               right = packet[2] & 0x10;
+               left = packet[2] & 0x10;
+               right = packet[2] & 0x08;
                middle = 0;
                x = packet[1] | ((packet[0] & 0x07) << 7);
                y = packet[4] | ((packet[3] & 0x07) << 7);
index 5ccc3ef3b89e84fe4d246a7a3fc6fd6d0b943394..c14395ba798005d31a14b7c3c0e135548ed4c03d 100644 (file)
 #include "lifebook.h"
 
 static struct dmi_system_id lifebook_dmi_table[] = {
+       {
+               .ident = "LifeBook B",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B Series"),
+               },
+       },
        {
                .ident = "Lifebook B",
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"),
                },
        },
+       {
+               .ident = "Lifebook B213x/B2150",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B2131/B2133/B2150"),
+               },
+       },
+       {
+               .ident = "Zephyr",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZEPHYR"),
+               },
+       },
+       {
+               .ident = "CF-18",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"),
+               },
+       },
        {
                .ident = "Lifebook B142",
                .matches = {
index 40333d61093c805383ed3f7ae245dfdd12a51f95..2f0d28840810aad3c4811d276aa1a0cb6ffb17b8 100644 (file)
@@ -19,6 +19,7 @@
 #define PS2PP_KIND_WHEEL       1
 #define PS2PP_KIND_MX          2
 #define PS2PP_KIND_TP3         3
+#define PS2PP_KIND_TRACKMAN    4
 
 /* Logitech mouse features */
 #define PS2PP_WHEEL            0x01
@@ -223,6 +224,7 @@ static struct ps2pp_info *get_model_info(unsigned char model)
                { 73,   0,                      PS2PP_SIDE_BTN },
                { 75,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
                { 76,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
+               { 79,   PS2PP_KIND_TRACKMAN,    PS2PP_WHEEL },          /* TrackMan with wheel */
                { 80,   PS2PP_KIND_WHEEL,       PS2PP_SIDE_BTN | PS2PP_WHEEL },
                { 81,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
                { 83,   PS2PP_KIND_WHEEL,       PS2PP_WHEEL },
@@ -298,6 +300,10 @@ static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_inf
                        psmouse->name = "TouchPad 3";
                        break;
 
+               case PS2PP_KIND_TRACKMAN:
+                       psmouse->name = "TrackMan";
+                       break;
+
                default:
                        /*
                         * Set name to "Mouse" only when using PS2++,
index 1494175ac6fe43d0666e3cfed2426cfb0e622ed5..161afddd0f44396da88402f0af5bb2b9445f1a74 100644 (file)
 
 
 /*
- * This code has been tested on an ads7846 / N770 device.
+ * This code has been heavily tested on a Nokia 770, and lightly
+ * tested on other ads7846 devices (OSK/Mistral, Lubbock).
  * Support for ads7843 and ads7845 has only been stubbed in.
  *
- * Not yet done:  How accurate are the temperature and voltage
- * readings? (System-specific calibration should support
- * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
- *
  * IRQ handling needs a workaround because of a shortcoming in handling
  * edge triggered IRQs on some platforms like the OMAP1/2. These
  * platforms don't handle the ARM lazy IRQ disabling properly, thus we
@@ -248,10 +245,13 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
 
        if (req->msg.status)
                status = req->msg.status;
+
+       /* on-wire is a must-ignore bit, a BE12 value, then padding */
        sample = be16_to_cpu(req->sample);
-       sample = sample >> 4;
-       kfree(req);
+       sample = sample >> 3;
+       sample &= 0x0fff;
 
+       kfree(req);
        return status ? status : sample;
 }
 
@@ -336,13 +336,13 @@ static void ads7846_rx(void *ads)
        u16                     x, y, z1, z2;
        unsigned long           flags;
 
-       /* adjust:  12 bit samples (left aligned), built from
-        * two 8 bit values writen msb-first.
+       /* adjust:  on-wire is a must-ignore bit, a BE12 value, then padding;
+        * built from two 8 bit values written msb-first.
         */
-       x = be16_to_cpu(ts->tc.x) >> 4;
-       y = be16_to_cpu(ts->tc.y) >> 4;
-       z1 = be16_to_cpu(ts->tc.z1) >> 4;
-       z2 = be16_to_cpu(ts->tc.z2) >> 4;
+       x = (be16_to_cpu(ts->tc.x) >> 3) & 0x0fff;
+       y = (be16_to_cpu(ts->tc.y) >> 3) & 0x0fff;
+       z1 = (be16_to_cpu(ts->tc.z1) >> 3) & 0x0fff;
+       z2 = (be16_to_cpu(ts->tc.z2) >> 3) & 0x0fff;
 
        /* range filtering */
        if (x == MAX_12BIT)
@@ -420,7 +420,7 @@ static void ads7846_debounce(void *ads)
 
        m = &ts->msg[ts->msg_idx];
        t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
-       val = (*(u16 *)t->rx_buf) >> 3;
+       val = (be16_to_cpu(*(__be16 *)t->rx_buf) >> 3) & 0x0fff;
        if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) {
                /* Repeat it, if this was the first read or the read
                 * wasn't consistent enough. */
@@ -469,7 +469,7 @@ static void ads7846_timer(unsigned long handle)
        spin_lock_irq(&ts->lock);
 
        if (unlikely(ts->msg_idx && !ts->pendown)) {
-               /* measurment cycle ended */
+               /* measurement cycle ended */
                if (!device_suspended(&ts->spi->dev)) {
                        ts->irq_disabled = 0;
                        enable_irq(ts->spi->irq);
@@ -495,11 +495,10 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
        spin_lock_irqsave(&ts->lock, flags);
        if (likely(ts->get_pendown_state())) {
                if (!ts->irq_disabled) {
-                       /* REVISIT irq logic for many ARM chips has cloned a
-                        * bug wherein disabling an irq in its handler won't
-                        * work;(it's disabled lazily, and too late to work.
-                        * until all their irq logic is fixed, we must shadow
-                        * that state here.
+                       /* The ARM do_simple_IRQ() dispatcher doesn't act
+                        * like the other dispatchers:  it will report IRQs
+                        * even after they've been disabled.  We work around
+                        * that here.  (The "generic irq" framework may help...)
                         */
                        ts->irq_disabled = 1;
                        disable_irq(ts->spi->irq);
@@ -609,16 +608,20 @@ static int __devinit ads7846_probe(struct spi_device *spi)
                return -EINVAL;
        }
 
+       /* REVISIT when the irq can be triggered active-low, or if for some
+        * reason the touchscreen isn't hooked up, we don't need to access
+        * the pendown state.
+        */
        if (pdata->get_pendown_state == NULL) {
                dev_dbg(&spi->dev, "no get_pendown_state function?\n");
                return -EINVAL;
        }
 
-       /* We'd set the wordsize to 12 bits ... except that some controllers
-        * will then treat the 8 bit command words as 12 bits (and drop the
-        * four MSBs of the 12 bit result).  Result: inputs must be shifted
-        * to discard the four garbage LSBs.
+       /* We'd set TX wordsize 8 bits and RX wordsize to 13 bits ... except
+        * that even if the hardware can do that, the SPI controller driver
+        * may not.  So we stick to very-portable 8 bit words, both RX and TX.
         */
+       spi->bits_per_word = 8;
 
        ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
        input_dev = input_allocate_device();
@@ -772,7 +775,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
 
        if (request_irq(spi->irq, ads7846_irq,
                        SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
-                       spi->dev.bus_id, ts)) {
+                       spi->dev.driver->name, ts)) {
                dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
                err = -EBUSY;
                goto err_free_mem;
index 3585fb1f334460ae69a3c24e32c0ee03d52def49..2ac90242d263714b7d6108a9005982ef660c02d7 100644 (file)
@@ -2880,7 +2880,7 @@ isdn_tty_cmd_ATand(char **p, modem_info * info)
                        p[0]++;
                        i = 0;
                        while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) &&
-                              (i < ISDN_LMSNLEN))
+                              (i < ISDN_LMSNLEN - 1))
                                m->lmsn[i++] = *p[0]++;
                        m->lmsn[i] = '\0';
                        break;
index d7316b829a62687a4c29372a893d2684121fb3a3..f19b874753a9c4aec3802b557ab05100f387ff61 100644 (file)
@@ -167,6 +167,15 @@ void md_new_event(mddev_t *mddev)
 }
 EXPORT_SYMBOL_GPL(md_new_event);
 
+/* Alternate version that can be called from interrupts
+ * when calling sysfs_notify isn't needed.
+ */
+void md_new_event_inintr(mddev_t *mddev)
+{
+       atomic_inc(&md_event_count);
+       wake_up(&md_event_waiters);
+}
+
 /*
  * Enables to iterate over all existing md arrays
  * all_mddevs_lock protects this list.
@@ -2252,7 +2261,7 @@ action_store(mddev_t *mddev, const char *page, size_t len)
        } else {
                if (cmd_match(page, "check"))
                        set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
-               else if (cmd_match(page, "repair"))
+               else if (!cmd_match(page, "repair"))
                        return -EINVAL;
                set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
                set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
@@ -4149,7 +4158,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
        set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        md_wakeup_thread(mddev->thread);
-       md_new_event(mddev);
+       md_new_event_inintr(mddev);
 }
 
 /* seq_file implementation /proc/mdstat */
@@ -5028,8 +5037,10 @@ static int md_notify_reboot(struct notifier_block *this,
                printk(KERN_INFO "md: stopping all md devices.\n");
 
                ITERATE_MDDEV(mddev,tmp)
-                       if (mddev_trylock(mddev))
+                       if (mddev_trylock(mddev)) {
                                do_md_stop (mddev, 1);
+                               mddev_unlock(mddev);
+                       }
                /*
                 * certain more exotic SCSI devices are known to be
                 * volatile wrt too early system reboots. While the
index 678f4dbbea1d5c22082d13fb1afd321465b61f28..cb8c6317e4e5fc367c7098a87e310b5ed059f724 100644 (file)
@@ -331,13 +331,14 @@ static int raid0_run (mddev_t *mddev)
                goto out_free_conf;
        size = conf->strip_zone[cur].size;
 
-       for (i=0; i< nb_zone; i++) {
-               conf->hash_table[i] = conf->strip_zone + cur;
+       conf->hash_table[0] = conf->strip_zone + cur;
+       for (i=1; i< nb_zone; i++) {
                while (size <= conf->hash_spacing) {
                        cur++;
                        size += conf->strip_zone[cur].size;
                }
                size -= conf->hash_spacing;
+               conf->hash_table[i] = conf->strip_zone + cur;
        }
        if (conf->preshift) {
                conf->hash_spacing >>= conf->preshift;
index fffc711c260caec4dffb7e358ce98afc3f7bb902..344d83aae3ec3b5d6d7b4e9e41dee2f47d59e79f 100644 (file)
@@ -8,22 +8,54 @@ config VIDEO_DEV
        tristate "Video For Linux"
        ---help---
          Support for audio/video capture and overlay devices and FM radio
-         cards. The exact capabilities of each device vary. User tools for
-         this are available from
-         <ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
+         cards. The exact capabilities of each device vary.
 
          This kernel includes support for the new Video for Linux Two API,
          (V4L2) as well as the original system. Drivers and applications
          need to be rewritten to use V4L2, but drivers for popular cards
          and applications for most video capture functions already exist.
 
-         Documentation for the original API is included in the file
-         <file:Documentation/video4linux/API.html>.  Documentation for V4L2 is
-         available on the web at <http://bytesex.org/v4l/>.
+         Additional info and docs are available on the web at
+         <http://linuxtv.org>
+
+         Documentation for V4L2 is also available on the web at
+         <http://bytesex.org/v4l/>.
 
          To compile this driver as a module, choose M here: the
          module will be called videodev.
 
+config VIDEO_V4L1
+       boolean "Enable Video For Linux API 1 (DEPRECATED)"
+       depends on VIDEO_DEV
+       select VIDEO_V4L1_COMPAT
+       default y
+       ---help---
+         Enables a compatibility API used by most V4L2 devices to allow
+         its usage with legacy applications that supports only V4L1 api.
+
+         If you are unsure as to whether this is required, answer Y.
+
+config VIDEO_V4L1_COMPAT
+       boolean "Enable Video For Linux API 1 compatible Layer"
+       depends on VIDEO_DEV
+       default y
+       ---help---
+         This api were developed to be used at Kernel 2.2 and 2.4, but
+         lacks support for several video standards. There are several
+         drivers at kernel that still depends on it.
+
+         Documentation for the original API is included in the file
+         <Documentation/video4linux/API.html>.
+
+         User tools for this are available from
+         <ftp://ftp.uk.linux.org/pub/linux/video4linux/>.
+
+         If you are unsure as to whether this is required, answer Y.
+
+config VIDEO_V4L2
+       tristate
+       default y
+
 source "drivers/media/video/Kconfig"
 
 source "drivers/media/radio/Kconfig"
@@ -65,4 +97,3 @@ config USB_DABUSB
          module will be called dabusb.
 
 endmenu
-
index 6a901a0268e174a6cdfde7a4b08aee76ff956fe6..1a04db4552da9dc2521867eaff7fd4c5666c7d89 100644 (file)
@@ -1,9 +1,10 @@
 config VIDEO_SAA7146
        tristate
-       select I2C
+       depends on I2C
 
 config VIDEO_SAA7146_VV
        tristate
+       select VIDEO_V4L2
        select VIDEO_BUF
        select VIDEO_VIDEOBUF
        select VIDEO_SAA7146
index 3f0ec6be03ae353811b264f83283e5f5a86721de..a97c8f5e9a5d1dc13f6414106e9f75cc7ab9cd09 100644 (file)
@@ -22,26 +22,26 @@ config DVB
 source "drivers/media/dvb/dvb-core/Kconfig"
 
 comment "Supported SAA7146 based PCI Adapters"
-       depends on DVB_CORE && PCI
+       depends on DVB_CORE && PCI && I2C
 source "drivers/media/dvb/ttpci/Kconfig"
 
 comment "Supported USB Adapters"
-       depends on DVB_CORE && USB
+       depends on DVB_CORE && USB && I2C
 source "drivers/media/dvb/dvb-usb/Kconfig"
 source "drivers/media/dvb/ttusb-budget/Kconfig"
 source "drivers/media/dvb/ttusb-dec/Kconfig"
 source "drivers/media/dvb/cinergyT2/Kconfig"
 
 comment "Supported FlexCopII (B2C2) Adapters"
-       depends on DVB_CORE && (PCI || USB)
+       depends on DVB_CORE && (PCI || USB) && I2C
 source "drivers/media/dvb/b2c2/Kconfig"
 
 comment "Supported BT878 Adapters"
-       depends on DVB_CORE && PCI
+       depends on DVB_CORE && PCI && I2C
 source "drivers/media/dvb/bt8xx/Kconfig"
 
 comment "Supported Pluto2 Adapters"
-       depends on DVB_CORE && PCI
+       depends on DVB_CORE && PCI && I2C
 source "drivers/media/dvb/pluto2/Kconfig"
 
 comment "Supported DVB Frontends"
index 2963605c0ecc236c3c95ea7f22595b4c095702a1..d7f1fd5b7b02a8c62c74d9867a3a228f24b46fda 100644 (file)
@@ -1,6 +1,6 @@
 config DVB_B2C2_FLEXCOP
        tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters"
-       depends on DVB_CORE
+       depends on DVB_CORE && I2C
        select DVB_STV0299
        select DVB_MT352
        select DVB_MT312
@@ -16,7 +16,7 @@ config DVB_B2C2_FLEXCOP
 
 config DVB_B2C2_FLEXCOP_PCI
        tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI"
-       depends on DVB_B2C2_FLEXCOP && PCI
+       depends on DVB_B2C2_FLEXCOP && PCI && I2C
        help
          Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2.
 
@@ -24,7 +24,7 @@ config DVB_B2C2_FLEXCOP_PCI
 
 config DVB_B2C2_FLEXCOP_USB
        tristate "Technisat/B2C2 Air/Sky/Cable2PC USB"
-       depends on DVB_B2C2_FLEXCOP && USB
+       depends on DVB_B2C2_FLEXCOP && USB && I2C
        help
          Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2,
 
index 376ca48f1d1da61e843b6fb0aead0203bf926ea7..f394002118f81d48da7aca9846bc7271d4ea19e5 100644 (file)
@@ -1,12 +1,13 @@
 config DVB_BT8XX
        tristate "BT8xx based PCI cards"
-       depends on DVB_CORE && PCI && VIDEO_BT848
+       depends on DVB_CORE && PCI && I2C && VIDEO_BT848
        select DVB_MT352
        select DVB_SP887X
        select DVB_NXT6000
        select DVB_CX24110
        select DVB_OR51211
        select DVB_LGDT330X
+       select DVB_ZL10353
        select FW_LOADER
        help
          Support for PCI cards based on the Bt8xx PCI bridge. Examples are
index baa8227ef87c8d5e045f24ffb8defb011ef6cdaa..ccc7b2eb4a2d33a424e243612634928821c0e096 100644 (file)
@@ -115,7 +115,7 @@ static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev)
        return 0;
 }
 
-static struct bt878 __init *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
+static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev)
 {
        unsigned int card_nr;
 
@@ -709,7 +709,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
                }
 }
 
-static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
+static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
 {
        int result;
 
@@ -794,7 +794,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type)
        return 0;
 }
 
-static int dvb_bt8xx_probe(struct bttv_sub_device *sub)
+static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
 {
        struct dvb_bt8xx_card *card;
        struct pci_dev* bttv_pci_dev;
index 71b575dc22bdb2fbfe7a21261da549ffaa8f2cb6..9325d039ea652c622071b04d8c31ed7e6ff473ef 100644 (file)
@@ -902,7 +902,10 @@ static int cinergyt2_probe (struct usb_interface *intf,
                return -ENOMEM;
        }
 
-       dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE);
+       if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) {
+               kfree(cinergyt2);
+               return err;
+       }
 
        cinergyt2->demux.priv = cinergyt2;
        cinergyt2->demux.filternum = 256;
index 4f8f257e67951f38c90b714dd9feadefb17bfadf..a051790161b095f674010e0e286c882f8df0b0a3 100644 (file)
@@ -106,6 +106,8 @@ struct dvb_frontend_private {
        unsigned long tune_mode_flags;
        unsigned int delay;
        unsigned int reinitialise;
+       int tone;
+       int voltage;
 
        /* swzigzag values */
        unsigned int state;
@@ -537,6 +539,12 @@ static int dvb_frontend_thread(void *data)
 
                if (fepriv->reinitialise) {
                        dvb_frontend_init(fe);
+                       if (fepriv->tone != -1) {
+                               fe->ops->set_tone(fe, fepriv->tone);
+                       }
+                       if (fepriv->voltage != -1) {
+                               fe->ops->set_voltage(fe, fepriv->voltage);
+                       }
                        fepriv->reinitialise = 0;
                }
 
@@ -788,6 +796,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
        case FE_SET_TONE:
                if (fe->ops->set_tone) {
                        err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg);
+                       fepriv->tone = (fe_sec_tone_mode_t) parg;
                        fepriv->state = FESTATE_DISEQC;
                        fepriv->status = 0;
                }
@@ -796,6 +805,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
        case FE_SET_VOLTAGE:
                if (fe->ops->set_voltage) {
                        err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg);
+                       fepriv->voltage = (fe_sec_voltage_t) parg;
                        fepriv->state = FESTATE_DISEQC;
                        fepriv->status = 0;
                }
@@ -995,6 +1005,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
 
                /* normal tune mode when opened R/W */
                fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT;
+               fepriv->tone = -1;
+               fepriv->voltage = -1;
        }
 
        return ret;
index 96fe0ecae25089da66ee5bd4ca77dd4261dcdd34..3852430d0260e65fc5daf8045c07bd19031933e0 100644 (file)
@@ -219,8 +219,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
                return -ENOMEM;
        }
 
-       mutex_unlock(&dvbdev_register_lock);
-
        memcpy(dvbdev, template, sizeof(struct dvb_device));
        dvbdev->type = type;
        dvbdev->id = id;
@@ -231,6 +229,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 
        list_add_tail (&dvbdev->list_head, &adap->device_list);
 
+       mutex_unlock(&dvbdev_register_lock);
+
        devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
                        S_IFCHR | S_IRUSR | S_IWUSR,
                        "dvb/adapter%d/%s%d", adap->num, dnames[type], id);
index d3df12039b066dcc4bf83a9dd174489baa1f9262..e388fb1567d6ec6d813158bc29516e07ecd8c496 100644 (file)
@@ -1,6 +1,6 @@
 config DVB_USB
        tristate "Support for various USB DVB devices"
-       depends on DVB_CORE && USB
+       depends on DVB_CORE && USB && I2C
        select FW_LOADER
        help
          By enabling this you will be able to choose the various supported
index 7edd6362b9cc677d414a34e21db232fd8e5e017a..1f0d3e995c8d67e64419b4493b56085719820204 100644 (file)
@@ -150,6 +150,15 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
                return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
 }
 
+static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+       u8 b = 0;
+       if (onoff)
+               return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
+       else
+               return 0;
+}
+
 static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
 {
        u8 buf[2] = { 0x03, 0x00 };
@@ -544,7 +553,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
        .size_of_priv     = sizeof(struct cxusb_state),
 
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_power_ctrl,
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_lgdt3303_frontend_attach,
        .tuner_attach     = cxusb_lgh064f_tuner_attach,
 
@@ -589,7 +598,7 @@ static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = {
        .size_of_priv     = sizeof(struct cxusb_state),
 
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_power_ctrl,
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_dee1601_frontend_attach,
        .tuner_attach     = cxusb_dee1601_tuner_attach,
 
@@ -638,7 +647,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgz201_properties = {
        .size_of_priv     = sizeof(struct cxusb_state),
 
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_power_ctrl,
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_mt352_frontend_attach,
        .tuner_attach     = cxusb_lgz201_tuner_attach,
 
@@ -683,7 +692,7 @@ static struct dvb_usb_properties cxusb_bluebird_dtt7579_properties = {
        .size_of_priv     = sizeof(struct cxusb_state),
 
        .streaming_ctrl   = cxusb_streaming_ctrl,
-       .power_ctrl       = cxusb_power_ctrl,
+       .power_ctrl       = cxusb_bluebird_power_ctrl,
        .frontend_attach  = cxusb_mt352_frontend_attach,
        .tuner_attach     = cxusb_dtt7579_tuner_attach,
 
index d661c6f9cbe527cfc0138ea79f2fc12fe315e310..691dc840dcc06ee15ad125aec428c6093413ad66 100644 (file)
@@ -29,6 +29,9 @@
 #include "dvb_frontend.h"
 #include "cx24123.h"
 
+#define XTAL 10111000
+
+static int force_band;
 static int debug;
 #define dprintk(args...) \
        do { \
@@ -52,6 +55,7 @@ struct cx24123_state
        u32 VGAarg;
        u32 bandselectarg;
        u32 pllarg;
+       u32 FILTune;
 
        /* The Demod/Tuner can't easily provide these, we cache them */
        u32 currentfreq;
@@ -63,43 +67,33 @@ static struct
 {
        u32 symbolrate_low;
        u32 symbolrate_high;
-       u32 VCAslope;
-       u32 VCAoffset;
-       u32 VGA1offset;
-       u32 VGA2offset;
        u32 VCAprogdata;
        u32 VGAprogdata;
+       u32 FILTune;
 } cx24123_AGC_vals[] =
 {
        {
                .symbolrate_low         = 1000000,
                .symbolrate_high        = 4999999,
-               .VCAslope               = 0x07,
-               .VCAoffset              = 0x0f,
-               .VGA1offset             = 0x1f8,
-               .VGA2offset             = 0x1f8,
-               .VGAprogdata            = (2 << 18) | (0x1f8 << 9) | 0x1f8,
-               .VCAprogdata            = (4 << 18) | (0x07 << 9) | 0x07,
+               /* the specs recommend other values for VGA offsets,
+                  but tests show they are wrong */
+               .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
+               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x07,
+               .FILTune                = 0x27f /* 0.41 V */
        },
        {
                .symbolrate_low         =  5000000,
                .symbolrate_high        = 14999999,
-               .VCAslope               = 0x1f,
-               .VCAoffset              = 0x1f,
-               .VGA1offset             = 0x1e0,
-               .VGA2offset             = 0x180,
-               .VGAprogdata            = (2 << 18) | (0x180 << 9) | 0x1e0,
-               .VCAprogdata            = (4 << 18) | (0x07 << 9) | 0x1f,
+               .VGAprogdata            = (1 << 19) | (0x180 << 9) | 0x1e0,
+               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x1f,
+               .FILTune                = 0x317 /* 0.90 V */
        },
        {
                .symbolrate_low         = 15000000,
                .symbolrate_high        = 45000000,
-               .VCAslope               = 0x3f,
-               .VCAoffset              = 0x3f,
-               .VGA1offset             = 0x180,
-               .VGA2offset             = 0x100,
-               .VGAprogdata            = (2 << 18) | (0x100 << 9) | 0x180,
-               .VCAprogdata            = (4 << 18) | (0x07 << 9) | 0x3f,
+               .VGAprogdata            = (1 << 19) | (0x100 << 9) | 0x180,
+               .VCAprogdata            = (2 << 19) | (0x07 << 9) | 0x3f,
+               .FILTune                = 0x145 /* 2.70 V */
        },
 };
 
@@ -112,91 +106,80 @@ static struct
 {
        u32 freq_low;
        u32 freq_high;
-       u32 bandselect;
        u32 VCOdivider;
-       u32 VCOnumber;
        u32 progdata;
 } cx24123_bandselect_vals[] =
 {
+       /* band 1 */
        {
                .freq_low       = 950000,
-               .freq_high      = 1018999,
-               .bandselect     = 0x40,
-               .VCOdivider     = 4,
-               .VCOnumber      = 7,
-               .progdata       = (0 << 18) | (0 << 9) | 0x40,
-       },
-       {
-               .freq_low       = 1019000,
                .freq_high      = 1074999,
-               .bandselect     = 0x80,
                .VCOdivider     = 4,
-               .VCOnumber      = 8,
-               .progdata       = (0 << 18) | (0 << 9) | 0x80,
+               .progdata       = (0 << 19) | (0 << 9) | 0x40,
        },
+
+       /* band 2 */
        {
                .freq_low       = 1075000,
-               .freq_high      = 1227999,
-               .bandselect     = 0x01,
-               .VCOdivider     = 2,
-               .VCOnumber      = 1,
-               .progdata       = (0 << 18) | (1 << 9) | 0x01,
+               .freq_high      = 1177999,
+               .VCOdivider     = 4,
+               .progdata       = (0 << 19) | (0 << 9) | 0x80,
        },
+
+       /* band 3 */
        {
-               .freq_low       = 1228000,
-               .freq_high      = 1349999,
-               .bandselect     = 0x02,
+               .freq_low       = 1178000,
+               .freq_high      = 1295999,
                .VCOdivider     = 2,
-               .VCOnumber      = 2,
-               .progdata       = (0 << 18) | (1 << 9) | 0x02,
+               .progdata       = (0 << 19) | (1 << 9) | 0x01,
        },
+
+       /* band 4 */
        {
-               .freq_low       = 1350000,
-               .freq_high      = 1481999,
-               .bandselect     = 0x04,
+               .freq_low       = 1296000,
+               .freq_high      = 1431999,
                .VCOdivider     = 2,
-               .VCOnumber      = 3,
-               .progdata       = (0 << 18) | (1 << 9) | 0x04,
+               .progdata       = (0 << 19) | (1 << 9) | 0x02,
        },
+
+       /* band 5 */
        {
-               .freq_low       = 1482000,
-               .freq_high      = 1595999,
-               .bandselect     = 0x08,
+               .freq_low       = 1432000,
+               .freq_high      = 1575999,
                .VCOdivider     = 2,
-               .VCOnumber      = 4,
-               .progdata       = (0 << 18) | (1 << 9) | 0x08,
+               .progdata       = (0 << 19) | (1 << 9) | 0x04,
        },
+
+       /* band 6 */
        {
-               .freq_low       = 1596000,
+               .freq_low       = 1576000,
                .freq_high      = 1717999,
-               .bandselect     = 0x10,
                .VCOdivider     = 2,
-               .VCOnumber      = 5,
-               .progdata       = (0 << 18) | (1 << 9) | 0x10,
+               .progdata       = (0 << 19) | (1 << 9) | 0x08,
        },
+
+       /* band 7 */
        {
                .freq_low       = 1718000,
                .freq_high      = 1855999,
-               .bandselect     = 0x20,
                .VCOdivider     = 2,
-               .VCOnumber      = 6,
-               .progdata       = (0 << 18) | (1 << 9) | 0x20,
+               .progdata       = (0 << 19) | (1 << 9) | 0x10,
        },
+
+       /* band 8 */
        {
                .freq_low       = 1856000,
                .freq_high      = 2035999,
-               .bandselect     = 0x40,
                .VCOdivider     = 2,
-               .VCOnumber      = 7,
-               .progdata       = (0 << 18) | (1 << 9) | 0x40,
+               .progdata       = (0 << 19) | (1 << 9) | 0x20,
        },
+
+       /* band 9 */
        {
                .freq_low       = 2036000,
-               .freq_high      = 2149999,
-               .bandselect     = 0x80,
+               .freq_high      = 2150000,
                .VCOdivider     = 2,
-               .VCOnumber      = 8,
-               .progdata       = (0 << 18) | (1 << 9) | 0x80,
+               .progdata       = (0 << 19) | (1 << 9) | 0x40,
        },
 };
 
@@ -207,49 +190,44 @@ static struct {
 {
        {0x00, 0x03}, /* Reset system */
        {0x00, 0x00}, /* Clear reset */
-       {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */
-       {0x03, 0x07},
-       {0x04, 0x10},
-       {0x05, 0x04},
-       {0x06, 0x31},
-       {0x0d, 0x02},
-       {0x0e, 0x03},
-       {0x0f, 0xfe},
-       {0x10, 0x01},
-       {0x14, 0x01},
-       {0x15, 0x98},
-       {0x16, 0x00},
-       {0x17, 0x01},
-       {0x1b, 0x05},
-       {0x1c, 0x80},
-       {0x1d, 0x00},
-       {0x1e, 0x00},
-       {0x20, 0x41},
-       {0x21, 0x15},
-       {0x27, 0x14},
-       {0x28, 0x46},
-       {0x29, 0x00},
-       {0x2a, 0xb0},
-       {0x2b, 0x73},
-       {0x2c, 0x00},
+       {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
+       {0x04, 0x10}, /* MPEG */
+       {0x05, 0x04}, /* MPEG */
+       {0x06, 0x31}, /* MPEG (default) */
+       {0x0b, 0x00}, /* Freq search start point (default) */
+       {0x0c, 0x00}, /* Demodulator sample gain (default) */
+       {0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */
+       {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
+       {0x0f, 0xfe}, /* FEC search mask (all supported codes) */
+       {0x10, 0x01}, /* Default search inversion, no repeat (default) */
+       {0x16, 0x00}, /* Enable reading of frequency */
+       {0x17, 0x01}, /* Enable EsNO Ready Counter */
+       {0x1c, 0x80}, /* Enable error counter */
+       {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
+       {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
+       {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
+       {0x29, 0x00}, /* DiSEqC LNB_DC off */
+       {0x2a, 0xb0}, /* DiSEqC Parameters (default) */
+       {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
+       {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
        {0x2d, 0x00},
        {0x2e, 0x00},
        {0x2f, 0x00},
        {0x30, 0x00},
        {0x31, 0x00},
-       {0x32, 0x8c},
-       {0x33, 0x00},
+       {0x32, 0x8c}, /* DiSEqC Parameters (default) */
+       {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
        {0x34, 0x00},
-       {0x35, 0x03},
-       {0x36, 0x02},
-       {0x37, 0x3a},
-       {0x3a, 0x00},   /* Enable AGC accumulator */
-       {0x44, 0x00},
-       {0x45, 0x00},
-       {0x46, 0x05},
-       {0x56, 0x41},
-       {0x57, 0xff},
-       {0x67, 0x83},
+       {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
+       {0x36, 0x02}, /* DiSEqC Parameters (default) */
+       {0x37, 0x3a}, /* DiSEqC Parameters (default) */
+       {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
+       {0x44, 0x00}, /* Constellation (default) */
+       {0x45, 0x00}, /* Symbol count (default) */
+       {0x46, 0x0d}, /* Symbol rate estimator on (default) */
+       {0x56, 0x41}, /* Various (default) */
+       {0x57, 0xff}, /* Error Counter Window (default) */
+       {0x67, 0x83}, /* Non-DCII symbol clock */
 };
 
 static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
@@ -258,6 +236,10 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
        struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
        int err;
 
+       if (debug>1)
+               printk("cx24123: %s:  write reg 0x%02x, value 0x%02x\n",
+                                               __FUNCTION__,reg, data);
+
        if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
                printk("%s: writereg error(err == %i, reg == 0x%02x,"
                         " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
@@ -274,6 +256,10 @@ static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
        struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
        int err;
 
+       if (debug>1)
+               printk("cx24123: %s:  writeln addr=0x08, reg 0x%02x, value 0x%02x\n",
+                                               __FUNCTION__,reg, data);
+
        if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
                printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
                         " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
@@ -303,6 +289,9 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg)
                return ret;
        }
 
+       if (debug>1)
+               printk("cx24123: read reg 0x%02x, value 0x%02x\n",reg, ret);
+
        return b1[0];
 }
 
@@ -313,17 +302,23 @@ static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
 
 static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
 {
+       u8 nom_reg = cx24123_readreg(state, 0x0e);
+       u8 auto_reg = cx24123_readreg(state, 0x10);
+
        switch (inversion) {
        case INVERSION_OFF:
-               cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f);
-               cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
+               dprintk("%s:  inversion off\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
+               cx24123_writereg(state, 0x10, auto_reg | 0x80);
                break;
        case INVERSION_ON:
-               cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80);
-               cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80);
+               dprintk("%s:  inversion on\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x80);
+               cx24123_writereg(state, 0x10, auto_reg | 0x80);
                break;
        case INVERSION_AUTO:
-               cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f);
+               dprintk("%s:  inversion auto\n",__FUNCTION__);
+               cx24123_writereg(state, 0x10, auto_reg & ~0x80);
                break;
        default:
                return -EINVAL;
@@ -338,92 +333,191 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers
 
        val = cx24123_readreg(state, 0x1b) >> 7;
 
-       if (val == 0)
+       if (val == 0) {
+               dprintk("%s:  read inversion off\n",__FUNCTION__);
                *inversion = INVERSION_OFF;
-       else
+       } else {
+               dprintk("%s:  read inversion on\n",__FUNCTION__);
                *inversion = INVERSION_ON;
+       }
 
        return 0;
 }
 
 static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
 {
+       u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
+
        if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
                fec = FEC_AUTO;
 
-       /* Hardware has 5/11 and 3/5 but are never unused */
        switch (fec) {
-       case FEC_NONE:
-               return cx24123_writereg(state, 0x0f, 0x01);
        case FEC_1_2:
-               return cx24123_writereg(state, 0x0f, 0x02);
+               dprintk("%s:  set FEC to 1/2\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x01);
+               cx24123_writereg(state, 0x0f, 0x02);
+               break;
        case FEC_2_3:
-               return cx24123_writereg(state, 0x0f, 0x04);
+               dprintk("%s:  set FEC to 2/3\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x02);
+               cx24123_writereg(state, 0x0f, 0x04);
+               break;
        case FEC_3_4:
-               return cx24123_writereg(state, 0x0f, 0x08);
+               dprintk("%s:  set FEC to 3/4\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x03);
+               cx24123_writereg(state, 0x0f, 0x08);
+               break;
+       case FEC_4_5:
+               dprintk("%s:  set FEC to 4/5\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x04);
+               cx24123_writereg(state, 0x0f, 0x10);
+               break;
        case FEC_5_6:
-               return cx24123_writereg(state, 0x0f, 0x20);
+               dprintk("%s:  set FEC to 5/6\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x05);
+               cx24123_writereg(state, 0x0f, 0x20);
+               break;
+       case FEC_6_7:
+               dprintk("%s:  set FEC to 6/7\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x06);
+               cx24123_writereg(state, 0x0f, 0x40);
+               break;
        case FEC_7_8:
-               return cx24123_writereg(state, 0x0f, 0x80);
+               dprintk("%s:  set FEC to 7/8\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0e, nom_reg | 0x07);
+               cx24123_writereg(state, 0x0f, 0x80);
+               break;
        case FEC_AUTO:
-               return cx24123_writereg(state, 0x0f, 0xae);
+               dprintk("%s:  set FEC to auto\n",__FUNCTION__);
+               cx24123_writereg(state, 0x0f, 0xfe);
+               break;
        default:
                return -EOPNOTSUPP;
        }
+
+       return 0;
 }
 
 static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
 {
        int ret;
-       u8 val;
 
        ret = cx24123_readreg (state, 0x1b);
        if (ret < 0)
                return ret;
-       val = ret & 0x07;
-       switch (val) {
+       ret = ret & 0x07;
+
+       switch (ret) {
        case 1:
                *fec = FEC_1_2;
                break;
-       case 3:
+       case 2:
                *fec = FEC_2_3;
                break;
-       case 4:
+       case 3:
                *fec = FEC_3_4;
                break;
-       case 5:
+       case 4:
                *fec = FEC_4_5;
                break;
-       case 6:
+       case 5:
                *fec = FEC_5_6;
                break;
+       case 6:
+               *fec = FEC_6_7;
+               break;
        case 7:
                *fec = FEC_7_8;
                break;
-       case 2: /* *fec = FEC_3_5; break; */
-       case 0: /* *fec = FEC_5_11; break; */
-               *fec = FEC_AUTO;
-               break;
        default:
-               *fec = FEC_NONE; // can't happen
+               /* this can happen when there's no lock */
+               *fec = FEC_NONE;
        }
 
        return 0;
 }
 
-/* fixme: Symbol rates < 3MSps may not work because of precision loss */
+/* Approximation of closest integer of log2(a/b). It actually gives the
+   lowest integer i such that 2^i >= round(a/b) */
+static u32 cx24123_int_log2(u32 a, u32 b)
+{
+       u32 exp, nearest = 0;
+       u32 div = a / b;
+       if(a % b >= b / 2) ++div;
+       if(div < (1 << 31))
+       {
+               for(exp = 1; div > exp; nearest++)
+                       exp += exp;
+       }
+       return nearest;
+}
+
 static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
 {
-       u32 val;
+       u32 tmp, sample_rate, ratio, sample_gain;
+       u8 pll_mult;
+
+       /*  check if symbol rate is within limits */
+       if ((srate > state->ops.info.symbol_rate_max) ||
+           (srate < state->ops.info.symbol_rate_min))
+               return -EOPNOTSUPP;;
+
+       /* choose the sampling rate high enough for the required operation,
+          while optimizing the power consumed by the demodulator */
+       if (srate < (XTAL*2)/2)
+               pll_mult = 2;
+       else if (srate < (XTAL*3)/2)
+               pll_mult = 3;
+       else if (srate < (XTAL*4)/2)
+               pll_mult = 4;
+       else if (srate < (XTAL*5)/2)
+               pll_mult = 5;
+       else if (srate < (XTAL*6)/2)
+               pll_mult = 6;
+       else if (srate < (XTAL*7)/2)
+               pll_mult = 7;
+       else if (srate < (XTAL*8)/2)
+               pll_mult = 8;
+       else
+               pll_mult = 9;
+
+
+       sample_rate = pll_mult * XTAL;
+
+       /*
+           SYSSymbolRate[21:0] = (srate << 23) / sample_rate
+
+           We have to use 32 bit unsigned arithmetic without precision loss.
+           The maximum srate is 45000000 or 0x02AEA540. This number has
+           only 6 clear bits on top, hence we can shift it left only 6 bits
+           at a time. Borrowed from cx24110.c
+       */
+
+       tmp = srate << 6;
+       ratio = tmp / sample_rate;
+
+       tmp = (tmp % sample_rate) << 6;
+       ratio = (ratio << 6) + (tmp / sample_rate);
+
+       tmp = (tmp % sample_rate) << 6;
+       ratio = (ratio << 6) + (tmp / sample_rate);
+
+       tmp = (tmp % sample_rate) << 5;
+       ratio = (ratio << 5) + (tmp / sample_rate);
+
+
+       cx24123_writereg(state, 0x01, pll_mult * 6);
 
-       val = (srate / 1185) * 100;
+       cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f );
+       cx24123_writereg(state, 0x09, (ratio >>  8) & 0xff );
+       cx24123_writereg(state, 0x0a, (ratio      ) & 0xff );
 
-       /* Compensate for scaling up, by removing 17 symbols per 1Msps */
-       val = val - (17 * (srate / 1000000));
+       /* also set the demodulator sample gain */
+       sample_gain = cx24123_int_log2(sample_rate, srate);
+       tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
+       cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
 
-       cx24123_writereg(state, 0x08, (val >> 16) & 0xff );
-       cx24123_writereg(state, 0x09, (val >>  8) & 0xff );
-       cx24123_writereg(state, 0x0a, (val      ) & 0xff );
+       dprintk("%s: srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", __FUNCTION__, srate, ratio, sample_rate, sample_gain);
 
        return 0;
 }
@@ -437,6 +531,9 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
        struct cx24123_state *state = fe->demodulator_priv;
        u32 ndiv = 0, adiv = 0, vco_div = 0;
        int i = 0;
+       int pump = 2;
+       int band = 0;
+       int num_bands = sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]);
 
        /* Defaults for low freq, low rate */
        state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
@@ -444,38 +541,49 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
        state->bandselectarg = cx24123_bandselect_vals[0].progdata;
        vco_div = cx24123_bandselect_vals[0].VCOdivider;
 
-       /* For the given symbolerate, determine the VCA and VGA programming bits */
+       /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */
        for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++)
        {
                if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
-                               (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
+                   (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
                        state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
                        state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
+                       state->FILTune = cx24123_AGC_vals[i].FILTune;
                }
        }
 
-       /* For the given frequency, determine the bandselect programming bits */
-       for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++)
+       /* determine the band to use */
+       if(force_band < 1 || force_band > num_bands)
        {
-               if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
-                               (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) {
-                       state->bandselectarg = cx24123_bandselect_vals[i].progdata;
-                       vco_div = cx24123_bandselect_vals[i].VCOdivider;
+               for (i = 0; i < num_bands; i++)
+               {
+                       if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
+                           (cx24123_bandselect_vals[i].freq_high >= p->frequency) )
+                               band = i;
                }
        }
+       else
+               band = force_band - 1;
+
+       state->bandselectarg = cx24123_bandselect_vals[band].progdata;
+       vco_div = cx24123_bandselect_vals[band].VCOdivider;
+
+       /* determine the charge pump current */
+       if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 )
+               pump = 0x01;
+       else
+               pump = 0x02;
 
        /* Determine the N/A dividers for the requested lband freq (in kHz). */
-       /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */
-       ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff;
-       adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f;
+       /* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */
+       ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
+       adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
 
        if (adiv == 0)
-               adiv++;
+               ndiv++;
 
-       /* determine the correct pll frequency values. */
-       /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */
-       state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14);
-       state->pllarg |= (ndiv << 5) | adiv;
+       /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
+       state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
 
        return 0;
 }
@@ -489,6 +597,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
        struct cx24123_state *state = fe->demodulator_priv;
        unsigned long timeout;
 
+       dprintk("%s:  pll writereg called, data=0x%08x\n",__FUNCTION__,data);
+
        /* align the 21 bytes into to bit23 boundary */
        data = data << 3;
 
@@ -538,6 +648,9 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
 static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 {
        struct cx24123_state *state = fe->demodulator_priv;
+       u8 val;
+
+       dprintk("frequency=%i\n", p->frequency);
 
        if (cx24123_pll_calculate(fe, p) != 0) {
                printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__);
@@ -552,6 +665,14 @@ static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_paramet
        cx24123_pll_writereg(fe, p, state->bandselectarg);
        cx24123_pll_writereg(fe, p, state->pllarg);
 
+       /* set the FILTUNE voltage */
+       val = cx24123_readreg(state, 0x28) & ~0x3;
+       cx24123_writereg(state, 0x27, state->FILTune >> 2);
+       cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
+
+       dprintk("%s:  pll tune VCA=%d, band=%d, pll=%d\n",__FUNCTION__,state->VCAarg,
+                       state->bandselectarg,state->pllarg);
+
        return 0;
 }
 
@@ -560,6 +681,8 @@ static int cx24123_initfe(struct dvb_frontend* fe)
        struct cx24123_state *state = fe->demodulator_priv;
        int i;
 
+       dprintk("%s:  init frontend\n",__FUNCTION__);
+
        /* Configure the demod to a good set of defaults */
        for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
                cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
@@ -587,10 +710,13 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
 
                switch (voltage) {
                case SEC_VOLTAGE_13:
+                       dprintk("%s:  isl6421 voltage = 13V\n",__FUNCTION__);
                        return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */
                case SEC_VOLTAGE_18:
+                       dprintk("%s:  isl6421 voltage = 18V\n",__FUNCTION__);
                        return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */
                case SEC_VOLTAGE_OFF:
+                       dprintk("%s:  isl5421 voltage off\n",__FUNCTION__);
                        return cx24123_writelnbreg(state, 0x0, val & 0x30);
                default:
                        return -EINVAL;
@@ -624,13 +750,93 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
        return 0;
 }
 
-static int cx24123_send_diseqc_msg(struct dvb_frontend* fe,
-                                  struct dvb_diseqc_master_cmd *cmd)
+/* wait for diseqc queue to become ready (or timeout) */
+static void cx24123_wait_for_diseqc(struct cx24123_state *state)
+{
+       unsigned long timeout = jiffies + msecs_to_jiffies(200);
+       while (!(cx24123_readreg(state, 0x29) & 0x40)) {
+               if(time_after(jiffies, timeout)) {
+                       printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__);
+                       break;
+               }
+               msleep(10);
+       }
+}
+
+static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
 {
-       /* fixme: Implement diseqc */
-       printk("%s: No support yet\n",__FUNCTION__);
+       struct cx24123_state *state = fe->demodulator_priv;
+       int i, val;
+
+       dprintk("%s:\n",__FUNCTION__);
+
+       /* check if continuous tone has been stopped */
+       if (state->config->use_isl6421)
+               val = cx24123_readlnbreg(state, 0x00) & 0x10;
+       else
+               val = cx24123_readreg(state, 0x29) & 0x10;
 
-       return -ENOTSUPP;
+
+       if (val) {
+               printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
+               return -ENOTSUPP;
+       }
+
+       /* wait for diseqc queue ready */
+       cx24123_wait_for_diseqc(state);
+
+       /* select tone mode */
+       cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8);
+
+       for (i = 0; i < cmd->msg_len; i++)
+               cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
+
+       val = cx24123_readreg(state, 0x29);
+       cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
+
+       /* wait for diseqc message to finish sending */
+       cx24123_wait_for_diseqc(state);
+
+       return 0;
+}
+
+static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+       struct cx24123_state *state = fe->demodulator_priv;
+       int val;
+
+       dprintk("%s:\n", __FUNCTION__);
+
+       /* check if continuous tone has been stoped */
+       if (state->config->use_isl6421)
+               val = cx24123_readlnbreg(state, 0x00) & 0x10;
+       else
+               val = cx24123_readreg(state, 0x29) & 0x10;
+
+
+       if (val) {
+               printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
+               return -ENOTSUPP;
+       }
+
+       cx24123_wait_for_diseqc(state);
+
+       /* select tone mode */
+       val = cx24123_readreg(state, 0x2a) & 0xf8;
+       cx24123_writereg(state, 0x2a, val | 0x04);
+
+       val = cx24123_readreg(state, 0x29);
+
+       if (burst == SEC_MINI_A)
+               cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
+       else if (burst == SEC_MINI_B)
+               cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
+       else
+               return -EINVAL;
+
+       cx24123_wait_for_diseqc(state);
+
+       return 0;
 }
 
 static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
@@ -642,13 +848,15 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
 
        *status = 0;
        if (lock & 0x01)
-               *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+               *status |= FE_HAS_SIGNAL;
+       if (sync & 0x02)
+               *status |= FE_HAS_CARRIER;
        if (sync & 0x04)
                *status |= FE_HAS_VITERBI;
        if (sync & 0x08)
-               *status |= FE_HAS_CARRIER;
+               *status |= FE_HAS_SYNC;
        if (sync & 0x80)
-               *status |= FE_HAS_SYNC | FE_HAS_LOCK;
+               *status |= FE_HAS_LOCK;
 
        return 0;
 }
@@ -681,6 +889,8 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
        else
                state->snr = 0;
 
+       dprintk("%s:  BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr);
+
        *ber = state->lastber;
 
        return 0;
@@ -691,6 +901,8 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
        struct cx24123_state *state = fe->demodulator_priv;
        *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
 
+       dprintk("%s:  Signal strength = %d\n",__FUNCTION__,*signal_strength);
+
        return 0;
 }
 
@@ -699,6 +911,8 @@ static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
        struct cx24123_state *state = fe->demodulator_priv;
        *snr = state->snr;
 
+       dprintk("%s:  read S/N index = %d\n",__FUNCTION__,*snr);
+
        return 0;
 }
 
@@ -707,6 +921,8 @@ static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
        struct cx24123_state *state = fe->demodulator_priv;
        *ucblocks = state->lastber;
 
+       dprintk("%s:  ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks);
+
        return 0;
 }
 
@@ -714,6 +930,8 @@ static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 {
        struct cx24123_state *state = fe->demodulator_priv;
 
+       dprintk("%s:  set_frontend\n",__FUNCTION__);
+
        if (state->config->set_ts_params)
                state->config->set_ts_params(fe, 0);
 
@@ -737,6 +955,8 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
 {
        struct cx24123_state *state = fe->demodulator_priv;
 
+       dprintk("%s:  get_frontend\n",__FUNCTION__);
+
        if (cx24123_get_inversion(state, &p->inversion) != 0) {
                printk("%s: Failed to get inversion status\n",__FUNCTION__);
                return -EREMOTEIO;
@@ -763,8 +983,10 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 
                switch (tone) {
                case SEC_TONE_ON:
+                       dprintk("%s:  isl6421 sec tone on\n",__FUNCTION__);
                        return cx24123_writelnbreg(state, 0x0, val | 0x10);
                case SEC_TONE_OFF:
+                       dprintk("%s:  isl6421 sec tone off\n",__FUNCTION__);
                        return cx24123_writelnbreg(state, 0x0, val & 0x2f);
                default:
                        printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
@@ -855,12 +1077,13 @@ static struct dvb_frontend_ops cx24123_ops = {
                .frequency_min = 950000,
                .frequency_max = 2150000,
                .frequency_stepsize = 1011, /* kHz for QPSK frontends */
-               .frequency_tolerance = 29500,
+               .frequency_tolerance = 5000,
                .symbol_rate_min = 1000000,
                .symbol_rate_max = 45000000,
                .caps = FE_CAN_INVERSION_AUTO |
                        FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-                       FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+                       FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+                       FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
                        FE_CAN_QPSK | FE_CAN_RECOVER
        },
 
@@ -875,12 +1098,16 @@ static struct dvb_frontend_ops cx24123_ops = {
        .read_snr = cx24123_read_snr,
        .read_ucblocks = cx24123_read_ucblocks,
        .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
+       .diseqc_send_burst = cx24123_diseqc_send_burst,
        .set_tone = cx24123_set_tone,
        .set_voltage = cx24123_set_voltage,
 };
 
 module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
+module_param(force_band, int, 0644);
+MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off).");
 
 MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware");
 MODULE_AUTHOR("Steven Toth");
index b6e2c387a04cc06f05405871b088bfa78cce1ae6..791706ec1da39a5b4ca528a08162ee19f9f70a00 100644 (file)
@@ -235,8 +235,8 @@ struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
        .max   = 863000000,
        .count = 3,
        .entries = {
-               {  160000000, 44000000, 62500, 0xce, 0x01 },
-               {  455000000, 44000000, 62500, 0xce, 0x02 },
+               {  165000000, 44000000, 62500, 0xce, 0x01 },
+               {  450000000, 44000000, 62500, 0xce, 0x02 },
                {  999999999, 44000000, 62500, 0xce, 0x04 },
        },
 };
index 84f8f9f52869a778f797d7dc2bfffb73f61b52b1..7d8e6e87bdbb23e63b8ec06c55a6c2972457dcba 100644 (file)
@@ -1,7 +1,6 @@
 config DVB_PLUTO2
        tristate "Pluto2 cards"
-       depends on DVB_CORE && PCI
-       select I2C
+       depends on DVB_CORE && PCI && I2C
        select I2C_ALGOBIT
        select DVB_TDA1004X
        help
index 86ca84b2be6e1a9a88fb39d218142439db96cc73..ce6a9aaf937e9e0a7c8713f015c1ccd0dcf91325 100644 (file)
@@ -1,3 +1,3 @@
-obj-$(CONFIG_DVB_PLUTO2) = pluto2.o
+obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
 
 EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
index 5b2aadb8385c2b92ee1d3b57145975fc185d848d..b5ac7dfde52f745aef95da9cc167d9b5562fee22 100644 (file)
@@ -1,8 +1,7 @@
 config DVB_AV7110
        tristate "AV7110 cards"
-       depends on DVB_CORE && PCI
+       depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
        select FW_LOADER
-       select VIDEO_DEV
        select VIDEO_SAA7146_VV
        select DVB_VES1820
        select DVB_VES1X93
@@ -59,7 +58,7 @@ config DVB_AV7110_OSD
 
 config DVB_BUDGET
        tristate "Budget cards"
-       depends on DVB_CORE && PCI
+       depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
        select VIDEO_SAA7146
        select DVB_STV0299
        select DVB_VES1X93
@@ -80,7 +79,7 @@ config DVB_BUDGET
 
 config DVB_BUDGET_CI
        tristate "Budget cards with onboard CI connector"
-       depends on DVB_CORE && PCI
+       depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
        select VIDEO_SAA7146
        select DVB_STV0297
        select DVB_STV0299
@@ -100,8 +99,7 @@ config DVB_BUDGET_CI
 
 config DVB_BUDGET_AV
        tristate "Budget cards with analog video inputs"
-       depends on DVB_CORE && PCI
-       select VIDEO_DEV
+       depends on DVB_CORE && PCI && I2C && VIDEO_V4L1
        select VIDEO_SAA7146_VV
        select DVB_STV0299
        select DVB_TDA1004X
@@ -119,7 +117,7 @@ config DVB_BUDGET_AV
 
 config DVB_BUDGET_PATCH
        tristate "AV7110 cards with Budget Patch"
-       depends on DVB_CORE && DVB_BUDGET
+       depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1
        select DVB_AV7110
        select DVB_STV0299
        select DVB_VES1X93
index 8efe3ce5f66c83edb9528ebc9421981d294234c3..8a7cd7d505cf533997dc76f2613f5e98a1d0c0d8 100644 (file)
@@ -1190,8 +1190,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
                                                SAA7146_HPS_SYNC_PORT_A);
 
                saa7113_setinput(budget_av, 0);
-       } else {
-               ciintf_init(budget_av);
        }
 
        /* fixme: find some sane values here... */
@@ -1211,6 +1209,10 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
        budget_av->budget.dvb_adapter.priv = budget_av;
        frontend_init(budget_av);
 
+       if (!budget_av->has_saa7113) {
+               ciintf_init(budget_av);
+       }
+
        return 0;
 }
 
index 5f91036f5b874af9a7bf4a80a841897d5a5a7ed3..e64a609cf4ff4825ac119047b3dd7cfddc7d7cdb 100644 (file)
@@ -71,6 +71,7 @@ struct budget_ci {
        struct tasklet_struct msp430_irq_tasklet;
        struct tasklet_struct ciintf_irq_tasklet;
        int slot_status;
+       int ci_irq;
        struct dvb_ca_en50221 ca;
        char ir_dev_name[50];
        u8 tuner_pll_address; /* used for philips_tdm1316l configs */
@@ -276,8 +277,10 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
        if (slot != 0)
                return -EINVAL;
 
-       // trigger on RISING edge during reset so we know when READY is re-asserted
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+       if (budget_ci->ci_irq) {
+               // trigger on RISING edge during reset so we know when READY is re-asserted
+               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+       }
        budget_ci->slot_status = SLOTSTATUS_RESET;
        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
        msleep(1);
@@ -370,11 +373,50 @@ static void ciintf_interrupt(unsigned long data)
        }
 }
 
+static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+       struct budget_ci *budget_ci = (struct budget_ci *) ca->data;
+       unsigned int flags;
+
+       // ensure we don't get spurious IRQs during initialisation
+       if (!budget_ci->budget.ci_present)
+               return -EINVAL;
+
+       // read the CAM status
+       flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
+       if (flags & CICONTROL_CAMDETECT) {
+               // mark it as present if it wasn't before
+               if (budget_ci->slot_status & SLOTSTATUS_NONE) {
+                       budget_ci->slot_status = SLOTSTATUS_PRESENT;
+               }
+
+               // during a RESET, we check if we can read from IO memory to see when CAM is ready
+               if (budget_ci->slot_status & SLOTSTATUS_RESET) {
+                       if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) {
+                               budget_ci->slot_status = SLOTSTATUS_READY;
+                       }
+               }
+       } else {
+               budget_ci->slot_status = SLOTSTATUS_NONE;
+       }
+
+       if (budget_ci->slot_status != SLOTSTATUS_NONE) {
+               if (budget_ci->slot_status & SLOTSTATUS_READY) {
+                       return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
+               }
+               return DVB_CA_EN50221_POLL_CAM_PRESENT;
+       }
+
+       return 0;
+}
+
 static int ciintf_init(struct budget_ci *budget_ci)
 {
        struct saa7146_dev *saa = budget_ci->budget.dev;
        int flags;
        int result;
+       int ci_version;
+       int ca_flags;
 
        memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
 
@@ -382,16 +424,29 @@ static int ciintf_init(struct budget_ci *budget_ci)
        saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
 
        // test if it is there
-       if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
+       ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0);
+       if ((ci_version & 0xa0) != 0xa0) {
                result = -ENODEV;
                goto error;
        }
+
        // determine whether a CAM is present or not
        flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
        budget_ci->slot_status = SLOTSTATUS_NONE;
        if (flags & CICONTROL_CAMDETECT)
                budget_ci->slot_status = SLOTSTATUS_PRESENT;
 
+       // version 0xa2 of the CI firmware doesn't generate interrupts
+       if (ci_version == 0xa2) {
+               ca_flags = 0;
+               budget_ci->ci_irq = 0;
+       } else {
+               ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
+                               DVB_CA_EN50221_FLAG_IRQ_FR |
+                               DVB_CA_EN50221_FLAG_IRQ_DA;
+               budget_ci->ci_irq = 1;
+       }
+
        // register CI interface
        budget_ci->ca.owner = THIS_MODULE;
        budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
@@ -401,23 +456,27 @@ static int ciintf_init(struct budget_ci *budget_ci)
        budget_ci->ca.slot_reset = ciintf_slot_reset;
        budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
        budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
+       budget_ci->ca.poll_slot_status = ciintf_poll_slot_status;
        budget_ci->ca.data = budget_ci;
        if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter,
                                          &budget_ci->ca,
-                                         DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
-                                         DVB_CA_EN50221_FLAG_IRQ_FR |
-                                         DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
+                                         ca_flags, 1)) != 0) {
                printk("budget_ci: CI interface detected, but initialisation failed.\n");
                goto error;
        }
+
        // Setup CI slot IRQ
-       tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
-       if (budget_ci->slot_status != SLOTSTATUS_NONE) {
-               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
-       } else {
-               saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+       if (budget_ci->ci_irq) {
+               tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
+               if (budget_ci->slot_status != SLOTSTATUS_NONE) {
+                       saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
+               } else {
+                       saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
+               }
+               saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
        }
-       saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
+
+       // enable interface
        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
                               CICONTROL_RESET, 1, 0);
 
@@ -426,10 +485,12 @@ static int ciintf_init(struct budget_ci *budget_ci)
        budget_ci->budget.ci_present = 1;
 
        // forge a fake CI IRQ so the CAM state is setup correctly
-       flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
-       if (budget_ci->slot_status != SLOTSTATUS_NONE)
-               flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
-       dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
+       if (budget_ci->ci_irq) {
+               flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
+               if (budget_ci->slot_status != SLOTSTATUS_NONE)
+                       flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
+               dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
+       }
 
        return 0;
 
@@ -443,9 +504,13 @@ static void ciintf_deinit(struct budget_ci *budget_ci)
        struct saa7146_dev *saa = budget_ci->budget.dev;
 
        // disable CI interrupts
-       saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
-       saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
-       tasklet_kill(&budget_ci->ciintf_irq_tasklet);
+       if (budget_ci->ci_irq) {
+               saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
+               saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
+               tasklet_kill(&budget_ci->ciintf_irq_tasklet);
+       }
+
+       // reset interface
        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
        msleep(1);
        ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
@@ -473,7 +538,7 @@ static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr)
        if (*isr & MASK_10)
                ttpci_budget_irq10_handler(dev, isr);
 
-       if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
+       if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq))
                tasklet_schedule(&budget_ci->ciintf_irq_tasklet);
 }
 
index 248fdc7accfb123d52c37460cc057faec7e2ca52..6ceae38125c7546990623d62028e35c56750f4a1 100644 (file)
@@ -1507,7 +1507,11 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
 
        mutex_unlock(&ttusb->semi2c);
 
-       dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
+       if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) {
+               ttusb_free_iso_urbs(ttusb);
+               kfree(ttusb);
+               return result;
+       }
        ttusb->adapter.priv = ttusb;
 
        /* i2c */
index d318be383de6a08d8301f2f4537a4d598f320597..3fff7576369323b5ff9bc3772408f595e32f0e58 100644 (file)
@@ -7,7 +7,7 @@ menu "Radio Adapters"
 
 config RADIO_CADET
        tristate "ADS Cadet AM/FM Tuner"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have one of these AM/FM radio cards, and then
          fill in the port address below.
@@ -25,7 +25,7 @@ config RADIO_CADET
 
 config RADIO_RTRACK
        tristate "AIMSlab RadioTrack (aka RadioReveal) support"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have one of these FM radio cards, and then fill
          in the port address below.
@@ -59,7 +59,7 @@ config RADIO_RTRACK_PORT
 
 config RADIO_RTRACK2
        tristate "AIMSlab RadioTrack II support"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have this FM radio card, and then fill in the
          port address below.
@@ -82,7 +82,7 @@ config RADIO_RTRACK2_PORT
 
 config RADIO_AZTECH
        tristate "Aztech/Packard Bell Radio"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have one of these FM radio cards, and then fill
          in the port address below.
@@ -106,7 +106,7 @@ config RADIO_AZTECH_PORT
 
 config RADIO_GEMTEK
        tristate "GemTek Radio Card support"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have this FM radio card, and then fill in the
          port address below.
@@ -131,7 +131,7 @@ config RADIO_GEMTEK_PORT
 
 config RADIO_GEMTEK_PCI
        tristate "GemTek PCI Radio Card support"
-       depends on VIDEO_DEV && PCI
+       depends on VIDEO_V4L1 && PCI
        ---help---
          Choose Y here if you have this PCI FM radio card.
 
@@ -145,7 +145,7 @@ config RADIO_GEMTEK_PCI
 
 config RADIO_MAXIRADIO
        tristate "Guillemot MAXI Radio FM 2000 radio"
-       depends on VIDEO_DEV && PCI
+       depends on VIDEO_V4L1 && PCI
        ---help---
          Choose Y here if you have this radio card.  This card may also be
          found as Gemtek PCI FM.
@@ -160,7 +160,7 @@ config RADIO_MAXIRADIO
 
 config RADIO_MAESTRO
        tristate "Maestro on board radio"
-       depends on VIDEO_DEV
+       depends on VIDEO_V4L1
        ---help---
          Say Y here to directly support the on-board radio tuner on the
          Maestro 2 or 2E sound card.
@@ -175,7 +175,7 @@ config RADIO_MAESTRO
 
 config RADIO_MIROPCM20
        tristate "miroSOUND PCM20 radio"
-       depends on ISA && VIDEO_DEV && SOUND_ACI_MIXER
+       depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER
        ---help---
          Choose Y here if you have this FM radio card. You also need to say Y
          to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound")
@@ -208,7 +208,7 @@ config RADIO_MIROPCM20_RDS
 
 config RADIO_SF16FMI
        tristate "SF16FMI Radio"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have one of these FM radio cards.  If you
          compile the driver into the kernel and your card is not PnP one, you
@@ -225,7 +225,7 @@ config RADIO_SF16FMI
 
 config RADIO_SF16FMR2
        tristate "SF16FMR2 Radio"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have one of these FM radio cards.
 
@@ -239,7 +239,7 @@ config RADIO_SF16FMR2
 
 config RADIO_TERRATEC
        tristate "TerraTec ActiveRadio ISA Standalone"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have this FM radio card, and then fill in the
          port address below. (TODO)
@@ -268,7 +268,7 @@ config RADIO_TERRATEC_PORT
 
 config RADIO_TRUST
        tristate "Trust FM radio card"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        help
          This is a driver for the Trust FM radio cards. Say Y if you have
          such a card and want to use it under Linux.
@@ -286,7 +286,7 @@ config RADIO_TRUST_PORT
 
 config RADIO_TYPHOON
        tristate "Typhoon Radio (a.k.a. EcoRadio)"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have one of these FM radio cards, and then fill
          in the port address and the frequency used for muting below.
@@ -330,7 +330,7 @@ config RADIO_TYPHOON_MUTEFREQ
 
 config RADIO_ZOLTRIX
        tristate "Zoltrix Radio"
-       depends on ISA && VIDEO_DEV
+       depends on ISA && VIDEO_V4L1
        ---help---
          Choose Y here if you have one of these FM radio cards, and then fill
          in the port address below.
index 85888a8a93c9b1eb7250de3b3120689b1ded71a5..6b41970185610780327355a0f4d4af6f5a852e8e 100644 (file)
@@ -2,10 +2,10 @@
 # Multimedia Video device configuration
 #
 
-menu "Video For Linux"
+menu "Video Capture Adapters"
        depends on VIDEO_DEV
 
-comment "Video Adapters"
+comment "Video Capture Adapters"
 
 config VIDEO_ADV_DEBUG
        bool "Enable advanced debug functionality"
@@ -16,11 +16,23 @@ config VIDEO_ADV_DEBUG
          V4L devices.
          In doubt, say N.
 
+config VIDEO_VIVI
+       tristate "Virtual Video Driver"
+       depends on VIDEO_V4L2 && !SPARC32 && !SPARC64
+       select VIDEO_BUF
+       default n
+       ---help---
+         Enables a virtual video driver. This device shows a color bar
+         and a timestamp, as a real device would generate by using V4L2
+         api.
+         Say Y here if you want to test video apps or debug V4L devices.
+         In doubt, say N.
+
 source "drivers/media/video/bt8xx/Kconfig"
 
 config VIDEO_SAA6588
        tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
-       depends on VIDEO_DEV && I2C && VIDEO_BT848
+       depends on I2C && VIDEO_BT848
 
        help
          Support for  Radio Data System (RDS) decoder. This allows seeing
@@ -32,7 +44,7 @@ config VIDEO_SAA6588
 
 config VIDEO_PMS
        tristate "Mediavision Pro Movie Studio Video For Linux"
-       depends on VIDEO_DEV && ISA
+       depends on ISA && VIDEO_V4L1
        help
          Say Y if you have such a thing.
 
@@ -41,7 +53,7 @@ config VIDEO_PMS
 
 config VIDEO_PLANB
        tristate "PlanB Video-In on PowerMac"
-       depends on PPC_PMAC && VIDEO_DEV && BROKEN
+       depends on PPC_PMAC && VIDEO_V4L1 && BROKEN
        help
          PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
          input hardware. If you want to experiment with this, say Y.
@@ -52,7 +64,7 @@ config VIDEO_PLANB
 
 config VIDEO_BWQCAM
        tristate "Quickcam BW Video For Linux"
-       depends on VIDEO_DEV && PARPORT
+       depends on PARPORT && VIDEO_V4L1
        help
          Say Y have if you the black and white version of the QuickCam
          camera. See the next option for the color version.
@@ -62,7 +74,7 @@ config VIDEO_BWQCAM
 
 config VIDEO_CQCAM
        tristate "QuickCam Colour Video For Linux (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && VIDEO_DEV && PARPORT
+       depends on EXPERIMENTAL && PARPORT && VIDEO_V4L1
        help
          This is the video4linux driver for the colour version of the
          Connectix QuickCam.  If you have one of these cameras, say Y here,
@@ -73,7 +85,7 @@ config VIDEO_CQCAM
 
 config VIDEO_W9966
        tristate "W9966CF Webcam (FlyCam Supra and others) Video For Linux"
-       depends on PARPORT_1284 && VIDEO_DEV && PARPORT
+       depends on PARPORT_1284 && PARPORT && VIDEO_V4L1
        help
          Video4linux driver for Winbond's w9966 based Webcams.
          Currently tested with the LifeView FlyCam Supra.
@@ -86,7 +98,7 @@ config VIDEO_W9966
 
 config VIDEO_CPIA
        tristate "CPiA Video For Linux"
-       depends on VIDEO_DEV
+       depends on VIDEO_V4L1
        ---help---
          This is the video4linux driver for cameras based on Vision's CPiA
          (Colour Processor Interface ASIC), such as the Creative Labs Video
@@ -123,7 +135,7 @@ source "drivers/media/video/cpia2/Kconfig"
 
 config VIDEO_SAA5246A
        tristate "SAA5246A, SAA5281 Teletext processor"
-       depends on VIDEO_DEV && I2C
+       depends on I2C && VIDEO_V4L1
        help
          Support for I2C bus based teletext using the SAA5246A or SAA5281
          chip. Useful only if you live in Europe.
@@ -150,7 +162,7 @@ config TUNER_3036
 
 config VIDEO_VINO
        tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
-       depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL
+       depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L1
        select I2C_ALGO_SGI
        help
          Say Y here to build in support for the Vino video input system found
@@ -158,7 +170,7 @@ config VIDEO_VINO
 
 config VIDEO_STRADIS
        tristate "Stradis 4:2:2 MPEG-2 video driver  (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && VIDEO_DEV && PCI
+       depends on EXPERIMENTAL && PCI && VIDEO_V4L1 && !PPC64
        help
          Say Y here to enable support for the Stradis 4:2:2 MPEG-2 video
          driver for PCI.  There is a product page at
@@ -166,7 +178,7 @@ config VIDEO_STRADIS
 
 config VIDEO_ZORAN
        tristate "Zoran ZR36057/36067 Video For Linux"
-       depends on VIDEO_DEV && PCI && I2C_ALGOBIT
+       depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && !PPC64
        help
          Say Y for support for MJPEG capture cards based on the Zoran
          36057/36067 PCI controller chipset. This includes the Iomega
@@ -214,7 +226,7 @@ config VIDEO_ZORAN_LML33R10
 
 config VIDEO_ZR36120
        tristate "Zoran ZR36120/36125 Video For Linux"
-       depends on VIDEO_DEV && PCI && I2C && BROKEN
+       depends on PCI && I2C && VIDEO_V4L1 && BROKEN
        help
          Support for ZR36120/ZR36125 based frame grabber/overlay boards.
          This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV,
@@ -226,7 +238,7 @@ config VIDEO_ZR36120
 
 config VIDEO_MEYE
        tristate "Sony Vaio Picturebook Motion Eye Video For Linux"
-       depends on VIDEO_DEV && PCI && SONYPI
+       depends on PCI && SONYPI && VIDEO_V4L1
        ---help---
          This is the video4linux driver for the Motion Eye camera found
          in the Vaio Picturebook laptops. Please read the material in
@@ -242,7 +254,7 @@ source "drivers/media/video/saa7134/Kconfig"
 
 config VIDEO_MXB
        tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
-       depends on VIDEO_DEV && PCI
+       depends on PCI && VIDEO_V4L1
        select VIDEO_SAA7146_VV
        select VIDEO_TUNER
        ---help---
@@ -254,8 +266,9 @@ config VIDEO_MXB
 
 config VIDEO_DPC
        tristate "Philips-Semiconductors 'dpc7146 demonstration board'"
-       depends on VIDEO_DEV && PCI
+       depends on PCI && VIDEO_V4L1
        select VIDEO_SAA7146_VV
+       select VIDEO_V4L2
        ---help---
          This is a video4linux driver for the 'dpc7146 demonstration
          board' by Philips-Semiconductors. It's the reference design
@@ -268,8 +281,9 @@ config VIDEO_DPC
 
 config VIDEO_HEXIUM_ORION
        tristate "Hexium HV-PCI6 and Orion frame grabber"
-       depends on VIDEO_DEV && PCI
+       depends on PCI && VIDEO_V4L1
        select VIDEO_SAA7146_VV
+       select VIDEO_V4L2
        ---help---
          This is a video4linux driver for the Hexium HV-PCI6 and
          Orion frame grabber cards by Hexium.
@@ -279,8 +293,9 @@ config VIDEO_HEXIUM_ORION
 
 config VIDEO_HEXIUM_GEMINI
        tristate "Hexium Gemini frame grabber"
-       depends on VIDEO_DEV && PCI
+       depends on PCI && VIDEO_V4L1
        select VIDEO_SAA7146_VV
+       select VIDEO_V4L2
        ---help---
          This is a video4linux driver for the Hexium Gemini frame
          grabber card by Hexium. Please note that the Gemini Dual
@@ -293,7 +308,7 @@ source "drivers/media/video/cx88/Kconfig"
 
 config VIDEO_OVCAMCHIP
        tristate "OmniVision Camera Chip support"
-       depends on VIDEO_DEV && I2C
+       depends on I2C && VIDEO_V4L1
        ---help---
          Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
          This driver is intended to be used with the ov511 and w9968cf USB
@@ -304,7 +319,7 @@ config VIDEO_OVCAMCHIP
 
 config VIDEO_M32R_AR
        tristate "AR devices"
-       depends on M32R
+       depends on M32R && VIDEO_V4L1
        ---help---
          This is a video4linux driver for the Renesas AR (Artificial Retina)
          camera module.
@@ -365,17 +380,17 @@ config VIDEO_WM8739
 source "drivers/media/video/cx25840/Kconfig"
 
 config VIDEO_SAA711X
-       tristate "Philips SAA7113/4/5 video decoders"
-       depends on VIDEO_DEV && I2C && EXPERIMENTAL
+       tristate "Philips SAA7113/4/5 video decoders (OBSOLETED)"
+       depends on VIDEO_V4L1 && I2C && EXPERIMENTAL
        ---help---
-         Support for the Philips SAA7113/4/5 video decoders.
+         Old support for the Philips SAA7113/4 video decoders.
 
          To compile this driver as a module, choose M here: the
          module will be called saa7115.
 
 config VIDEO_SAA7127
        tristate "Philips SAA7127/9 digital video encoders"
-       depends on VIDEO_DEV && I2C && EXPERIMENTAL
+       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
        ---help---
          Support for the Philips SAA7127/9 digital video encoders.
 
@@ -384,7 +399,7 @@ config VIDEO_SAA7127
 
 config VIDEO_UPD64031A
        tristate "NEC Electronics uPD64031A Ghost Reduction"
-       depends on VIDEO_DEV && I2C && EXPERIMENTAL
+       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
        ---help---
          Support for the NEC Electronics uPD64031A Ghost Reduction
          video chip. It is most often found in NTSC TV cards made for
@@ -396,7 +411,7 @@ config VIDEO_UPD64031A
 
 config VIDEO_UPD64083
        tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
-       depends on VIDEO_DEV && I2C && EXPERIMENTAL
+       depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
        ---help---
          Support for the NEC Electronics uPD64083 3-Dimensional Y/C
          separation video chip. It is used to improve the quality of
@@ -418,7 +433,7 @@ source "drivers/media/video/em28xx/Kconfig"
 
 config USB_DSBR
        tristate "D-Link USB FM radio support (EXPERIMENTAL)"
-       depends on USB && VIDEO_DEV && EXPERIMENTAL
+       depends on USB && VIDEO_V4L1 && EXPERIMENTAL
        ---help---
          Say Y here if you want to connect this type of radio to your
          computer's USB port. Note that the audio is not digital, and
@@ -434,7 +449,7 @@ source "drivers/media/video/et61x251/Kconfig"
 
 config USB_OV511
        tristate "USB OV511 Camera support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. See <file:Documentation/video4linux/ov511.txt>
@@ -445,7 +460,7 @@ config USB_OV511
 
 config USB_SE401
        tristate "USB SE401 Camera support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. See <file:Documentation/video4linux/se401.txt>
@@ -458,7 +473,7 @@ source "drivers/media/video/sn9c102/Kconfig"
 
 config USB_STV680
        tristate "USB STV680 (Pencam) Camera support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port. This includes the Pencam line of cameras.
@@ -470,7 +485,7 @@ config USB_STV680
 
 config USB_W9968CF
        tristate "USB W996[87]CF JPEG Dual Mode Camera support"
-       depends on USB && VIDEO_DEV && I2C
+       depends on USB && VIDEO_V4L1 && I2C
        select VIDEO_OVCAMCHIP
        ---help---
          Say Y here if you want support for cameras based on OV681 or
index b3ea2d63db9b04a5e7161a85f469711b4817cd16..e5bf2687b76de83f15508429f327ca0f3d4046df 100644 (file)
@@ -10,7 +10,11 @@ tuner-objs   :=      tuner-core.o tuner-types.o tuner-simple.o \
 
 msp3400-objs   :=      msp3400-driver.o msp3400-kthreads.o
 
-obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o
+obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o compat_ioctl32.o
+
+ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
+  obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
+endif
 
 obj-$(CONFIG_VIDEO_BT848) += bt8xx/
 obj-$(CONFIG_VIDEO_BT848) += tvaudio.o tda7432.o tda9875.o ir-kbd-i2c.o
@@ -84,4 +88,8 @@ obj-$(CONFIG_USB_IBMCAM)        += usbvideo/
 obj-$(CONFIG_USB_KONICAWC)      += usbvideo/
 obj-$(CONFIG_USB_VICAM)         += usbvideo/
 
+obj-$(CONFIG_VIDEO_VIVI) += vivi.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
+extra-cflags-$(CONFIG_VIDEO_V4L1_COMPAT) += -DCONFIG_VIDEO_V4L1_COMPAT
+
index 085477c12612afe39f05cbda7f88e604096397f5..153f6a4a96c990c3a55de92e131774c5d51c8356 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_BT848
        tristate "BT848 Video For Linux"
-       depends on VIDEO_DEV && PCI && I2C
+       depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2
        select I2C_ALGOBIT
        select FW_LOADER
        select VIDEO_BTCX
index db641a36b197afc10495f573bb9a9e20b17ad8c9..a096a03418aaf430dd7b83c1b130642cae4656f1 100644 (file)
@@ -8,5 +8,5 @@ bttv-objs      :=      bttv-driver.o bttv-cards.o bttv-if.o \
 
 obj-$(CONFIG_VIDEO_BT848) += bttv.o
 
-EXTRA_CFLAGS += -I$(src)/..
+EXTRA_CFLAGS += -Idrivers/media/video
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
index f209a749205104af0fb8276373d71c7b150bad32..2b64aa835b423663a203685b6c95a9fc94348fef 100644 (file)
@@ -2991,13 +2991,13 @@ void __devinit bttv_idcard(struct bttv *btv)
 
        if (UNSET != audiomux[0]) {
                gpiobits = 0;
-               for (i = 0; i < 5; i++) {
+               for (i = 0; i < 4; i++) {
                        bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
                        gpiobits |= audiomux[i];
                }
        } else {
                gpiobits = audioall;
-               for (i = 0; i < 5; i++) {
+               for (i = 0; i < 4; i++) {
                        bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
                }
        }
index 16323a5d68acc431095b14655d6a2c9aaf73dcea..afcfe71e37928ca7558a6dad33ef27dea609a0b4 100644 (file)
@@ -233,7 +233,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
                  const struct bttv_format *fmt, struct bttv_overlay *ov,
                  int skip_even, int skip_odd)
 {
-       int instructions,rc,line,maxy,start,end,skip,nskips;
+       int dwords,rc,line,maxy,start,end,skip,nskips;
        struct btcx_skiplist *skips;
        u32 *rp,ri,ra;
        u32 addr;
@@ -242,12 +242,12 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
        if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
                return -ENOMEM;
 
-       /* estimate risc mem: worst case is (clip+1) * lines instructions
+       /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
           + sync + jump (all 2 dwords) */
-       instructions  = (ov->nclips + 1) *
-               ((skip_even || skip_odd) ? ov->w.height>>1 :  ov->w.height);
-       instructions += 2;
-       if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) {
+       dwords  = (3 * ov->nclips + 2) *
+               ((skip_even || skip_odd) ? (ov->w.height+1)>>1 :  ov->w.height);
+       dwords += 4;
+       if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
                kfree(skips);
                return rc;
        }
@@ -276,8 +276,6 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
                if (line > maxy)
                        btcx_calc_skips(line, ov->w.width, &maxy,
                                        skips, &nskips, ov->clips, ov->nclips);
-               else
-                       nskips = 0;
 
                /* write out risc code */
                for (start = 0, skip = 0; start < ov->w.width; start = end) {
index f59ced181c553a074da086ee4c630903c1d9879a..1958d4016ea15c4bb5b9e7faa59377fe80d9a4f6 100644 (file)
 
 #define FWDEV(x) &((x)->adapter->dev)
 
-static int fastfw = 1;
 static char *firmware = FWFILE;
 
-module_param(fastfw, bool, 0444);
 module_param(firmware, charp, 0444);
 
-MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]");
 MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
 
-static void set_i2c_delay(struct i2c_client *client, int delay)
-{
-       struct i2c_algo_bit_data *algod = client->adapter->algo_data;
-
-       /* We aren't guaranteed to be using algo_bit,
-        * so avoid the null pointer dereference
-        * and disable the 'fast firmware load' */
-       if (algod) {
-               algod->udelay = delay;
-       } else {
-               fastfw = 0;
-       }
-}
-
 static void start_fw_load(struct i2c_client *client)
 {
        /* DL_ADDR_LB=0 DL_ADDR_HB=0 */
@@ -71,16 +54,10 @@ static void start_fw_load(struct i2c_client *client)
        cx25840_write(client, 0x803, 0x0b);
        /* AUTO_INC_DIS=1 */
        cx25840_write(client, 0x000, 0x20);
-
-       if (fastfw)
-               set_i2c_delay(client, 3);
 }
 
 static void end_fw_load(struct i2c_client *client)
 {
-       if (fastfw)
-               set_i2c_delay(client, 10);
-
        /* AUTO_INC_DIS=0 */
        cx25840_write(client, 0x000, 0x00);
        /* DL_ENABLE=0 */
@@ -107,30 +84,8 @@ static int fw_write(struct i2c_client *client, u8 * data, int size)
        int sent;
 
        if ((sent = i2c_master_send(client, data, size)) < size) {
-
-               if (fastfw) {
-                       v4l_err(client, "333MHz i2c firmware load failed\n");
-                       fastfw = 0;
-                       set_i2c_delay(client, 10);
-
-                       if (sent > 2) {
-                               u16 dl_addr = cx25840_read(client, 0x801) << 8;
-                               dl_addr |= cx25840_read(client, 0x800);
-                               dl_addr -= sent - 2;
-                               cx25840_write(client, 0x801, dl_addr >> 8);
-                               cx25840_write(client, 0x800, dl_addr & 0xff);
-                       }
-
-                       if (i2c_master_send(client, data, size) < size) {
-                               v4l_err(client, "100MHz i2c firmware load failed\n");
-                               return -ENOSYS;
-                       }
-
-               } else {
-                       v4l_err(client, "firmware load i2c failure\n");
-                       return -ENOSYS;
-               }
-
+               v4l_err(client, "firmware load i2c failure\n");
+               return -ENOSYS;
        }
 
        return 0;
index c7042cf412318293c6f8f8b3e0064a53a9416839..f80154b87d22977d337e4d0159472ca8b074f899 100644 (file)
@@ -564,7 +564,7 @@ struct cx88_board cx88_boards[] = {
        },
        [CX88_BOARD_PCHDTV_HD3000] = {
                .name           = "pcHDTV HD3000 HDTV",
-               .tuner_type     = TUNER_THOMSON_DTT7610,
+               .tuner_type     = TUNER_THOMSON_DTT761X,
                .radio_type     = UNSET,
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
index 2c3d9f1999be6e5884e912bad2476f8b99fec16a..e1092d5d4628de6d078971be4ca62ce1a92c4592 100644 (file)
@@ -146,9 +146,11 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
                fields++;
 
        /* estimate risc mem: worst case is one write per page border +
-          one write per scan line + syncs + jump (all 2 dwords) */
-       instructions  = (bpl * lines * fields) / PAGE_SIZE + lines * fields;
-       instructions += 3 + 4;
+          one write per scan line + syncs + jump (all 2 dwords).  Padding
+          can cause next bpl to start close to a page border.  First DMA
+          region may be smaller than PAGE_SIZE */
+       instructions  = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
+       instructions += 2;
        if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
                return rc;
 
@@ -176,9 +178,11 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc,
        int rc;
 
        /* estimate risc mem: worst case is one write per page border +
-          one write per scan line + syncs + jump (all 2 dwords) */
-       instructions  = (bpl * lines) / PAGE_SIZE + lines;
-       instructions += 3 + 4;
+          one write per scan line + syncs + jump (all 2 dwords).  Here
+          there is no padding and no sync.  First DMA region may be smaller
+          than PAGE_SIZE */
+       instructions  = 1 + (bpl * lines) / PAGE_SIZE + lines;
+       instructions += 1;
        if ((rc = btcx_riscmem_alloc(pci,risc,instructions*8)) < 0)
                return rc;
 
index f0ea9b5cdbc234c50bcd8bb9f93aaa7c3b42f904..3619a449aefd91899e9ed26453006b7f8c124b4d 100644 (file)
@@ -372,7 +372,7 @@ static int or51132_set_ts_param(struct dvb_frontend* fe,
 static struct or51132_config pchdtv_hd3000 = {
        .demod_address    = 0x15,
        .pll_address      = 0x61,
-       .pll_desc         = &dvb_pll_thomson_dtt7610,
+       .pll_desc         = &dvb_pll_thomson_dtt761x,
        .set_ts_params    = or51132_set_ts_param,
 };
 #endif
index 72a417b3174521e2f67aac7944274351052307e8..694d1d80ff3f2e16d1c6c78c6a9164b25faf72c5 100644 (file)
 #include "cx88.h"
 #include <media/v4l2-common.h>
 
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
 /* Include V4L1 specific functions. Should be removed soon */
 #include <linux/videodev.h>
+#endif
 
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
index 5a793ae7cc23d40c8bab720f45d57478e0a15f07..dfb15bfb83dcad2f03b47a521a10d26174ccdd22 100644 (file)
@@ -1,6 +1,6 @@
 config VIDEO_EM28XX
        tristate "Empia EM2800/2820/2840 USB video capture support"
-       depends on VIDEO_DEV && USB && I2C
+       depends on VIDEO_V4L1 && USB && I2C
        select VIDEO_BUF
        select VIDEO_TUNER
        select VIDEO_TVEEPROM
index ddc92cbb5276b776c4ff21097c2c14111996568b..cf7cdf9ef6178e50f3cf1596bf65b856a5fa5df6 100644 (file)
@@ -1576,8 +1576,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        errCode = em28xx_config(dev);
        if (errCode) {
                em28xx_errdev("error configuring device\n");
-               kfree(dev);
                em28xx_devused&=~(1<<dev->devno);
+               kfree(dev);
                return -ENOMEM;
        }
 
@@ -1603,8 +1603,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->vdev = video_device_alloc();
        if (NULL == dev->vdev) {
                em28xx_errdev("cannot allocate video_device.\n");
-               kfree(dev);
                em28xx_devused&=~(1<<dev->devno);
+               kfree(dev);
                return -ENOMEM;
        }
 
@@ -1612,8 +1612,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        if (NULL == dev->vbi_dev) {
                em28xx_errdev("cannot allocate video_device.\n");
                kfree(dev->vdev);
-               kfree(dev);
                em28xx_devused&=~(1<<dev->devno);
+               kfree(dev);
                return -ENOMEM;
        }
 
@@ -1650,8 +1650,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                mutex_unlock(&dev->lock);
                list_del(&dev->devlist);
                video_device_release(dev->vdev);
-               kfree(dev);
                em28xx_devused&=~(1<<dev->devno);
+               kfree(dev);
                return -ENODEV;
        }
 
@@ -1662,8 +1662,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                list_del(&dev->devlist);
                video_device_release(dev->vbi_dev);
                video_device_release(dev->vdev);
-               kfree(dev);
                em28xx_devused&=~(1<<dev->devno);
+               kfree(dev);
                return -ENODEV;
        } else {
                printk("registered VBI\n");
index 6c43a90c6569f4d3856966294f19da110328d753..c6bff705688d0e02404b7730a972557042e67cd4 100644 (file)
@@ -1,6 +1,6 @@
 config USB_ET61X251
        tristate "USB ET61X[12]51 PC Camera Controller support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        ---help---
          Say Y here if you want support for cameras based on Etoms ET61X151
          or ET61X251 PC Camera Controllers.
index 86376556f108303019b7a20618c4d43b1e20053b..53cbc950f95c6a74066ba64c840b8fe28ac35b6e 100644 (file)
@@ -1,6 +1,6 @@
 config USB_PWC
        tristate "USB Philips Cameras"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        ---help---
          Say Y or M here if you want to use one of these Philips & OEM
          webcams:
index 8326684f49f3214003f7dbb18eff402c9f63ba59..33d60126c02499b27a29a4bfcd2628669c9f6ccc 100644 (file)
@@ -1,20 +1,3 @@
-ifneq ($(KERNELRELEASE),)
-
 pwc-objs       := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o
 
 obj-$(CONFIG_USB_PWC) += pwc.o
-
-else
-
-KDIR := /lib/modules/$(shell uname -r)/build
-PWD := $(shell pwd)
-
-default:
-       $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
-
-endif
-
-clean:
-       rm -f *.[oas] .*.flags *.ko .*.cmd .*.d .*.tmp *.mod.c
-       rm -rf .tmp_versions
-
index 133f9e5252fec0f0646c3d1d34e2f92d85385199..c271e2e14105721e953da48d2dc2ad564370e27a 100644 (file)
@@ -142,6 +142,7 @@ struct i2c_reg_value {
 static const struct i2c_reg_value saa7129_init_config_extra[] = {
        { SAA7127_REG_OUTPUT_PORT_CONTROL,              0x38 },
        { SAA7127_REG_VTRIG,                            0xfa },
+       { 0, 0 }
 };
 
 static const struct i2c_reg_value saa7127_init_config_common[] = {
index e666a4465ca460fa7e510cdf899802670f2653c9..86eae3528330bb415316ffb6247de54d6fc0492a 100644 (file)
@@ -3504,6 +3504,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
                /* power-up tuner chip */
                saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x00040000, 0x00040000);
                saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
+               break;
        case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
                /* this turns the remote control chip off to work around a bug in it */
                saa_writeb(SAA7134_GPIO_GPMODE1, 0x80);
index 13de05532e0ac7015ae7d5c98780d09a300070e9..f0c2111f14ad1f11c5bbe0575edd6aedd23420bd 100644 (file)
@@ -548,6 +548,8 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
                if (report & SAA7134_IRQ_REPORT_GPIO16) {
                        switch (dev->has_remote) {
                                case SAA7134_REMOTE_GPIO:
+                                       if (!dev->remote)
+                                               break;
                                        if  (dev->remote->mask_keydown & 0x10000) {
                                                saa7134_input_irq(dev);
                                        }
@@ -564,6 +566,8 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
                if (report & SAA7134_IRQ_REPORT_GPIO18) {
                        switch (dev->has_remote) {
                                case SAA7134_REMOTE_GPIO:
+                                       if (!dev->remote)
+                                               break;
                                        if ((dev->remote->mask_keydown & 0x40000) ||
                                            (dev->remote->mask_keyup & 0x40000)) {
                                                saa7134_input_irq(dev);
@@ -676,7 +680,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
                SAA7134_IRQ2_INTE_PE      |
                SAA7134_IRQ2_INTE_AR;
 
-       if (dev->has_remote == SAA7134_REMOTE_GPIO) {
+       if (dev->has_remote == SAA7134_REMOTE_GPIO && dev->remote) {
                if (dev->remote->mask_keydown & 0x10000)
                        irq2_mask |= SAA7134_IRQ2_INTE_GPIO16;
                else if (dev->remote->mask_keydown & 0x40000)
index aeef80f88a6bb0076a1c7e23709b17b0f1420e09..e4156ec9c6d7ed4412b65aefbfa94ebffc4a1a3a 100644 (file)
 #include "saa7134.h"
 #include <media/v4l2-common.h>
 
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
 /* Include V4L1 specific functions. Should be removed soon */
 #include <linux/videodev.h>
+#endif
 
 /* ------------------------------------------------------------------ */
 
index 55f2bc11964ba33bf107d5af48152eddb6456ba5..cf552e6b8ecfb20ef5b7ed89b591afaeba7ccf18 100644 (file)
@@ -1,6 +1,6 @@
 config USB_SN9C102
        tristate "USB SN9C10x PC Camera Controller support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        ---help---
          Say Y here if you want support for cameras based on SONiX SN9C101,
          SN9C102 or SN9C103 PC Camera Controllers.
index 72e0f01db563597315d3811ef5854a46cde8b912..a1ae036b44ec9cd362d452697122f06e0db83dee 100644 (file)
@@ -877,8 +877,8 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
 /* ------------ TUNER_LG_TDVS_H062F - INFINEON ATSC ------------ */
 
 static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
-       { 16 * 160.00 /*MHz*/, 0x8e, 0x01 },
-       { 16 * 455.00 /*MHz*/, 0x8e, 0x02 },
+       { 16 * 165.00 /*MHz*/, 0x8e, 0x01 },
+       { 16 * 450.00 /*MHz*/, 0x8e, 0x02 },
        { 16 * 999.99        , 0x8e, 0x04 },
 };
 
index 431c3e2f6c4274a81fe21c62ef232758c5220df5..b463e996961adbb5ee5b6c62db3a045402343adb 100644 (file)
@@ -218,7 +218,7 @@ hauppauge_tuner[] =
        /* 110-119 */
        { TUNER_ABSENT,        "Thompson DTT75105"},
        { TUNER_ABSENT,        "Conexant_CX24109"},
-       { TUNER_ABSENT,        "TCL M2523_5N_E"},
+       { TUNER_TCL_2002N,     "TCL M2523_5N_E"},
        { TUNER_ABSENT,        "TCL M2523_3DB_E"},
        { TUNER_ABSENT,        "Philips 8275A"},
        { TUNER_ABSENT,        "Microtune MT2060"},
index 08a5d20bb2c0dd3488a6e2330b93be1d31d6eb66..39269a2c5635912abcbc8b4f252a50d92a265887 100644 (file)
@@ -3,7 +3,7 @@ config VIDEO_USBVIDEO
 
 config USB_VICAM
        tristate "USB 3com HomeConnect (aka vicam) support (EXPERIMENTAL)"
-       depends on USB && VIDEO_DEV && EXPERIMENTAL
+       depends on USB && VIDEO_V4L1 && EXPERIMENTAL
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you have 3com homeconnect camera (vicam).
@@ -13,7 +13,7 @@ config USB_VICAM
 
 config USB_IBMCAM
        tristate "USB IBM (Xirlink) C-it Camera support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you want to connect a IBM "C-It" camera, also known as
@@ -28,7 +28,7 @@ config USB_IBMCAM
 
 config USB_KONICAWC
        tristate "USB Konica Webcam support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        select VIDEO_USBVIDEO
        ---help---
          Say Y here if you want support for webcams based on a Konica
index 5e813404d06813a981e201a5db2e0e04a5a91244..779db26771c03b5cf4cb8223dbc3a615c2f3a2ab 100644 (file)
 #include <linux/random.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
+#include <linux/dma-mapping.h>
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+/* Include V4L1 specific functions. Should be removed soon */
+#include <linux/videodev.h>
+#endif
 #include <linux/interrupt.h>
 #include <media/video-buf.h>
 #include <media/v4l2-common.h>
index c3bf886b80cdb55ebe485b48ced9debf3ceafe8c..115833e4f4dd3b421832a0a1d81a8aabd39330ee 100644 (file)
@@ -1,6 +1,6 @@
 config USB_ZC0301
        tristate "USB ZC0301 Image Processor and Control Chip support"
-       depends on USB && VIDEO_DEV
+       depends on USB && VIDEO_V4L1
        ---help---
          Say Y here if you want support for cameras based on the ZC0301
          Image Processor and Control Chip.
index 914d62b2406411ca76f707c4ccf8d42a58d4f583..5dc4bee7abebfb9c8685e61306ae54bdff754060 100644 (file)
@@ -310,7 +310,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
                }
                else
                        data->bytes_xfered =
-                               (data->blocks * (1 << data->blksz_bits)) -
+                               (data->blocks * data->blksz) -
                                host->pio.len;
        }
 
@@ -575,7 +575,7 @@ static int
 au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
 {
 
-       int datalen = data->blocks * (1 << data->blksz_bits);
+       int datalen = data->blocks * data->blksz;
 
        if (dma != 0)
                host->flags |= HOST_F_DMA;
@@ -596,7 +596,7 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
        if (host->dma.len == 0)
                return MMC_ERR_TIMEOUT;
 
-       au_writel((1 << data->blksz_bits) - 1, HOST_BLKSIZE(host));
+       au_writel(data->blksz - 1, HOST_BLKSIZE(host));
 
        if (host->flags & HOST_F_DMA) {
                int i;
index 79358e223f5788fdd8dac33c24ce11170ec2ca5c..a4eb1d0e7a7169e381847c978c71b7bcb4dd72f1 100644 (file)
@@ -218,8 +218,10 @@ static int imxmci_busy_wait_for_status(struct imxmci_host *host,
        if(!loops)
                return 0;
 
-       dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n",
-               loops, where, *pstat, stat_mask);
+       /* The busy-wait is expected there for clock <8MHz due to SDHC hardware flaws */
+       if(!(stat_mask & STATUS_END_CMD_RESP) || (host->mmc->ios.clock>=8000000))
+               dev_info(mmc_dev(host->mmc), "busy wait for %d usec in %s, STATUS = 0x%x (0x%x)\n",
+                       loops, where, *pstat, stat_mask);
        return loops;
 }
 
@@ -333,6 +335,9 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd,
        WARN_ON(host->cmd != NULL);
        host->cmd = cmd;
 
+       /* Ensure, that clock are stopped else command programming and start fails */
+       imxmci_stop_clock(host);
+
        if (cmd->flags & MMC_RSP_BUSY)
                cmdat |= CMD_DAT_CONT_BUSY;
 
@@ -553,7 +558,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
        int trans_done = 0;
        unsigned int stat = *pstat;
 
-       if(host->actual_bus_width == MMC_BUS_WIDTH_4)
+       if(host->actual_bus_width != MMC_BUS_WIDTH_4)
                burst_len = 16;
        else
                burst_len = 64;
@@ -591,8 +596,7 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat)
                        stat = MMC_STATUS;
 
                        /* Flush extra bytes from FIFO */
-                       while(flush_len >= 2){
-                               flush_len -= 2;
+                       while(flush_len && !(stat & STATUS_DATA_TRANS_DONE)){
                                i = MMC_BUFFER_ACCESS;
                                stat = MMC_STATUS;
                                stat &= ~STATUS_CRC_READ_ERR; /* Stupid but required there */
@@ -746,10 +750,6 @@ static void imxmci_tasklet_fnc(unsigned long data)
                        data_dir_mask = STATUS_DATA_TRANS_DONE;
                }
 
-               imxmci_busy_wait_for_status(host, &stat,
-                               data_dir_mask,
-                               50, "imxmci_tasklet_fnc data");
-
                if(stat & data_dir_mask) {
                        clear_bit(IMXMCI_PEND_DMA_END_b, &host->pending_events);
                        imxmci_data_done(host, stat);
@@ -865,7 +865,11 @@ static void imxmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
                imxmci_stop_clock(host);
                MMC_CLK_RATE = (prescaler<<3) | clk;
-               imxmci_start_clock(host);
+               /*
+                * Under my understanding, clock should not be started there, because it would
+                * initiate SDHC sequencer and send last or random command into card
+                */
+               /*imxmci_start_clock(host);*/
 
                dev_dbg(mmc_dev(host->mmc), "MMC_CLK_RATE: 0x%08x\n", MMC_CLK_RATE);
        } else {
index 1ca2c8b9c9b552b488702753bfac8d5309a625c8..6201f3086a0226d1810aab52067d0a33e22206fe 100644 (file)
@@ -951,6 +951,7 @@ static void mmc_read_scrs(struct mmc_host *host)
                data.timeout_ns = card->csd.tacc_ns * 10;
                data.timeout_clks = card->csd.tacc_clks * 10;
                data.blksz_bits = 3;
+               data.blksz = 1 << 3;
                data.blocks = 1;
                data.flags = MMC_DATA_READ;
                data.sg = &sg;
index 06bd1f4cb9b1e34c71255ef2c2f6711d0dbbbfc1..587458b370b9a9d71c817d0375d140847f01c505 100644 (file)
@@ -175,6 +175,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
                brq.data.timeout_ns = card->csd.tacc_ns * 10;
                brq.data.timeout_clks = card->csd.tacc_clks * 10;
                brq.data.blksz_bits = md->block_bits;
+               brq.data.blksz = 1 << md->block_bits;
                brq.data.blocks = req->nr_sectors >> (md->block_bits - 9);
                brq.stop.opcode = MMC_STOP_TRANSMISSION;
                brq.stop.arg = 0;
@@ -352,7 +353,7 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
                         */
                        printk(KERN_ERR "%s: unable to select block size for "
                                "writing (rb%u wb%u rp%u wp%u)\n",
-                               md->disk->disk_name,
+                               mmc_card_id(card),
                                1 << card->csd.read_blkbits,
                                1 << card->csd.write_blkbits,
                                card->csd.read_partial,
index f97b472085cbf2c39f3eb99b0b4fd38460aa2c8d..b49368fd96b82b051d59fe85ec00c9127ca05390 100644 (file)
@@ -119,7 +119,7 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
                nob = 0xffff;
 
        writel(nob, host->base + MMC_NOB);
-       writel(1 << data->blksz_bits, host->base + MMC_BLKLEN);
+       writel(data->blksz, host->base + MMC_BLKLEN);
 
        clks = (unsigned long long)data->timeout_ns * CLOCKRATE;
        do_div(clks, 1000000000UL);
@@ -283,7 +283,7 @@ static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
         * data blocks as being in error.
         */
        if (data->error == MMC_ERR_NONE)
-               data->bytes_xfered = data->blocks << data->blksz_bits;
+               data->bytes_xfered = data->blocks * data->blksz;
        else
                data->bytes_xfered = 0;
 
index 39b3d97f891ecf007185170121d0abda316e4a66..8167332d4013d3e7701f108d2aea0dcd241ea700 100644 (file)
@@ -662,14 +662,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
        unsigned long dmaflags;
 
        DBGF("blksz %04x blks %04x flags %08x\n",
-               1 << data->blksz_bits, data->blocks, data->flags);
+               data->blksz, data->blocks, data->flags);
        DBGF("tsac %d ms nsac %d clk\n",
                data->timeout_ns / 1000000, data->timeout_clks);
 
        /*
         * Calculate size.
         */
-       host->size = data->blocks << data->blksz_bits;
+       host->size = data->blocks * data->blksz;
 
        /*
         * Check timeout values for overflow.
@@ -696,12 +696,12 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
         * Two bytes are needed for each data line.
         */
        if (host->bus_width == MMC_BUS_WIDTH_1) {
-               blksize = (1 << data->blksz_bits) + 2;
+               blksize = data->blksz + 2;
 
                wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0);
                wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
        } else if (host->bus_width == MMC_BUS_WIDTH_4) {
-               blksize = (1 << data->blksz_bits) + 2 * 4;
+               blksize = data->blksz + 2 * 4;
 
                wbsd_write_index(host, WBSD_IDX_PBSMSB,
                        ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
index 5ca99e26660af7f9b32f873e06bd3efd9ea4a313..54161aef3cac0cd763479a3a5bc9d7b00da1f83b 100644 (file)
@@ -55,8 +55,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.4.39"
-#define DRV_MODULE_RELDATE     "March 22, 2006"
+#define DRV_MODULE_VERSION     "1.4.40"
+#define DRV_MODULE_RELDATE     "May 22, 2006"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -2945,7 +2945,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
                int buf_size)
 {
        u32 written, offset32, len32;
-       u8 *buf, start[4], end[4];
+       u8 *buf, start[4], end[4], *flash_buffer = NULL;
        int rc = 0;
        int align_start, align_end;
 
@@ -2985,12 +2985,19 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
                memcpy(buf + align_start, data_buf, buf_size);
        }
 
+       if (bp->flash_info->buffered == 0) {
+               flash_buffer = kmalloc(264, GFP_KERNEL);
+               if (flash_buffer == NULL) {
+                       rc = -ENOMEM;
+                       goto nvram_write_end;
+               }
+       }
+
        written = 0;
        while ((written < len32) && (rc == 0)) {
                u32 page_start, page_end, data_start, data_end;
                u32 addr, cmd_flags;
                int i;
-               u8 flash_buffer[264];
 
                /* Find the page_start addr */
                page_start = offset32 + written;
@@ -3061,7 +3068,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
                }
 
                /* Loop to write the new data from data_start to data_end */
-               for (addr = data_start; addr < data_end; addr += 4, i++) {
+               for (addr = data_start; addr < data_end; addr += 4, i += 4) {
                        if ((addr == page_end - 4) ||
                                ((bp->flash_info->buffered) &&
                                 (addr == data_end - 4))) {
@@ -3109,6 +3116,9 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf,
        }
 
 nvram_write_end:
+       if (bp->flash_info->buffered == 0)
+               kfree(flash_buffer);
+
        if (align_start || align_end)
                kfree(buf);
        return rc;
index c99e87838f92913ce277c9a2494955551cb79f04..ed15fcaedaf90a892f266b762164dd3137c10662 100644 (file)
@@ -220,6 +220,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter);
 static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 static int e1000_resume(struct pci_dev *pdev);
 #endif
+static void e1000_shutdown(struct pci_dev *pdev);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /* for netdump / net console */
@@ -235,8 +236,9 @@ static struct pci_driver e1000_driver = {
        /* Power Managment Hooks */
 #ifdef CONFIG_PM
        .suspend  = e1000_suspend,
-       .resume   = e1000_resume
+       .resume   = e1000_resume,
 #endif
+       .shutdown = e1000_shutdown
 };
 
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
@@ -4611,6 +4613,12 @@ e1000_resume(struct pci_dev *pdev)
        return 0;
 }
 #endif
+
+static void e1000_shutdown(struct pci_dev *pdev)
+{
+       e1000_suspend(pdev, PMSG_SUSPEND);
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Polling 'interrupt' - used by things like netconsole to send skbs
index f7235c9bc42179a9b405ac43dcf2c3ec25fe58de..705e1229d89db994aa0db6e0d11a0653e19b9a84 100644 (file)
@@ -2891,78 +2891,6 @@ static int nv_open(struct net_device *dev)
                goto out_drain;
        }
 
-       if (np->msi_flags & NV_MSI_X_CAPABLE) {
-               for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
-                       np->msi_x_entry[i].entry = i;
-               }
-               if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) {
-                       np->msi_flags |= NV_MSI_X_ENABLED;
-                       if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) {
-                               /* Request irq for rx handling */
-                               if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) {
-                                       printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
-                                       pci_disable_msix(np->pci_dev);
-                                       np->msi_flags &= ~NV_MSI_X_ENABLED;
-                                       goto out_drain;
-                               }
-                               /* Request irq for tx handling */
-                               if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) {
-                                       printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
-                                       pci_disable_msix(np->pci_dev);
-                                       np->msi_flags &= ~NV_MSI_X_ENABLED;
-                                       goto out_drain;
-                               }
-                               /* Request irq for link and timer handling */
-                               if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) {
-                                       printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
-                                       pci_disable_msix(np->pci_dev);
-                                       np->msi_flags &= ~NV_MSI_X_ENABLED;
-                                       goto out_drain;
-                               }
-
-                               /* map interrupts to their respective vector */
-                               writel(0, base + NvRegMSIXMap0);
-                               writel(0, base + NvRegMSIXMap1);
-                               set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL);
-                               set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL);
-                               set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER);
-                       } else {
-                               /* Request irq for all interrupts */
-                               if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) {
-                                       printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
-                                       pci_disable_msix(np->pci_dev);
-                                       np->msi_flags &= ~NV_MSI_X_ENABLED;
-                                       goto out_drain;
-                               }
-
-                               /* map interrupts to vector 0 */
-                               writel(0, base + NvRegMSIXMap0);
-                               writel(0, base + NvRegMSIXMap1);
-                       }
-               }
-       }
-       if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
-               if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
-                       np->msi_flags |= NV_MSI_ENABLED;
-                       if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) {
-                               printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
-                               pci_disable_msi(np->pci_dev);
-                               np->msi_flags &= ~NV_MSI_ENABLED;
-                               goto out_drain;
-                       }
-
-                       /* map interrupts to vector 0 */
-                       writel(0, base + NvRegMSIMap0);
-                       writel(0, base + NvRegMSIMap1);
-                       /* enable msi vector 0 */
-                       writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask);
-               }
-       }
-       if (ret != 0) {
-               if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0)
-                       goto out_drain;
-       }
-
        /* ask for interrupts */
        nv_enable_hw_interrupts(dev, np->irqmask);
 
index 5e6d007529905744ce7e0f3d0e5a67b09aa469cc..cff8598aa8004e439564a9727d4495e1e3552012 100644 (file)
@@ -33,7 +33,7 @@ config DONGLE
 
 config ESI_DONGLE
        tristate "ESI JetEye PC dongle"
-       depends on DONGLE && IRDA
+       depends on IRTTY_SIR && DONGLE && IRDA
        help
          Say Y here if you want to build support for the Extended Systems
          JetEye PC dongle.  To compile it as a module, choose M here. The ESI
@@ -44,7 +44,7 @@ config ESI_DONGLE
 
 config ACTISYS_DONGLE
        tristate "ACTiSYS IR-220L and IR220L+ dongle"
-       depends on DONGLE && IRDA
+       depends on IRTTY_SIR && DONGLE && IRDA
        help
          Say Y here if you want to build support for the ACTiSYS IR-220L and
          IR220L+ dongles.  To compile it as a module, choose M here. The
@@ -55,7 +55,7 @@ config ACTISYS_DONGLE
 
 config TEKRAM_DONGLE
        tristate "Tekram IrMate 210B dongle"
-       depends on DONGLE && IRDA
+       depends on IRTTY_SIR && DONGLE && IRDA
        help
          Say Y here if you want to build support for the Tekram IrMate 210B
          dongle.  To compile it as a module, choose M here. The Tekram dongle
@@ -66,7 +66,7 @@ config TEKRAM_DONGLE
 
 config TOIM3232_DONGLE
        tristate "TOIM3232 IrDa dongle"
-       depends on DONGLE && IRDA
+       depends on IRTTY_SIR && DONGLE && IRDA
        help
          Say Y here if you want to build support for the Vishay/Temic
          TOIM3232 and TOIM4232 based dongles.
@@ -74,7 +74,7 @@ config TOIM3232_DONGLE
 
 config LITELINK_DONGLE
        tristate "Parallax LiteLink dongle"
-       depends on DONGLE && IRDA
+       depends on IRTTY_SIR && DONGLE && IRDA
        help
          Say Y here if you want to build support for the Parallax Litelink
          dongle.  To compile it as a module, choose M here.  The Parallax
@@ -85,7 +85,7 @@ config LITELINK_DONGLE
 
 config MA600_DONGLE
        tristate "Mobile Action MA600 dongle"
-       depends on DONGLE && IRDA && EXPERIMENTAL
+       depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL
        help
          Say Y here if you want to build support for the Mobile Action MA600
          dongle.  To compile it as a module, choose M here. The MA600 dongle
@@ -98,7 +98,7 @@ config MA600_DONGLE
 
 config GIRBIL_DONGLE
        tristate "Greenwich GIrBIL dongle"
-       depends on DONGLE && IRDA && EXPERIMENTAL
+       depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL
        help
          Say Y here if you want to build support for the Greenwich GIrBIL
          dongle.  If you want to compile it as a module, choose M here.
@@ -109,7 +109,7 @@ config GIRBIL_DONGLE
 
 config MCP2120_DONGLE
        tristate "Microchip MCP2120"
-       depends on DONGLE && IRDA && EXPERIMENTAL
+       depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL
        help
          Say Y here if you want to build support for the Microchip MCP2120
          dongle.  If you want to compile it as a module, choose M here.
@@ -123,7 +123,7 @@ config MCP2120_DONGLE
 
 config OLD_BELKIN_DONGLE
        tristate "Old Belkin dongle"
-       depends on DONGLE && IRDA && EXPERIMENTAL
+       depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL
        help
          Say Y here if you want to build support for the Adaptec Airport 1000
          and 2000 dongles.  If you want to compile it as a module, choose
@@ -132,7 +132,7 @@ config OLD_BELKIN_DONGLE
 
 config ACT200L_DONGLE
        tristate "ACTiSYS IR-200L dongle"
-       depends on DONGLE && IRDA && EXPERIMENTAL
+       depends on IRTTY_SIR && DONGLE && IRDA && EXPERIMENTAL
        help
          Say Y here if you want to build support for the ACTiSYS IR-200L
          dongle. If you want to compile it as a module, choose M here.
index 448a09488529f59ca3727ce5d89c8ba3903d3c32..2ea66aca648b417ae0109ae132921965b9615eb9 100644 (file)
@@ -1691,17 +1691,6 @@ static void do_set_multicast_list(struct net_device *dev)
                memset(ei_local->mcfilter, 0xFF, 8);
        }
 
-       /* 
-        * DP8390 manuals don't specify any magic sequence for altering
-        * the multicast regs on an already running card. To be safe, we
-        * ensure multicast mode is off prior to loading up the new hash
-        * table. If this proves to be not enough, we can always resort
-        * to stopping the NIC, loading the table and then restarting.
-        */
-        
-       if (netif_running(dev))
-               outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
-
        outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD);
        for(i = 0; i < 8; i++) 
        {
@@ -1715,6 +1704,8 @@ static void do_set_multicast_list(struct net_device *dev)
                outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR);
        else
                outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR);
+
+       outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD);
 }
 
 /*
index 07c31f19c6ba40d419b2d022d069af321130f73f..fc08c4af506ca8194b7f4d3854181fdc5eed43b4 100644 (file)
@@ -1774,8 +1774,6 @@ static int pcnet32_open(struct net_device *dev)
                lp->rx_dma_addr[i] = 0;
        }
 
-       pcnet32_free_ring(dev);
-
        /*
         * Switch back to 16bit mode to avoid problems with dumb
         * DOS packet driver after a warm reboot
index a70c2b0cc10425c9d0b23ffba57f2c7fa185a86c..5ca5a1b546a162ed23eaf2e422fd9db21eee2537 100644 (file)
@@ -78,8 +78,7 @@ static const struct pci_device_id skge_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
        { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
-       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
-       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },    /* DGE-530T */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
        { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) },
@@ -402,7 +401,7 @@ static int skge_set_ring_param(struct net_device *dev,
        int err;
 
        if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
-           p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
+           p->tx_pending < MAX_SKB_FRAGS+1 || p->tx_pending > MAX_TX_RING_SIZE)
                return -EINVAL;
 
        skge->rx_ring.count = p->rx_pending;
@@ -2717,8 +2716,7 @@ static int skge_poll(struct net_device *dev, int *budget)
                if (control & BMU_OWN)
                        break;
 
-               skb = skge_rx_get(skge, e, control, rd->status,
-                                 le16_to_cpu(rd->csum2));
+               skb = skge_rx_get(skge, e, control, rd->status, rd->csum2);
                if (likely(skb)) {
                        dev->last_rx = jiffies;
                        netif_receive_skb(skb);
index 62be6d99d05cd3623e1d0df74cff1495adc9b47c..959109609d852bb47c2c0fd5f3ed04c693486c88 100644 (file)
@@ -51,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME               "sky2"
-#define DRV_VERSION            "1.3"
+#define DRV_VERSION            "1.4"
 #define PFX                    DRV_NAME " "
 
 /*
@@ -105,6 +105,7 @@ MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)
 static const struct pci_device_id sky2_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
        { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },    /* DGE-560T */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@@ -235,6 +236,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
                }
 
                if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+                       sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
                        sky2_pci_write32(hw, PCI_DEV_REG3, 0);
                        reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
                        reg1 &= P_ASPM_CONTROL_MSK;
@@ -306,7 +308,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
        u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
 
        if (sky2->autoneg == AUTONEG_ENABLE &&
-           (hw->chip_id != CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
+           !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
                u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
 
                ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@@ -977,6 +979,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
        struct sky2_hw *hw = sky2->hw;
        unsigned rxq = rxqaddr[sky2->port];
        int i;
+       unsigned thresh;
 
        sky2->rx_put = sky2->rx_next = 0;
        sky2_qset(hw, rxq);
@@ -1001,9 +1004,21 @@ static int sky2_rx_start(struct sky2_port *sky2)
                sky2_rx_add(sky2, re->mapaddr);
        }
 
-       /* Truncate oversize frames */
-       sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8);
-       sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
+
+       /*
+        * The receiver hangs if it receives frames larger than the
+        * packet buffer. As a workaround, truncate oversize frames, but
+        * the register is limited to 9 bits, so if you do frames > 2052
+        * you better get the MTU right!
+        */
+       thresh = (sky2->rx_bufsize - 8) / sizeof(u32);
+       if (thresh > 0x1ff)
+               sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF);
+       else {
+               sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), thresh);
+               sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
+       }
+
 
        /* Tell chip about available buffers */
        sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
@@ -1020,19 +1035,26 @@ static int sky2_up(struct net_device *dev)
        struct sky2_hw *hw = sky2->hw;
        unsigned port = sky2->port;
        u32 ramsize, rxspace, imask;
-       int err;
+       int cap, err = -ENOMEM;
        struct net_device *otherdev = hw->dev[sky2->port^1];
 
-       /* Block bringing up both ports at the same time on a dual port card.
-        * There is an unfixed bug where receiver gets confused and picks up
-        * packets out of order. Until this is fixed, prevent data corruption.
+       /*
+        * On dual port PCI-X card, there is an problem where status
+        * can be received out of order due to split transactions
         */
-       if (otherdev && netif_running(otherdev)) {
-               printk(KERN_INFO PFX "dual port support is disabled.\n");
-               return -EBUSY;
-       }
+       if (otherdev && netif_running(otherdev) &&
+           (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
+               struct sky2_port *osky2 = netdev_priv(otherdev);
+               u16 cmd;
+
+               cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
+               cmd &= ~PCI_X_CMD_MAX_SPLIT;
+               sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
+
+               sky2->rx_csum = 0;
+               osky2->rx_csum = 0;
+       }
 
-       err = -ENOMEM;
        if (netif_msg_ifup(sky2))
                printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
 
@@ -1910,6 +1932,12 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
        }
 }
 
+/* Is status ring empty or is there more to do? */
+static inline int sky2_more_work(const struct sky2_hw *hw)
+{
+       return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX));
+}
+
 /* Process status response ring */
 static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 {
@@ -2182,19 +2210,19 @@ static int sky2_poll(struct net_device *dev0, int *budget)
        if (status & Y2_IS_CHK_TXA2)
                sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
 
-       if (status & Y2_IS_STAT_BMU)
-               sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
        work_done = sky2_status_intr(hw, work_limit);
        *budget -= work_done;
        dev0->quota -= work_done;
 
-       if (work_done >= work_limit)
+       if (status & Y2_IS_STAT_BMU)
+               sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+
+       if (sky2_more_work(hw))
                return 1;
 
        netif_rx_complete(dev0);
 
-       status = sky2_read32(hw, B0_Y2_SP_LISR);
+       sky2_read32(hw, B0_Y2_SP_LISR);
        return 0;
 }
 
@@ -3078,12 +3106,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
        sky2->duplex = -1;
        sky2->speed = -1;
        sky2->advertising = sky2_supported_modes(hw);
-
-       /* Receive checksum disabled for Yukon XL
-        * because of observed problems with incorrect
-        * values when multiple packets are received in one interrupt
-        */
-       sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
+       sky2->rx_csum = 1;
 
        spin_lock_init(&sky2->phy_lock);
        sky2->tx_pending = TX_DEF_PENDING;
index 8012994c9b93213480ac4734d053abb84efdad9a..8a0bc5525f0a64e8024b58d550ed29c4357fc6f4 100644 (file)
@@ -214,6 +214,8 @@ enum csr_regs {
 enum {
        Y2_VMAIN_AVAIL  = 1<<17,/* VMAIN available (YUKON-2 only) */
        Y2_VAUX_AVAIL   = 1<<16,/* VAUX available (YUKON-2 only) */
+       Y2_HW_WOL_ON    = 1<<15,/* HW WOL On  (Yukon-EC Ultra A1 only) */
+       Y2_HW_WOL_OFF   = 1<<14,/* HW WOL On  (Yukon-EC Ultra A1 only) */
        Y2_ASF_ENABLE   = 1<<13,/* ASF Unit Enable (YUKON-2 only) */
        Y2_ASF_DISABLE  = 1<<12,/* ASF Unit Disable (YUKON-2 only) */
        Y2_CLK_RUN_ENA  = 1<<11,/* CLK_RUN Enable  (YUKON-2 only) */
index e1b33a25a25f504e2c246aa326471c0d76c2ea38..49ad60b726579e8bdf8fdf75cafa264cae44cc2b 100644 (file)
@@ -69,8 +69,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.57"
-#define DRV_MODULE_RELDATE     "Apr 28, 2006"
+#define DRV_MODULE_VERSION     "3.58"
+#define DRV_MODULE_RELDATE     "May 22, 2006"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -6488,6 +6488,10 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
        TG3_STAT_ADD32(&sp->rx_frame_too_long_errors, MAC_RX_STATS_FRAME_TOO_LONG);
        TG3_STAT_ADD32(&sp->rx_jabbers, MAC_RX_STATS_JABBERS);
        TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE);
+
+       TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT);
+       TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+       TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT);
 }
 
 static void tg3_timer(unsigned long __opaque)
index ba05dedf29d3396fa08d30c15c240535e6d64b6d..136a70c4d5e4880c442cfd75bf5f6450a621cfb9 100644 (file)
@@ -850,7 +850,7 @@ static void init_rxtx_rings(struct net_device *dev)
                        break;
                skb->dev = dev;                 /* Mark as being used by this device. */
                np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data,
-                                       skb->len,PCI_DMA_FROMDEVICE);
+                                       np->rx_buf_sz,PCI_DMA_FROMDEVICE);
 
                np->rx_ring[i].buffer1 = np->rx_addr[i];
                np->rx_ring[i].status = DescOwn;
@@ -1316,7 +1316,7 @@ static int netdev_rx(struct net_device *dev)
                        skb->dev = dev;                 /* Mark as being used by this device. */
                        np->rx_addr[entry] = pci_map_single(np->pci_dev,
                                                        skb->data,
-                                                       skb->len, PCI_DMA_FROMDEVICE);
+                                                       np->rx_buf_sz, PCI_DMA_FROMDEVICE);
                        np->rx_ring[entry].buffer1 = np->rx_addr[entry];
                }
                wmb();
index a6dc53b4250d83924fa388681697a948e582ade5..fdc21037f6dcf8204bf8950e7d294527312c1091 100644 (file)
@@ -491,8 +491,6 @@ struct rhine_private {
        u8 tx_thresh, rx_thresh;
 
        struct mii_if_info mii_if;
-       struct work_struct tx_timeout_task;
-       struct work_struct check_media_task;
        void __iomem *base;
 };
 
@@ -500,8 +498,6 @@ static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  rhine_open(struct net_device *dev);
 static void rhine_tx_timeout(struct net_device *dev);
-static void rhine_tx_timeout_task(struct net_device *dev);
-static void rhine_check_media_task(struct net_device *dev);
 static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static void rhine_tx(struct net_device *dev);
@@ -856,12 +852,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
        if (rp->quirks & rqRhineI)
                dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
 
-       INIT_WORK(&rp->tx_timeout_task,
-                 (void (*)(void *))rhine_tx_timeout_task, dev);
-
-       INIT_WORK(&rp->check_media_task,
-                 (void (*)(void *))rhine_check_media_task, dev);
-
        /* dev->name not defined before register_netdev()! */
        rc = register_netdev(dev);
        if (rc)
@@ -1108,11 +1098,6 @@ static void rhine_set_carrier(struct mii_if_info *mii)
                       netif_carrier_ok(mii->dev));
 }
 
-static void rhine_check_media_task(struct net_device *dev)
-{
-       rhine_check_media(dev, 0);
-}
-
 static void init_registers(struct net_device *dev)
 {
        struct rhine_private *rp = netdev_priv(dev);
@@ -1166,8 +1151,8 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks)
        if (quirks & rqRhineI) {
                iowrite8(0x01, ioaddr + MIIRegAddr);    // MII_BMSR
 
-               /* Do not call from ISR! */
-               msleep(1);
+               /* Can be called from ISR. Evil. */
+               mdelay(1);
 
                /* 0x80 must be set immediately before turning it off */
                iowrite8(0x80, ioaddr + MIICmd);
@@ -1255,16 +1240,6 @@ static int rhine_open(struct net_device *dev)
 }
 
 static void rhine_tx_timeout(struct net_device *dev)
-{
-       struct rhine_private *rp = netdev_priv(dev);
-
-       /*
-        * Move bulk of work outside of interrupt context
-        */
-       schedule_work(&rp->tx_timeout_task);
-}
-
-static void rhine_tx_timeout_task(struct net_device *dev)
 {
        struct rhine_private *rp = netdev_priv(dev);
        void __iomem *ioaddr = rp->base;
@@ -1677,7 +1652,7 @@ static void rhine_error(struct net_device *dev, int intr_status)
        spin_lock(&rp->lock);
 
        if (intr_status & IntrLinkChange)
-               schedule_work(&rp->check_media_task);
+               rhine_check_media(dev, 0);
        if (intr_status & IntrStatsMax) {
                rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
                rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@@ -1927,9 +1902,6 @@ static int rhine_close(struct net_device *dev)
        spin_unlock_irq(&rp->lock);
 
        free_irq(rp->pdev->irq, dev);
-
-       flush_scheduled_work();
-
        free_rbufs(dev);
        free_tbufs(dev);
        free_ring(dev);
index 0e1ac338cac1a7283e46d4b7145ce7864550edfc..bed6823d980906908da6ecb1b608c7ec5fa32816 100644 (file)
@@ -1838,7 +1838,7 @@ struct net_device * __init arlan_probe(int unit)
 }
 
 #ifdef  MODULE
-int init_module(void)
+int __init init_module(void)
 {
        int i = 0;
 
@@ -1860,7 +1860,7 @@ int init_module(void)
 }
 
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        int i = 0;
        struct net_device *dev;
index e2982a83ae424c8f7ea999239f4f61f70da2bab2..7ed18cad29f75632b6408e72bd258ec25af05eb6 100644 (file)
@@ -3271,6 +3271,9 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm)
        bcm43xx_sysfs_register(bcm);
        //FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
 
+       /*FIXME: This should be handled by softmac instead. */
+       schedule_work(&bcm->softmac->associnfo.work);
+
        assert(err == 0);
 out:
        return err;
@@ -3946,9 +3949,6 @@ static int bcm43xx_resume(struct pci_dev *pdev)
 
        netif_device_attach(net_dev);
        
-       /*FIXME: This should be handled by softmac instead. */
-       schedule_work(&bcm->softmac->associnfo.work);
-
        dprintk(KERN_INFO PFX "Device resumed.\n");
 
        return 0;
index 06523e2a8471f0be0a3fd5e2ef09625283667596..c2d0b09e0418e1955c452248bb65686d8ed0d70e 100644 (file)
@@ -812,7 +812,6 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
        if (datalen > IEEE80211_DATA_LEN + 12) {
                printk(KERN_DEBUG "%s: oversized monitor frame, "
                       "data length = %d\n", dev->name, datalen);
-               err = -EIO;
                stats->rx_length_errors++;
                goto update_stats;
        }
@@ -821,8 +820,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
        if (!skb) {
                printk(KERN_WARNING "%s: Cannot allocate skb for monitor frame\n",
                       dev->name);
-               err = -ENOMEM;
-               goto drop;
+               goto update_stats;
        }
 
        /* Copy the 802.11 header to the skb */
index ff192e96268a1c69519a3c35aac6386bec35ed10..dade4b903579fe2d8f06f03cd3d9fe9c590d48fa 100644 (file)
@@ -4306,7 +4306,7 @@ out:
  * Insertion of the module
  * I'm now quite proud of the multi-device support.
  */
-int init_module(void)
+int __init init_module(void)
 {
        int ret = -EIO;         /* Return error if no cards found */
        int i;
index 6917c6cb091287a407a6274fa7ebdd382237bed5..c2ecae5ff0c17623917f0b365d7fd9e278be90a2 100644 (file)
@@ -33,13 +33,10 @@ acpi_query_osc (
        acpi_status             status;
        struct acpi_object_list input;
        union acpi_object       in_params[4];
-       struct acpi_buffer      output;
-       union acpi_object       out_obj;        
+       struct acpi_buffer      output = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object       *out_obj;
        u32                     osc_dw0;
 
-       /* Setting up output buffer */
-       output.length = sizeof(out_obj) + 3*sizeof(u32);  
-       output.pointer = &out_obj;
        
        /* Setting up input parameters */
        input.count = 4;
@@ -61,12 +58,15 @@ acpi_query_osc (
                        "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
                return status;
        }
-       if (out_obj.type != ACPI_TYPE_BUFFER) {
+       out_obj = output.pointer;
+
+       if (out_obj->type != ACPI_TYPE_BUFFER) {
                printk(KERN_DEBUG  
                        "Evaluate _OSC returns wrong type\n");
-               return AE_TYPE;
+               status = AE_TYPE;
+               goto query_osc_out;
        }
-       osc_dw0 = *((u32 *) out_obj.buffer.pointer);
+       osc_dw0 = *((u32 *) out_obj->buffer.pointer);
        if (osc_dw0) {
                if (osc_dw0 & OSC_REQUEST_ERROR)
                        printk(KERN_DEBUG "_OSC request fails\n"); 
@@ -76,15 +76,21 @@ acpi_query_osc (
                        printk(KERN_DEBUG "_OSC invalid revision\n"); 
                if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
                        /* Update Global Control Set */
-                       global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8));
-                       return AE_OK;
+                       global_ctrlsets = *((u32 *)(out_obj->buffer.pointer+8));
+                       status = AE_OK;
+                       goto query_osc_out;
                }
-               return AE_ERROR;
+               status = AE_ERROR;
+               goto query_osc_out;
        }
 
        /* Update Global Control Set */
-       global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8));
-       return AE_OK;
+       global_ctrlsets = *((u32 *)(out_obj->buffer.pointer + 8));
+       status = AE_OK;
+
+query_osc_out:
+       kfree(output.pointer);
+       return status;
 }
 
 
@@ -96,14 +102,10 @@ acpi_run_osc (
        acpi_status             status;
        struct acpi_object_list input;
        union acpi_object       in_params[4];
-       struct acpi_buffer      output;
-       union acpi_object       out_obj;        
+       struct acpi_buffer      output = {ACPI_ALLOCATE_BUFFER, NULL};
+       union acpi_object       *out_obj;
        u32                     osc_dw0;
 
-       /* Setting up output buffer */
-       output.length = sizeof(out_obj) + 3*sizeof(u32);  
-       output.pointer = &out_obj;
-       
        /* Setting up input parameters */
        input.count = 4;
        input.pointer = in_params;
@@ -124,12 +126,14 @@ acpi_run_osc (
                        "Evaluate _OSC Set fails. Status = 0x%04x\n", status);
                return status;
        }
-       if (out_obj.type != ACPI_TYPE_BUFFER) {
+       out_obj = output.pointer;
+       if (out_obj->type != ACPI_TYPE_BUFFER) {
                printk(KERN_DEBUG  
                        "Evaluate _OSC returns wrong type\n");
-               return AE_TYPE;
+               status = AE_TYPE;
+               goto run_osc_out;
        }
-       osc_dw0 = *((u32 *) out_obj.buffer.pointer);
+       osc_dw0 = *((u32 *) out_obj->buffer.pointer);
        if (osc_dw0) {
                if (osc_dw0 & OSC_REQUEST_ERROR)
                        printk(KERN_DEBUG "_OSC request fails\n"); 
@@ -139,11 +143,17 @@ acpi_run_osc (
                        printk(KERN_DEBUG "_OSC invalid revision\n"); 
                if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) {
                        printk(KERN_DEBUG "_OSC FW not grant req. control\n");
-                       return AE_SUPPORT;
+                       status = AE_SUPPORT;
+                       goto run_osc_out;
                }
-               return AE_ERROR;
+               status = AE_ERROR;
+               goto run_osc_out;
        }
-       return AE_OK;
+       status = AE_OK;
+
+run_osc_out:
+       kfree(output.pointer);
+       return status;
 }
 
 /**
index 16d1ea7b0a18ae0edadea084b891ad3c2797711c..247ab837f841739f0982c51ecd937692d841f5ef 100644 (file)
@@ -589,7 +589,7 @@ static int pd6729_check_irq(int irq, int flags)
        return 0;
 }
 
-static u_int __init pd6729_isa_scan(void)
+static u_int __devinit pd6729_isa_scan(void)
 {
        u_int mask0, mask = 0;
        int i;
index 6c9ad92747fddd2c35061c5e49a4bcc1ad04e2cd..2011567005f99a55b5072b1b7600fc616a1bd5a7 100644 (file)
@@ -141,13 +141,13 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
        /* try the driver's ioctl interface */
        if (ops->ioctl) {
                err = ops->ioctl(class_dev->dev, cmd, arg);
-               if (err != -EINVAL)
+               if (err != -ENOIOCTLCMD)
                        return err;
        }
 
        /* if the driver does not provide the ioctl interface
         * or if that particular ioctl was not implemented
-        * (-EINVAL), we will try to emulate here.
+        * (-ENOIOCTLCMD), we will try to emulate here.
         */
 
        switch (cmd) {
@@ -233,7 +233,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
                break;
 
        default:
-               err = -EINVAL;
+               err = -ENOTTY;
                break;
        }
 
index 2bc8aad47219180f58799a4b89523a9cf8298234..a997529f8926e24e0d3161acabb4c30215c2d21f 100644 (file)
@@ -247,7 +247,7 @@ static int sa1100_rtc_ioctl(struct device *dev, unsigned int cmd,
                rtc_freq = arg;
                return 0;
        }
-       return -EINVAL;
+       return -ENOIOCTLCMD;
 }
 
 static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm)
index e1f7e8e86daffee9f96737442ef9d840904f6a0e..e1fa5fe7901f900167b448997cb4f4373a85e892 100644 (file)
@@ -71,7 +71,7 @@ static int test_rtc_ioctl(struct device *dev, unsigned int cmd,
                return 0;
 
        default:
-               return -EINVAL;
+               return -ENOIOCTLCMD;
        }
 }
 
index 4d49fd501198fee4b8d1d0080c829935a80f50d2..277596c302e30426262db9392be87355cfeb7114 100644 (file)
@@ -270,7 +270,7 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
                epoch = arg;
                break;
        default:
-               return -EINVAL;
+               return -ENOIOCTLCMD;
        }
 
        return 0;
index af9f212314b3a3c00cf5e298daba5f95d9b1acce..fe986af884f8413287082736f94de62b25ee9152 100644 (file)
@@ -1486,13 +1486,13 @@ ch_action_iofatal(fsm_instance * fi, int event, void *arg)
        }
 }
 
-static void 
+static void
 ch_action_reinit(fsm_instance *fi, int event, void *arg)
 {
        struct channel *ch = (struct channel *)arg;
        struct net_device *dev = ch->netdev;
        struct ctc_priv *privptr = dev->priv;
+
        DBF_TEXT(trace, 4, __FUNCTION__);
        ch_action_iofatal(fi, event, arg);
        fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
@@ -1624,7 +1624,7 @@ less_than(char *id1, char *id2)
        }
        dev1 = simple_strtoul(id1, &id1, 16);
        dev2 = simple_strtoul(id2, &id2, 16);
-       
+
        return (dev1 < dev2);
 }
 
@@ -1895,7 +1895,7 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                            irb->scsw.dstat);
                return;
        }
-       
+
        priv = ((struct ccwgroup_device *)cdev->dev.driver_data)
                ->dev.driver_data;
 
@@ -1909,7 +1909,7 @@ ctc_irq_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                           "device %s\n", cdev->dev.bus_id);
                return;
        }
-       
+
        dev = (struct net_device *) (ch->netdev);
        if (dev == NULL) {
                ctc_pr_crit("ctc: ctc_irq_handler dev=NULL bus_id=%s, ch=0x%p\n",
@@ -2008,12 +2008,12 @@ dev_action_stop(fsm_instance * fi, int event, void *arg)
                fsm_event(ch->fsm, CH_EVENT_STOP, ch);
        }
 }
-static void 
+static void
 dev_action_restart(fsm_instance *fi, int event, void *arg)
 {
        struct net_device *dev = (struct net_device *)arg;
        struct ctc_priv *privptr = dev->priv;
-       
+
        DBF_TEXT(trace, 3, __FUNCTION__);
        ctc_pr_debug("%s: Restarting\n", dev->name);
        dev_action_stop(fi, event, arg);
@@ -2193,7 +2193,7 @@ transmit_skb(struct channel *ch, struct sk_buff *skb)
 
        DBF_TEXT(trace, 5, __FUNCTION__);
        /* we need to acquire the lock for testing the state
-        * otherwise we can have an IRQ changing the state to 
+        * otherwise we can have an IRQ changing the state to
         * TXIDLE after the test but before acquiring the lock.
         */
        spin_lock_irqsave(&ch->collect_lock, saveflags);
@@ -2393,7 +2393,7 @@ ctc_tx(struct sk_buff *skb, struct net_device * dev)
 
        /**
         * If channels are not running, try to restart them
-        * and throw away packet. 
+        * and throw away packet.
         */
        if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
                fsm_event(privptr->fsm, DEV_EVENT_START, dev);
@@ -2738,7 +2738,7 @@ ctc_remove_files(struct device *dev)
 /**
  * Add ctc specific attributes.
  * Add ctc private data.
- * 
+ *
  * @param cgdev pointer to ccwgroup_device just added
  *
  * @returns 0 on success, !0 on failure.
@@ -2869,7 +2869,7 @@ ctc_new_device(struct ccwgroup_device *cgdev)
        DBF_TEXT(setup, 3, buffer);
 
        type = get_channel_type(&cgdev->cdev[0]->id);
-       
+
        snprintf(read_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id);
        snprintf(write_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[1]->dev.bus_id);
 
@@ -2907,7 +2907,7 @@ ctc_new_device(struct ccwgroup_device *cgdev)
                    channel_get(type, direction == READ ? read_id : write_id,
                                direction);
                if (privptr->channel[direction] == NULL) {
-                       if (direction == WRITE) 
+                       if (direction == WRITE)
                                channel_free(privptr->channel[READ]);
 
                        ctc_free_netdevice(dev, 1);
@@ -2955,7 +2955,7 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev)
 {
        struct ctc_priv *priv;
        struct net_device *ndev;
-               
+
        DBF_TEXT(setup, 3, __FUNCTION__);
        pr_debug("%s() called\n", __FUNCTION__);
 
index 5cdcdbf92962ee89e8be5534ed5d5152f7a5a9a3..af54d1de07bfb8786f93c5af83efd4f7b286d88c 100644 (file)
@@ -130,7 +130,7 @@ ctc_tty_readmodem(ctc_tty_info *info)
        if ((tty = info->tty)) {
                if (info->mcr & UART_MCR_RTS) {
                        struct sk_buff *skb;
-                       
+
                        if ((skb = skb_dequeue(&info->rx_queue))) {
                                int len = skb->len;
                                tty_insert_flip_string(tty, skb->data, len);
@@ -328,7 +328,7 @@ ctc_tty_inject(ctc_tty_info *info, char c)
 {
        int skb_res;
        struct sk_buff *skb;
-       
+
        DBF_TEXT(trace, 4, __FUNCTION__);
        if (ctc_tty_shuttingdown)
                return;
@@ -497,7 +497,7 @@ ctc_tty_write(struct tty_struct *tty, const u_char * buf, int count)
                c = (count < CTC_TTY_XMIT_SIZE) ? count : CTC_TTY_XMIT_SIZE;
                if (c <= 0)
                        break;
-               
+
                skb_res = info->netdev->hard_header_len + sizeof(info->mcr) +
                        + sizeof(__u32);
                skb = dev_alloc_skb(skb_res + c);
@@ -828,7 +828,7 @@ ctc_tty_block_til_ready(struct tty_struct *tty, struct file *filp, ctc_tty_info
        if (tty_hung_up_p(filp) ||
            (info->flags & CTC_ASYNC_CLOSING)) {
                if (info->flags & CTC_ASYNC_CLOSING)
-                       wait_event(info->close_wait, 
+                       wait_event(info->close_wait,
                                   !(info->flags & CTC_ASYNC_CLOSING));
 #ifdef MODEM_DO_RESTART
                if (info->flags & CTC_ASYNC_HUP_NOTIFY)
@@ -1247,7 +1247,7 @@ ctc_tty_unregister_netdev(struct net_device *dev) {
 void
 ctc_tty_cleanup(void) {
        unsigned long saveflags;
-       
+
        DBF_TEXT(trace, 2, __FUNCTION__);
        spin_lock_irqsave(&ctc_tty_lock, saveflags);
        ctc_tty_shuttingdown = 1;
index b12533104c1ff5b38242791d22d0e94c0f0293de..e965f03a7291659a8384998e57eb30748a9b422a 100644 (file)
@@ -20,7 +20,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-\f
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/err.h>
@@ -77,7 +77,7 @@ group_write(struct device_driver *drv, const char *buf, size_t count)
                int len;
 
                if (!(end = strchr(start, delim[i])))
-                       return count;
+                       return -EINVAL;
                len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1);
                strlcpy (bus_ids[i], start, len);
                argv[i] = bus_ids[i];
@@ -94,7 +94,7 @@ static DRIVER_ATTR(group, 0200, NULL, group_write);
 
 /* Register-unregister for ctc&lcs */
 int
-register_cu3088_discipline(struct ccwgroup_driver *dcp) 
+register_cu3088_discipline(struct ccwgroup_driver *dcp)
 {
        int rc;
 
@@ -109,7 +109,7 @@ register_cu3088_discipline(struct ccwgroup_driver *dcp)
        rc = driver_create_file(&dcp->driver, &driver_attr_group);
        if (rc)
                ccwgroup_driver_unregister(dcp);
-               
+
        return rc;
 
 }
@@ -137,7 +137,7 @@ static int __init
 cu3088_init (void)
 {
        int rc;
-       
+
        cu3088_root_dev = s390_root_dev_register("cu3088");
        if (IS_ERR(cu3088_root_dev))
                return PTR_ERR(cu3088_root_dev);
index 6190be9dca991b7502aa9e60761b459014fa3ae2..e0c7deb9883189f012d0b27d67c83db08317b01e 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * IUCV network driver
  *
  * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
@@ -28,7 +28,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-\f
+
 /* #define DEBUG */
 
 #include <linux/module.h>
@@ -81,7 +81,7 @@ iucv_bus_match (struct device *dev, struct device_driver *drv)
 struct bus_type iucv_bus = {
        .name = "iucv",
        .match = iucv_bus_match,
-};     
+};
 
 struct device *iucv_root;
 
@@ -297,7 +297,7 @@ MODULE_LICENSE("GPL");
 /*
  * Debugging stuff
  *******************************************************************************/
-\f
+
 
 #ifdef DEBUG
 static int debuglevel = 0;
@@ -344,7 +344,7 @@ do { \
 /*
  * Internal functions
  *******************************************************************************/
-\f
+
 /**
  * print start banner
  */
@@ -810,7 +810,7 @@ iucv_register_program (__u8 pgmname[16],
                        sizeof (new_handler->id.userid));
                EBC_TOUPPER (new_handler->id.userid,
                             sizeof (new_handler->id.userid));
-               
+
                if (pgmmask) {
                        memcpy (new_handler->id.mask, pgmmask,
                                sizeof (new_handler->id.mask));
@@ -1229,7 +1229,7 @@ iucv_purge (__u16 pathid, __u32 msgid, __u32 srccls, __u32 *audit)
                /* parm->ipaudit has only 3 bytes */
                *audit >>= 8;
        }
-       
+
        release_param(parm);
 
        iucv_debug(1, "b2f0_result = %ld", b2f0_result);
@@ -2330,14 +2330,14 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                        temp_buff1[j] &= (h->id.mask)[j];
                                        temp_buff2[j] &= (h->id.mask)[j];
                                }
-                               
+
                                iucv_dumpit("temp_buff1:",
                                            temp_buff1, sizeof(temp_buff1));
                                iucv_dumpit("temp_buff2",
                                            temp_buff2, sizeof(temp_buff2));
-                               
+
                                if (!memcmp (temp_buff1, temp_buff2, 24)) {
-                                       
+
                                        iucv_debug(2,
                                                   "found a matching handler");
                                        break;
@@ -2368,7 +2368,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                        } else
                                iucv_sever(int_buf->ippathid, no_listener);
                        break;
-                       
+
                case 0x02:              /*connection complete */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2387,7 +2387,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                        } else
                                iucv_sever(int_buf->ippathid, no_listener);
                        break;
-                       
+
                case 0x03:              /* connection severed */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2398,13 +2398,13 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                        interrupt->ConnectionSevered(
                                                (iucv_ConnectionSevered *)int_buf,
                                                h->pgm_data);
-                               
+
                                else
                                        iucv_sever (int_buf->ippathid, no_listener);
                        } else
                                iucv_sever(int_buf->ippathid, no_listener);
                        break;
-                       
+
                case 0x04:              /* connection quiesced */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2420,7 +2420,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                                   "ConnectionQuiesced not called");
                        }
                        break;
-                       
+
                case 0x05:              /* connection resumed */
                        if (messagesDisabled) {
                            iucv_setmask(~0);
@@ -2436,7 +2436,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                                   "ConnectionResumed not called");
                        }
                        break;
-                       
+
                case 0x06:              /* priority message complete */
                case 0x07:              /* nonpriority message complete */
                        if (h) {
@@ -2449,7 +2449,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                                                   "MessageComplete not called");
                        }
                        break;
-                       
+
                case 0x08:              /* priority message pending  */
                case 0x09:              /* nonpriority message pending  */
                        if (h) {
@@ -2467,7 +2467,7 @@ iucv_do_int(iucv_GeneralInterrupt * int_buf)
                               __FUNCTION__);
                        break;
        }                       /* end switch */
-       
+
        iucv_debug(2, "exiting pathid %d, type %02X",
                 int_buf->ippathid, int_buf->iptype);
 
index 0c4644d3d2f35e76a3529284b9a9b0aeceaf7b06..5b6b1b7241c96452345694a7b76d98dd69150a8b 100644 (file)
@@ -4,7 +4,7 @@
  *
  *  S390 version
  *    Copyright (C) 2000 IBM Corporation
- *    Author(s):Alan Altmark (Alan_Altmark@us.ibm.com) 
+ *    Author(s):Alan Altmark (Alan_Altmark@us.ibm.com)
  *             Xenia Tkatschow (xenia@us.ibm.com)
  *
  *
  * CP Programming Services book, also available on the web
  * thru www.ibm.com/s390/vm/pubs, manual # SC24-5760
  *
- *      Definition of Return Codes                                    
- *      -All positive return codes including zero are reflected back  
- *       from CP except for iucv_register_program. The definition of each 
- *       return code can be found in CP Programming Services book.    
- *       Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760          
- *      - Return Code of:         
- *             (-EINVAL) Invalid value       
- *             (-ENOMEM) storage allocation failed              
+ *      Definition of Return Codes
+ *      -All positive return codes including zero are reflected back
+ *       from CP except for iucv_register_program. The definition of each
+ *       return code can be found in CP Programming Services book.
+ *       Also available on the web thru www.ibm.com/s390/vm/pubs, manual # SC24-5760
+ *      - Return Code of:
+ *             (-EINVAL) Invalid value
+ *             (-ENOMEM) storage allocation failed
  *     pgmask defined in iucv_register_program will be set depending on input
- *     paramters. 
- *     
+ *     paramters.
+ *
  */
 
 #include <linux/types.h>
@@ -124,13 +124,13 @@ iucv_hex_dump(unsigned char *buf, size_t len)
 #define iucv_handle_t void *
 
 /* flags1:
- * All flags are defined in the field IPFLAGS1 of each function   
- * and can be found in CP Programming Services.                  
- * IPLOCAL  - Indicates the connect can only be satisfied on the 
- *            local system                                       
- * IPPRTY   - Indicates a priority message                       
- * IPQUSCE  - Indicates you do not want to receive messages on a 
- *            path until an iucv_resume is issued                
+ * All flags are defined in the field IPFLAGS1 of each function
+ * and can be found in CP Programming Services.
+ * IPLOCAL  - Indicates the connect can only be satisfied on the
+ *            local system
+ * IPPRTY   - Indicates a priority message
+ * IPQUSCE  - Indicates you do not want to receive messages on a
+ *            path until an iucv_resume is issued
  * IPRMDATA - Indicates that the message is in the parameter list
  */
 #define IPLOCAL        0x01
@@ -154,14 +154,14 @@ iucv_hex_dump(unsigned char *buf, size_t len)
 #define AllInterrupts                                    0xf8
 /*
  * Mapping of external interrupt buffers should be used with the corresponding
- * interrupt types.                  
- * Names: iucv_ConnectionPending    ->  connection pending 
+ * interrupt types.
+ * Names: iucv_ConnectionPending    ->  connection pending
  *        iucv_ConnectionComplete   ->  connection complete
- *        iucv_ConnectionSevered    ->  connection severed 
- *        iucv_ConnectionQuiesced   ->  connection quiesced 
- *        iucv_ConnectionResumed    ->  connection resumed 
- *        iucv_MessagePending       ->  message pending    
- *        iucv_MessageComplete      ->  message complete   
+ *        iucv_ConnectionSevered    ->  connection severed
+ *        iucv_ConnectionQuiesced   ->  connection quiesced
+ *        iucv_ConnectionResumed    ->  connection resumed
+ *        iucv_MessagePending       ->  message pending
+ *        iucv_MessageComplete      ->  message complete
  */
 typedef struct {
        u16 ippathid;
@@ -260,16 +260,16 @@ typedef struct {
        uchar res2[3];
 } iucv_MessageComplete;
 
-/* 
- * iucv_interrupt_ops_t: Is a vector of functions that handle 
- * IUCV interrupts.                                          
- * Parameter list:                                           
- *         eib - is a pointer to a 40-byte area described    
- *               with one of the structures above.           
- *         pgm_data - this data is strictly for the          
- *                    interrupt handler that is passed by    
- *                    the application. This may be an address 
- *                    or token.                              
+/*
+ * iucv_interrupt_ops_t: Is a vector of functions that handle
+ * IUCV interrupts.
+ * Parameter list:
+ *         eib - is a pointer to a 40-byte area described
+ *               with one of the structures above.
+ *         pgm_data - this data is strictly for the
+ *                    interrupt handler that is passed by
+ *                    the application. This may be an address
+ *                    or token.
 */
 typedef struct {
        void (*ConnectionPending) (iucv_ConnectionPending * eib,
@@ -287,8 +287,8 @@ typedef struct {
 } iucv_interrupt_ops_t;
 
 /*
- *iucv_array_t : Defines buffer array.                      
- * Inside the array may be 31- bit addresses and 31-bit lengths. 
+ *iucv_array_t : Defines buffer array.
+ * Inside the array may be 31- bit addresses and 31-bit lengths.
 */
 typedef struct {
        u32 address;
@@ -299,19 +299,19 @@ extern struct bus_type iucv_bus;
 extern struct device *iucv_root;
 
 /*   -prototypes-    */
-/*                                                                
- * Name: iucv_register_program                                    
- * Purpose: Registers an application with IUCV                    
- * Input: prmname - user identification                           
+/*
+ * Name: iucv_register_program
+ * Purpose: Registers an application with IUCV
+ * Input: prmname - user identification
  *        userid  - machine identification
  *        pgmmask - indicates which bits in the prmname and userid combined will be
  *                 used to determine who is given control
- *        ops     - address of vector of interrupt handlers       
- *        pgm_data- application data passed to interrupt handlers 
- * Output: NA                                                     
- * Return: address of handler                                     
+ *        ops     - address of vector of interrupt handlers
+ *        pgm_data- application data passed to interrupt handlers
+ * Output: NA
+ * Return: address of handler
  *         (0) - Error occurred, registration not completed.
- * NOTE: Exact cause of failure will be recorded in syslog.                        
+ * NOTE: Exact cause of failure will be recorded in syslog.
 */
 iucv_handle_t iucv_register_program (uchar pgmname[16],
                                     uchar userid[8],
@@ -319,13 +319,13 @@ iucv_handle_t iucv_register_program (uchar pgmname[16],
                                     iucv_interrupt_ops_t * ops,
                                     void *pgm_data);
 
-/*                                                
- * Name: iucv_unregister_program                  
- * Purpose: Unregister application with IUCV      
- * Input: address of handler                      
- * Output: NA                                     
- * Return: (0) - Normal return                    
- *         (-EINVAL) - Internal error, wild pointer     
+/*
+ * Name: iucv_unregister_program
+ * Purpose: Unregister application with IUCV
+ * Input: address of handler
+ * Output: NA
+ * Return: (0) - Normal return
+ *         (-EINVAL) - Internal error, wild pointer
 */
 int iucv_unregister_program (iucv_handle_t handle);
 
@@ -333,7 +333,7 @@ int iucv_unregister_program (iucv_handle_t handle);
  * Name: iucv_accept
  * Purpose: This function is issued after the user receives a Connection Pending external
  *          interrupt and now wishes to complete the IUCV communication path.
- * Input:  pathid - u16 , Path identification number   
+ * Input:  pathid - u16 , Path identification number
  *         msglim_reqstd - u16, The number of outstanding messages requested.
  *         user_data - uchar[16], Data specified by the iucv_connect function.
  *        flags1 - int, Contains options for this path.
@@ -358,34 +358,34 @@ int iucv_accept (u16 pathid,
                 void *pgm_data, int *flags1_out, u16 * msglim);
 
 /*
- * Name: iucv_connect                                         
+ * Name: iucv_connect
  * Purpose: This function establishes an IUCV path. Although the connect may complete
- *         successfully, you are not able to use the path until you receive an IUCV 
- *          Connection Complete external interrupt.            
- * Input: pathid - u16 *, Path identification number          
- *        msglim_reqstd - u16, Number of outstanding messages requested       
- *        user_data - uchar[16], 16-byte user data                    
+ *         successfully, you are not able to use the path until you receive an IUCV
+ *          Connection Complete external interrupt.
+ * Input: pathid - u16 *, Path identification number
+ *        msglim_reqstd - u16, Number of outstanding messages requested
+ *        user_data - uchar[16], 16-byte user data
  *       userid - uchar[8], User identification
- *        system_name - uchar[8], 8-byte identifying the system name 
+ *        system_name - uchar[8], 8-byte identifying the system name
  *       flags1 - int, Contains options for this path.
  *          -IPPRTY -   0x20, Specifies if you want to send priority message.
  *          -IPRMDATA - 0x80, Specifies whether your program can handle a message
  *              in  the parameter list.
- *          -IPQUSCE -  0x40, Specifies whether you want to quiesce the path being      
+ *          -IPQUSCE -  0x40, Specifies whether you want to quiesce the path being
  *             established.
- *          -IPLOCAL -  0X01, Allows an application to force the partner to be on 
+ *          -IPLOCAL -  0X01, Allows an application to force the partner to be on
  *             the local system. If local is specified then target class cannot be
- *             specified.                       
+ *             specified.
  *        flags1_out - int * Contains information about the path
  *           - IPPRTY - 0x20, Indicates you may send priority messages.
  *        msglim - * u16, Number of outstanding messages
- *        handle - iucv_handle_t, Address of handler                         
- *        pgm_data - void *, Application data passed to interrupt handlers              
+ *        handle - iucv_handle_t, Address of handler
+ *        pgm_data - void *, Application data passed to interrupt handlers
  * Output: return code from CP IUCV call
  *         rc - return code from iucv_declare_buffer
- *         -EINVAL - Invalid handle passed by application 
- *         -EINVAL - Pathid address is NULL 
- *         add_pathid_result - Return code from internal function add_pathid         
+ *         -EINVAL - Invalid handle passed by application
+ *         -EINVAL - Pathid address is NULL
+ *         add_pathid_result - Return code from internal function add_pathid
 */
 int
     iucv_connect (u16 * pathid,
@@ -397,16 +397,16 @@ int
                  int *flags1_out,
                  u16 * msglim, iucv_handle_t handle, void *pgm_data);
 
-/*                                                                     
- * Name: iucv_purge                                                    
- * Purpose: This function cancels a message that you have sent.        
- * Input: pathid - Path identification number.                          
+/*
+ * Name: iucv_purge
+ * Purpose: This function cancels a message that you have sent.
+ * Input: pathid - Path identification number.
  *        msgid - Specifies the message ID of the message to be purged.
- *        srccls - Specifies the source message class.                  
- * Output: audit - Contains information about asynchronous error       
- *                 that may have affected the normal completion        
- *                 of this message.                                    
- * Return: Return code from CP IUCV call.                           
+ *        srccls - Specifies the source message class.
+ * Output: audit - Contains information about asynchronous error
+ *                 that may have affected the normal completion
+ *                 of this message.
+ * Return: Return code from CP IUCV call.
 */
 int iucv_purge (u16 pathid, u32 msgid, u32 srccls, __u32 *audit);
 /*
@@ -426,38 +426,38 @@ ulong iucv_query_maxconn (void);
  */
 ulong iucv_query_bufsize (void);
 
-/*                                                                     
- * Name: iucv_quiesce                                                  
- * Purpose: This function temporarily suspends incoming messages on an 
- *          IUCV path. You can later reactivate the path by invoking   
- *          the iucv_resume function.                                  
- * Input: pathid - Path identification number                          
- *        user_data  - 16-bytes of user data                           
- * Output: NA                                                          
- * Return: Return code from CP IUCV call.                           
+/*
+ * Name: iucv_quiesce
+ * Purpose: This function temporarily suspends incoming messages on an
+ *          IUCV path. You can later reactivate the path by invoking
+ *          the iucv_resume function.
+ * Input: pathid - Path identification number
+ *        user_data  - 16-bytes of user data
+ * Output: NA
+ * Return: Return code from CP IUCV call.
 */
 int iucv_quiesce (u16 pathid, uchar user_data[16]);
 
-/*                                                                     
- * Name: iucv_receive                                                  
- * Purpose: This function receives messages that are being sent to you 
+/*
+ * Name: iucv_receive
+ * Purpose: This function receives messages that are being sent to you
  *          over established paths. Data will be returned in buffer for length of
  *          buflen.
- * Input: 
- *       pathid - Path identification number.                          
- *       buffer - Address of buffer to receive.                        
- *       buflen - Length of buffer to receive.                         
- *       msgid - Specifies the message ID.          
- *       trgcls - Specifies target class.                       
- * Output: 
+ * Input:
+ *       pathid - Path identification number.
+ *       buffer - Address of buffer to receive.
+ *       buflen - Length of buffer to receive.
+ *       msgid - Specifies the message ID.
+ *       trgcls - Specifies target class.
+ * Output:
  *      flags1_out: int *, Contains information about this path.
  *         IPNORPY - 0x10 Specifies this is a one-way message and no reply is
- *        expected.      
- *         IPPRTY  - 0x20 Specifies if you want to send priority message.       
+ *        expected.
+ *         IPPRTY  - 0x20 Specifies if you want to send priority message.
  *         IPRMDATA - 0x80 specifies the data is contained in the parameter list
  *       residual_buffer - address of buffer updated by the number
  *                         of bytes you have received.
- *       residual_length -      
+ *       residual_length -
  *              Contains one of the following values, if the receive buffer is:
  *               The same length as the message, this field is zero.
  *               Longer than the message, this field contains the number of
@@ -466,8 +466,8 @@ int iucv_quiesce (u16 pathid, uchar user_data[16]);
  *                count (that is, the number of bytes remaining in the
  *                message that does not fit into the buffer. In this
  *                case b2f0_result = 5.
- * Return: Return code from CP IUCV call.                           
- *         (-EINVAL) - buffer address is pointing to NULL                   
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - buffer address is pointing to NULL
 */
 int iucv_receive (u16 pathid,
                  u32 msgid,
@@ -477,16 +477,16 @@ int iucv_receive (u16 pathid,
                  int *flags1_out,
                  ulong * residual_buffer, ulong * residual_length);
 
- /*                                                                     
-  * Name: iucv_receive_array                                            
-  * Purpose: This function receives messages that are being sent to you 
+ /*
+  * Name: iucv_receive_array
+  * Purpose: This function receives messages that are being sent to you
   *          over established paths. Data will be returned in first buffer for
   *          length of first buffer.
-  * Input: pathid - Path identification number.                          
+  * Input: pathid - Path identification number.
   *        msgid - specifies the message ID.
   *        trgcls - Specifies target class.
-  *        buffer - Address of array of buffers.                         
-  *        buflen - Total length of buffers.                             
+  *        buffer - Address of array of buffers.
+  *        buflen - Total length of buffers.
   * Output:
   *        flags1_out: int *, Contains information about this path.
   *          IPNORPY - 0x10 Specifies this is a one-way message and no reply is
@@ -504,8 +504,8 @@ int iucv_receive (u16 pathid,
   *                count (that is, the number of bytes remaining in the
   *                message that does not fit into the buffer. In this
   *                case b2f0_result = 5.
-  * Return: Return code from CP IUCV call.                           
-  *         (-EINVAL) - Buffer address is NULL.       
+  * Return: Return code from CP IUCV call.
+  *         (-EINVAL) - Buffer address is NULL.
   */
 int iucv_receive_array (u16 pathid,
                        u32 msgid,
@@ -515,44 +515,44 @@ int iucv_receive_array (u16 pathid,
                        int *flags1_out,
                        ulong * residual_buffer, ulong * residual_length);
 
-/*                                                                       
- * Name: iucv_reject                                                     
- * Purpose: The reject function refuses a specified message. Between the 
- *          time you are notified of a message and the time that you     
- *          complete the message, the message may be rejected.           
- * Input: pathid - Path identification number.                            
- *        msgid - Specifies the message ID.                   
- *        trgcls - Specifies target class.                                
- * Output: NA                                                            
- * Return: Return code from CP IUCV call.                             
+/*
+ * Name: iucv_reject
+ * Purpose: The reject function refuses a specified message. Between the
+ *          time you are notified of a message and the time that you
+ *          complete the message, the message may be rejected.
+ * Input: pathid - Path identification number.
+ *        msgid - Specifies the message ID.
+ *        trgcls - Specifies target class.
+ * Output: NA
+ * Return: Return code from CP IUCV call.
 */
 int iucv_reject (u16 pathid, u32 msgid, u32 trgcls);
 
-/*                                                                     
- * Name: iucv_reply                                                    
- * Purpose: This function responds to the two-way messages that you    
- *          receive. You must identify completely the message to       
- *          which you wish to reply. ie, pathid, msgid, and trgcls.    
- * Input: pathid - Path identification number.                          
- *        msgid - Specifies the message ID.                
- *        trgcls - Specifies target class.                              
+/*
+ * Name: iucv_reply
+ * Purpose: This function responds to the two-way messages that you
+ *          receive. You must identify completely the message to
+ *          which you wish to reply. ie, pathid, msgid, and trgcls.
+ * Input: pathid - Path identification number.
+ *        msgid - Specifies the message ID.
+ *        trgcls - Specifies target class.
  *        flags1 - Option for path.
- *          IPPRTY- 0x20, Specifies if you want to send priority message.        
- *        buffer - Address of reply buffer.                             
- *        buflen - Length of reply buffer.                              
- * Output: residual_buffer - Address of buffer updated by the number 
- *                    of bytes you have moved.              
+ *          IPPRTY- 0x20, Specifies if you want to send priority message.
+ *        buffer - Address of reply buffer.
+ *        buflen - Length of reply buffer.
+ * Output: residual_buffer - Address of buffer updated by the number
+ *                    of bytes you have moved.
  *         residual_length - Contains one of the following values:
  *             If the answer buffer is the same length as the reply, this field
  *              contains zero.
  *             If the answer buffer is longer than the reply, this field contains
- *              the number of bytes remaining in the buffer.  
+ *              the number of bytes remaining in the buffer.
  *             If the answer buffer is shorter than the reply, this field contains
  *              a residual count (that is, the number of bytes remianing in the
  *              reply that does not fit into the buffer. In this
  *               case b2f0_result = 5.
- * Return: Return code from CP IUCV call.                           
- *         (-EINVAL) - Buffer address is NULL.                               
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Buffer address is NULL.
 */
 int iucv_reply (u16 pathid,
                u32 msgid,
@@ -561,20 +561,20 @@ int iucv_reply (u16 pathid,
                void *buffer, ulong buflen, ulong * residual_buffer,
                ulong * residual_length);
 
-/*                                                                       
- * Name: iucv_reply_array                                                
- * Purpose: This function responds to the two-way messages that you      
- *          receive. You must identify completely the message to         
- *          which you wish to reply. ie, pathid, msgid, and trgcls.      
- *          The array identifies a list of addresses and lengths of      
- *          discontiguous buffers that contains the reply data.          
- * Input: pathid - Path identification number                            
- *        msgid - Specifies the message ID. 
- *        trgcls - Specifies target class.                                
+/*
+ * Name: iucv_reply_array
+ * Purpose: This function responds to the two-way messages that you
+ *          receive. You must identify completely the message to
+ *          which you wish to reply. ie, pathid, msgid, and trgcls.
+ *          The array identifies a list of addresses and lengths of
+ *          discontiguous buffers that contains the reply data.
+ * Input: pathid - Path identification number
+ *        msgid - Specifies the message ID.
+ *        trgcls - Specifies target class.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20, Specifies if you want to send priority message.
- *        buffer - Address of array of reply buffers.                     
- *        buflen - Total length of reply buffers.                         
+ *        buffer - Address of array of reply buffers.
+ *        buflen - Total length of reply buffers.
  * Output: residual_buffer - Address of buffer which IUCV is currently working on.
  *         residual_length - Contains one of the following values:
  *              If the answer buffer is the same length as the reply, this field
@@ -585,8 +585,8 @@ int iucv_reply (u16 pathid,
  *               a residual count (that is, the number of bytes remianing in the
  *               reply that does not fit into the buffer. In this
  *               case b2f0_result = 5.
- * Return: Return code from CP IUCV call.                             
- *         (-EINVAL) - Buffer address is NULL.              
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Buffer address is NULL.
 */
 int iucv_reply_array (u16 pathid,
                      u32 msgid,
@@ -596,77 +596,77 @@ int iucv_reply_array (u16 pathid,
                      ulong buflen, ulong * residual_address,
                      ulong * residual_length);
 
-/*                                                                  
- * Name: iucv_reply_prmmsg                                          
- * Purpose: This function responds to the two-way messages that you 
- *          receive. You must identify completely the message to    
- *          which you wish to reply. ie, pathid, msgid, and trgcls. 
- *          Prmmsg signifies the data is moved into the             
- *          parameter list.                                         
- * Input: pathid - Path identification number.                       
- *        msgid - Specifies the message ID.              
- *        trgcls - Specifies target class.                           
+/*
+ * Name: iucv_reply_prmmsg
+ * Purpose: This function responds to the two-way messages that you
+ *          receive. You must identify completely the message to
+ *          which you wish to reply. ie, pathid, msgid, and trgcls.
+ *          Prmmsg signifies the data is moved into the
+ *          parameter list.
+ * Input: pathid - Path identification number.
+ *        msgid - Specifies the message ID.
+ *        trgcls - Specifies target class.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20 Specifies if you want to send priority message.
- *        prmmsg - 8-bytes of data to be placed into the parameter.  
- *                 list.                                            
- * Output: NA                                                       
- * Return: Return code from CP IUCV call.                        
+ *        prmmsg - 8-bytes of data to be placed into the parameter.
+ *                 list.
+ * Output: NA
+ * Return: Return code from CP IUCV call.
 */
 int iucv_reply_prmmsg (u16 pathid,
                       u32 msgid, u32 trgcls, int flags1, uchar prmmsg[8]);
 
-/*                                                                     
- * Name: iucv_resume                                                   
- * Purpose: This function restores communications over a quiesced path 
- * Input: pathid - Path identification number.                          
- *        user_data  - 16-bytes of user data.                           
- * Output: NA                                                          
- * Return: Return code from CP IUCV call.                           
+/*
+ * Name: iucv_resume
+ * Purpose: This function restores communications over a quiesced path
+ * Input: pathid - Path identification number.
+ *        user_data  - 16-bytes of user data.
+ * Output: NA
+ * Return: Return code from CP IUCV call.
 */
 int iucv_resume (u16 pathid, uchar user_data[16]);
 
-/*                                                                   
- * Name: iucv_send                                                   
- * Purpose: This function transmits data to another application.     
- *          Data to be transmitted is in a buffer and this is a      
- *          one-way message and the receiver will not reply to the   
- *          message.                                                 
- * Input: pathid - Path identification number.                        
- *        trgcls - Specifies target class.                            
- *        srccls - Specifies the source message class.                
- *        msgtag - Specifies a tag to be associated with the message. 
+/*
+ * Name: iucv_send
+ * Purpose: This function transmits data to another application.
+ *          Data to be transmitted is in a buffer and this is a
+ *          one-way message and the receiver will not reply to the
+ *          message.
+ * Input: pathid - Path identification number.
+ *        trgcls - Specifies target class.
+ *        srccls - Specifies the source message class.
+ *        msgtag - Specifies a tag to be associated with the message.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20 Specifies if you want to send priority message.
- *        buffer - Address of send buffer.                            
- *        buflen - Length of send buffer.                             
- * Output: msgid - Specifies the message ID.                         
- * Return: Return code from CP IUCV call.                         
- *         (-EINVAL) - Buffer address is NULL.                             
+ *        buffer - Address of send buffer.
+ *        buflen - Length of send buffer.
+ * Output: msgid - Specifies the message ID.
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Buffer address is NULL.
 */
 int iucv_send (u16 pathid,
               u32 * msgid,
               u32 trgcls,
               u32 srccls, u32 msgtag, int flags1, void *buffer, ulong buflen);
 
-/*                                                                   
- * Name: iucv_send_array                                             
- * Purpose: This function transmits data to another application.     
- *          The contents of buffer is the address of the array of    
- *          addresses and lengths of discontiguous buffers that hold 
- *          the message text. This is a one-way message and the      
- *          receiver will not reply to the message.                  
- * Input: pathid - Path identification number.                        
- *        trgcls - Specifies target class.                            
- *        srccls - Specifies the source message class.                
+/*
+ * Name: iucv_send_array
+ * Purpose: This function transmits data to another application.
+ *          The contents of buffer is the address of the array of
+ *          addresses and lengths of discontiguous buffers that hold
+ *          the message text. This is a one-way message and the
+ *          receiver will not reply to the message.
+ * Input: pathid - Path identification number.
+ *        trgcls - Specifies target class.
+ *        srccls - Specifies the source message class.
  *        msgtag - Specifies a tag to be associated witht the message.
  *        flags1 - Option for path.
- *          IPPRTY- specifies if you want to send priority message. 
- *        buffer - Address of array of send buffers.                  
- *        buflen - Total length of send buffers.                      
- * Output: msgid - Specifies the message ID.                         
- * Return: Return code from CP IUCV call.                         
- *         (-EINVAL) - Buffer address is NULL.                             
+ *          IPPRTY- specifies if you want to send priority message.
+ *        buffer - Address of array of send buffers.
+ *        buflen - Total length of send buffers.
+ * Output: msgid - Specifies the message ID.
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Buffer address is NULL.
 */
 int iucv_send_array (u16 pathid,
                     u32 * msgid,
@@ -675,48 +675,48 @@ int iucv_send_array (u16 pathid,
                     u32 msgtag,
                     int flags1, iucv_array_t * buffer, ulong buflen);
 
-/*                                                                     
- * Name: iucv_send_prmmsg                                              
- * Purpose: This function transmits data to another application.       
- *          Prmmsg specifies that the 8-bytes of data are to be moved  
- *          into the parameter list. This is a one-way message and the 
- *          receiver will not reply to the message.                    
- * Input: pathid - Path identification number.                          
- *        trgcls - Specifies target class.                              
- *        srccls - Specifies the source message class.                  
- *        msgtag - Specifies a tag to be associated with the message.   
+/*
+ * Name: iucv_send_prmmsg
+ * Purpose: This function transmits data to another application.
+ *          Prmmsg specifies that the 8-bytes of data are to be moved
+ *          into the parameter list. This is a one-way message and the
+ *          receiver will not reply to the message.
+ * Input: pathid - Path identification number.
+ *        trgcls - Specifies target class.
+ *        srccls - Specifies the source message class.
+ *        msgtag - Specifies a tag to be associated with the message.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20 specifies if you want to send priority message.
- *        prmmsg - 8-bytes of data to be placed into parameter list.    
- * Output: msgid - Specifies the message ID.                           
- * Return: Return code from CP IUCV call.                           
+ *        prmmsg - 8-bytes of data to be placed into parameter list.
+ * Output: msgid - Specifies the message ID.
+ * Return: Return code from CP IUCV call.
 */
 int iucv_send_prmmsg (u16 pathid,
                      u32 * msgid,
                      u32 trgcls,
                      u32 srccls, u32 msgtag, int flags1, uchar prmmsg[8]);
 
-/*                                                                
- * Name: iucv_send2way                                            
- * Purpose: This function transmits data to another application.  
- *          Data to be transmitted is in a buffer. The receiver   
- *          of the send is expected to reply to the message and   
- *          a buffer is provided into which IUCV moves the reply  
- *          to this message.                                      
- * Input: pathid - Path identification number.                     
- *        trgcls - Specifies target class.                         
- *        srccls - Specifies the source message class.             
- *        msgtag - Specifies a tag associated with the message.    
+/*
+ * Name: iucv_send2way
+ * Purpose: This function transmits data to another application.
+ *          Data to be transmitted is in a buffer. The receiver
+ *          of the send is expected to reply to the message and
+ *          a buffer is provided into which IUCV moves the reply
+ *          to this message.
+ * Input: pathid - Path identification number.
+ *        trgcls - Specifies target class.
+ *        srccls - Specifies the source message class.
+ *        msgtag - Specifies a tag associated with the message.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20 Specifies if you want to send priority message.
- *        buffer - Address of send buffer.                         
- *        buflen - Length of send buffer.                          
- *        ansbuf - Address of buffer into which IUCV moves the reply of 
- *                 this message.        
- *        anslen - Address of length of buffer.          
- * Output: msgid - Specifies the message ID.                      
- * Return: Return code from CP IUCV call.                      
- *         (-EINVAL) - Buffer or ansbuf address is NULL.    
+ *        buffer - Address of send buffer.
+ *        buflen - Length of send buffer.
+ *        ansbuf - Address of buffer into which IUCV moves the reply of
+ *                 this message.
+ *        anslen - Address of length of buffer.
+ * Output: msgid - Specifies the message ID.
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Buffer or ansbuf address is NULL.
 */
 int iucv_send2way (u16 pathid,
                   u32 * msgid,
@@ -726,28 +726,28 @@ int iucv_send2way (u16 pathid,
                   int flags1,
                   void *buffer, ulong buflen, void *ansbuf, ulong anslen);
 
-/*                                                                    
- * Name: iucv_send2way_array                                          
- * Purpose: This function transmits data to another application.      
- *          The contents of buffer is the address of the array of     
- *          addresses and lengths of discontiguous buffers that hold  
- *          the message text. The receiver of the send is expected to 
- *          reply to the message and a buffer is provided into which  
- *          IUCV moves the reply to this message.                     
- * Input: pathid - Path identification number.                         
- *        trgcls - Specifies target class.                             
- *        srccls - Specifies the source message class.                 
- *        msgtag - Specifies a tag to be associated with the message.   
+/*
+ * Name: iucv_send2way_array
+ * Purpose: This function transmits data to another application.
+ *          The contents of buffer is the address of the array of
+ *          addresses and lengths of discontiguous buffers that hold
+ *          the message text. The receiver of the send is expected to
+ *          reply to the message and a buffer is provided into which
+ *          IUCV moves the reply to this message.
+ * Input: pathid - Path identification number.
+ *        trgcls - Specifies target class.
+ *        srccls - Specifies the source message class.
+ *        msgtag - Specifies a tag to be associated with the message.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20 Specifies if you want to send priority message.
- *        buffer - Sddress of array of send buffers.                   
- *        buflen - Total length of send buffers.                       
- *        ansbuf - Address of array of buffer into which IUCV moves the reply            
- *                 of this message.                         
- *        anslen - Address of length reply buffers.              
- * Output: msgid - Specifies the message ID.                          
- * Return: Return code from CP IUCV call.                          
- *         (-EINVAL) - Buffer address is NULL.                              
+ *        buffer - Sddress of array of send buffers.
+ *        buflen - Total length of send buffers.
+ *        ansbuf - Address of array of buffer into which IUCV moves the reply
+ *                 of this message.
+ *        anslen - Address of length reply buffers.
+ * Output: msgid - Specifies the message ID.
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Buffer address is NULL.
 */
 int iucv_send2way_array (u16 pathid,
                         u32 * msgid,
@@ -758,27 +758,27 @@ int iucv_send2way_array (u16 pathid,
                         iucv_array_t * buffer,
                         ulong buflen, iucv_array_t * ansbuf, ulong anslen);
 
-/*                                                                     
- * Name: iucv_send2way_prmmsg                                          
- * Purpose: This function transmits data to another application.       
- *          Prmmsg specifies that the 8-bytes of data are to be moved  
- *          into the parameter list. This is a two-way message and the 
- *          receiver of the message is expected to reply. A buffer     
- *          is provided into which IUCV moves the reply to this        
- *          message.                                                   
- * Input: pathid - Rath identification number.                          
- *        trgcls - Specifies target class.                              
- *        srccls - Specifies the source message class.                  
- *        msgtag - Specifies a tag to be associated with the message.   
+/*
+ * Name: iucv_send2way_prmmsg
+ * Purpose: This function transmits data to another application.
+ *          Prmmsg specifies that the 8-bytes of data are to be moved
+ *          into the parameter list. This is a two-way message and the
+ *          receiver of the message is expected to reply. A buffer
+ *          is provided into which IUCV moves the reply to this
+ *          message.
+ * Input: pathid - Rath identification number.
+ *        trgcls - Specifies target class.
+ *        srccls - Specifies the source message class.
+ *        msgtag - Specifies a tag to be associated with the message.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20 Specifies if you want to send priority message.
- *        prmmsg - 8-bytes of data to be placed in parameter list.      
- *        ansbuf - Address of buffer into which IUCV moves the reply of    
+ *        prmmsg - 8-bytes of data to be placed in parameter list.
+ *        ansbuf - Address of buffer into which IUCV moves the reply of
  *                 this message.
- *        anslen - Address of length of buffer.               
- * Output: msgid - Specifies the message ID.                           
- * Return: Return code from CP IUCV call.                           
- *         (-EINVAL) - Buffer address is NULL.         
+ *        anslen - Address of length of buffer.
+ * Output: msgid - Specifies the message ID.
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Buffer address is NULL.
 */
 int iucv_send2way_prmmsg (u16 pathid,
                          u32 * msgid,
@@ -788,29 +788,29 @@ int iucv_send2way_prmmsg (u16 pathid,
                          ulong flags1,
                          uchar prmmsg[8], void *ansbuf, ulong anslen);
 
-/*                                                                      
- * Name: iucv_send2way_prmmsg_array                                     
- * Purpose: This function transmits data to another application.        
- *          Prmmsg specifies that the 8-bytes of data are to be moved   
- *          into the parameter list. This is a two-way message and the  
- *          receiver of the message is expected to reply. A buffer      
- *          is provided into which IUCV moves the reply to this         
- *          message. The contents of ansbuf is the address of the       
- *          array of addresses and lengths of discontiguous buffers     
- *          that contain the reply.                                     
- * Input: pathid - Path identification number.                           
- *        trgcls - Specifies target class.                               
- *        srccls - Specifies the source message class.                   
- *        msgtag - Specifies a tag to be associated with the message.    
+/*
+ * Name: iucv_send2way_prmmsg_array
+ * Purpose: This function transmits data to another application.
+ *          Prmmsg specifies that the 8-bytes of data are to be moved
+ *          into the parameter list. This is a two-way message and the
+ *          receiver of the message is expected to reply. A buffer
+ *          is provided into which IUCV moves the reply to this
+ *          message. The contents of ansbuf is the address of the
+ *          array of addresses and lengths of discontiguous buffers
+ *          that contain the reply.
+ * Input: pathid - Path identification number.
+ *        trgcls - Specifies target class.
+ *        srccls - Specifies the source message class.
+ *        msgtag - Specifies a tag to be associated with the message.
  *        flags1 - Option for path.
  *          IPPRTY- 0x20 specifies if you want to send priority message.
- *        prmmsg - 8-bytes of data to be placed into the parameter list. 
+ *        prmmsg - 8-bytes of data to be placed into the parameter list.
  *        ansbuf - Address of array of buffer into which IUCV moves the reply
- *                 of this message.  
- *        anslen - Address of length of reply buffers.                
- * Output: msgid - Specifies the message ID.      
- * Return: Return code from CP IUCV call.      
- *         (-EINVAL) - Ansbuf address is NULL.          
+ *                 of this message.
+ *        anslen - Address of length of reply buffers.
+ * Output: msgid - Specifies the message ID.
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Ansbuf address is NULL.
 */
 int iucv_send2way_prmmsg_array (u16 pathid,
                                u32 * msgid,
@@ -821,29 +821,29 @@ int iucv_send2way_prmmsg_array (u16 pathid,
                                uchar prmmsg[8],
                                iucv_array_t * ansbuf, ulong anslen);
 
-/*                                                                   
- * Name: iucv_setmask                                                
- * Purpose: This function enables or disables the following IUCV     
- *          external interruptions: Nonpriority and priority message 
- *          interrupts, nonpriority and priority reply interrupts.   
+/*
+ * Name: iucv_setmask
+ * Purpose: This function enables or disables the following IUCV
+ *          external interruptions: Nonpriority and priority message
+ *          interrupts, nonpriority and priority reply interrupts.
  * Input: SetMaskFlag - options for interrupts
- *           0x80 - Nonpriority_MessagePendingInterruptsFlag         
- *           0x40 - Priority_MessagePendingInterruptsFlag            
- *           0x20 - Nonpriority_MessageCompletionInterruptsFlag      
- *           0x10 - Priority_MessageCompletionInterruptsFlag         
+ *           0x80 - Nonpriority_MessagePendingInterruptsFlag
+ *           0x40 - Priority_MessagePendingInterruptsFlag
+ *           0x20 - Nonpriority_MessageCompletionInterruptsFlag
+ *           0x10 - Priority_MessageCompletionInterruptsFlag
  *           0x08 - IUCVControlInterruptsFlag
- * Output: NA                                                        
- * Return: Return code from CP IUCV call.                         
+ * Output: NA
+ * Return: Return code from CP IUCV call.
 */
 int iucv_setmask (int SetMaskFlag);
 
-/*                                                  
- * Name: iucv_sever                                 
- * Purpose: This function terminates an IUCV path.  
- * Input: pathid - Path identification number.       
- *        user_data - 16-bytes of user data.         
- * Output: NA       
- * Return: Return code from CP IUCV call.                                
- *         (-EINVAL) - Interal error, wild pointer.       
+/*
+ * Name: iucv_sever
+ * Purpose: This function terminates an IUCV path.
+ * Input: pathid - Path identification number.
+ *        user_data - 16-bytes of user data.
+ * Output: NA
+ * Return: Return code from CP IUCV call.
+ *         (-EINVAL) - Interal error, wild pointer.
 */
 int iucv_sever (u16 pathid, uchar user_data[16]);
index e65da921a827da68fb941b1f90aa4025e666636e..f94419b334f7c064c840c831adf9c77eac15e82d 100644 (file)
@@ -68,6 +68,7 @@ static void lcs_tasklet(unsigned long);
 static void lcs_start_kernel_thread(struct lcs_card *card);
 static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
 static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *);
+static int lcs_recovery(void *ptr);
 
 /**
  * Debug Facility Stuff
@@ -429,12 +430,6 @@ lcs_setup_card(struct lcs_card *card)
        card->tx_buffer = NULL;
        card->tx_emitted = 0;
 
-       /* Initialize kernel thread task used for LGW commands. */
-       INIT_WORK(&card->kernel_thread_starter,
-                 (void *)lcs_start_kernel_thread,card);
-       card->thread_start_mask = 0;
-       card->thread_allowed_mask = 0;
-       card->thread_running_mask = 0;
        init_waitqueue_head(&card->wait_q);
        spin_lock_init(&card->lock);
        spin_lock_init(&card->ipm_lock);
@@ -675,8 +670,9 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
        int index, rc;
 
        LCS_DBF_TEXT(5, trace, "rdybuff");
-       BUG_ON(buffer->state != BUF_STATE_LOCKED &&
-               buffer->state != BUF_STATE_PROCESSED);
+       if (buffer->state != BUF_STATE_LOCKED &&
+           buffer->state != BUF_STATE_PROCESSED)
+               BUG();
        spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
        buffer->state = BUF_STATE_READY;
        index = buffer - channel->iob;
@@ -700,7 +696,8 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
        int index, prev, next;
 
        LCS_DBF_TEXT(5, trace, "prcsbuff");
-       BUG_ON(buffer->state != BUF_STATE_READY);
+       if (buffer->state != BUF_STATE_READY)
+               BUG();
        buffer->state = BUF_STATE_PROCESSED;
        index = buffer - channel->iob;
        prev = (index - 1) & (LCS_NUM_BUFFS - 1);
@@ -732,8 +729,9 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
        unsigned long flags;
 
        LCS_DBF_TEXT(5, trace, "relbuff");
-       BUG_ON(buffer->state != BUF_STATE_LOCKED &&
-               buffer->state != BUF_STATE_PROCESSED);
+       if (buffer->state != BUF_STATE_LOCKED &&
+           buffer->state != BUF_STATE_PROCESSED)
+               BUG();
        spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
        buffer->state = BUF_STATE_EMPTY;
        spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
@@ -1147,8 +1145,6 @@ list_modified:
                list_add_tail(&ipm->list, &card->ipm_list);
        }
        spin_unlock_irqrestore(&card->ipm_lock, flags);
-       if (card->state == DEV_STATE_UP)
-               netif_wake_queue(card->dev);
 }
 
 /**
@@ -1231,17 +1227,17 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev)
                if (ipm != NULL)
                        continue;       /* Address already in list. */
                ipm = (struct lcs_ipm_list *)
-                       kmalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC);
+                       kzalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC);
                if (ipm == NULL) {
                        PRINT_INFO("Not enough memory to add "
                                   "new multicast entry!\n");
                        break;
                }
-               memset(ipm, 0, sizeof(struct lcs_ipm_list));
                memcpy(&ipm->ipm.mac_addr, buf, LCS_MAC_LENGTH);
                ipm->ipm.ip_addr = im4->multiaddr;
                ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED;
                spin_lock_irqsave(&card->ipm_lock, flags);
+               LCS_DBF_HEX(2,trace,&ipm->ipm.ip_addr,4);
                list_add(&ipm->list, &card->ipm_list);
                spin_unlock_irqrestore(&card->ipm_lock, flags);
        }
@@ -1269,7 +1265,15 @@ lcs_register_mc_addresses(void *data)
        read_unlock(&in4_dev->mc_list_lock);
        in_dev_put(in4_dev);
 
+       netif_carrier_off(card->dev);
+       netif_tx_disable(card->dev);
+       wait_event(card->write.wait_q,
+                       (card->write.state != CH_STATE_RUNNING));
        lcs_fix_multicast_list(card);
+       if (card->state == DEV_STATE_UP) {
+               netif_carrier_on(card->dev);
+               netif_wake_queue(card->dev);
+       }
 out:
        lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD);
        return 0;
@@ -1286,7 +1290,7 @@ lcs_set_multicast_list(struct net_device *dev)
         LCS_DBF_TEXT(4, trace, "setmulti");
         card = (struct lcs_card *) dev->priv;
 
-        if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD)) 
+        if (!lcs_set_thread_start_bit(card, LCS_SET_MC_THREAD))
                schedule_work(&card->kernel_thread_starter);
 }
 
@@ -1318,6 +1322,53 @@ lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)
        return PTR_ERR(irb);
 }
 
+static int
+lcs_get_problem(struct ccw_device *cdev, struct irb *irb)
+{
+       int dstat, cstat;
+       char *sense;
+
+       sense = (char *) irb->ecw;
+       cstat = irb->scsw.cstat;
+       dstat = irb->scsw.dstat;
+
+       if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
+                    SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
+                    SCHN_STAT_PROT_CHECK   | SCHN_STAT_PROG_CHECK)) {
+               LCS_DBF_TEXT(2, trace, "CGENCHK");
+               return 1;
+       }
+       if (dstat & DEV_STAT_UNIT_CHECK) {
+               if (sense[LCS_SENSE_BYTE_1] &
+                   LCS_SENSE_RESETTING_EVENT) {
+                       LCS_DBF_TEXT(2, trace, "REVIND");
+                       return 1;
+               }
+               if (sense[LCS_SENSE_BYTE_0] &
+                   LCS_SENSE_CMD_REJECT) {
+                       LCS_DBF_TEXT(2, trace, "CMDREJ");
+                       return 0;
+               }
+               if ((!sense[LCS_SENSE_BYTE_0]) &&
+                   (!sense[LCS_SENSE_BYTE_1]) &&
+                   (!sense[LCS_SENSE_BYTE_2]) &&
+                   (!sense[LCS_SENSE_BYTE_3])) {
+                       LCS_DBF_TEXT(2, trace, "ZEROSEN");
+                       return 0;
+               }
+               LCS_DBF_TEXT(2, trace, "DGENCHK");
+               return 1;
+       }
+       return 0;
+}
+
+void
+lcs_schedule_recovery(struct lcs_card *card)
+{
+       LCS_DBF_TEXT(2, trace, "startrec");
+       if (!lcs_set_thread_start_bit(card, LCS_RECOVERY_THREAD))
+               schedule_work(&card->kernel_thread_starter);
+}
 
 /**
  * IRQ Handler for LCS channels
@@ -1327,7 +1378,8 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 {
        struct lcs_card *card;
        struct lcs_channel *channel;
-       int index;
+       int rc, index;
+       int cstat, dstat;
 
        if (lcs_check_irb_error(cdev, irb))
                return;
@@ -1338,14 +1390,27 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
        else
                channel = &card->write;
 
+       cstat = irb->scsw.cstat;
+       dstat = irb->scsw.dstat;
        LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id);
        LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.cstat, irb->scsw.dstat);
        LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.fctl, irb->scsw.actl);
 
+       /* Check for channel and device errors presented */
+       rc = lcs_get_problem(cdev, irb);
+       if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) {
+               PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n",
+                           cdev->dev.bus_id, dstat, cstat);
+               if (rc) {
+                       lcs_schedule_recovery(card);
+                       wake_up(&card->wait_q);
+                       return;
+               }
+       }
        /* How far in the ccw chain have we processed? */
        if ((channel->state != CH_STATE_INIT) &&
            (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
-               index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) 
+               index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa)
                        - channel->ccws;
                if ((irb->scsw.actl & SCSW_ACTL_SUSPENDED) ||
                    (irb->scsw.cstat & SCHN_STAT_PCI))
@@ -1367,7 +1432,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
        else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED)
                /* CCW execution stopped on a suspend bit. */
                channel->state = CH_STATE_SUSPENDED;
-
        if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
                if (irb->scsw.cc != 0) {
                        ccw_device_halt(channel->ccwdev, (addr_t) channel);
@@ -1376,7 +1440,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
                /* The channel has been stopped by halt_IO. */
                channel->state = CH_STATE_HALTED;
        }
-
        if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) {
                channel->state = CH_STATE_CLEARED;
        }
@@ -1452,7 +1515,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
        lcs_release_buffer(channel, buffer);
        card = (struct lcs_card *)
                ((char *) channel - offsetof(struct lcs_card, write));
-       if (netif_queue_stopped(card->dev))
+       if (netif_queue_stopped(card->dev) && netif_carrier_ok(card->dev))
                netif_wake_queue(card->dev);
        spin_lock(&card->lock);
        card->tx_emitted--;
@@ -1488,6 +1551,10 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
                card->stats.tx_carrier_errors++;
                return 0;
        }
+       if (skb->protocol == htons(ETH_P_IPV6)) {
+               dev_kfree_skb(skb);
+               return 0;
+       }
        netif_stop_queue(card->dev);
        spin_lock(&card->lock);
        if (card->tx_buffer != NULL &&
@@ -1632,30 +1699,6 @@ lcs_detect(struct lcs_card *card)
        return rc;
 }
 
-/**
- * reset card
- */
-static int
-lcs_resetcard(struct lcs_card *card)
-{
-       int retries;
-
-       LCS_DBF_TEXT(2, trace, "rescard");
-       for (retries = 0; retries < 10; retries++) {
-               if (lcs_detect(card) == 0) {
-                       netif_wake_queue(card->dev);
-                       card->state = DEV_STATE_UP;
-                       PRINT_INFO("LCS device %s successfully restarted!\n",
-                                  card->dev->name);
-                       return 0;
-               }
-               msleep(3000);
-       }
-       PRINT_ERR("Error in Reseting LCS card!\n");
-       return -EIO;
-}
-
-
 /**
  * LCS Stop card
  */
@@ -1679,111 +1722,6 @@ lcs_stopcard(struct lcs_card *card)
        return rc;
 }
 
-/**
- * LGW initiated commands
- */
-static int
-lcs_lgw_startlan_thread(void *data)
-{
-       struct lcs_card *card;
-
-       card = (struct lcs_card *) data;
-       daemonize("lgwstpln");
-
-       if (!lcs_do_run_thread(card, LCS_STARTLAN_THREAD))
-               return 0;
-       LCS_DBF_TEXT(4, trace, "lgwstpln");
-       if (card->dev)
-               netif_stop_queue(card->dev);
-       if (lcs_startlan(card) == 0) {
-               netif_wake_queue(card->dev);
-               card->state = DEV_STATE_UP;
-               PRINT_INFO("LCS Startlan for device %s succeeded!\n",
-                          card->dev->name);
-
-       } else
-               PRINT_ERR("LCS Startlan for device %s failed!\n",
-                         card->dev->name);
-       lcs_clear_thread_running_bit(card, LCS_STARTLAN_THREAD);
-       return 0;
-}
-
-/**
- * Send startup command initiated by Lan Gateway
- */
-static int
-lcs_lgw_startup_thread(void *data)
-{
-       int rc;
-
-       struct lcs_card *card;
-
-       card = (struct lcs_card *) data;
-       daemonize("lgwstaln");
-
-       if (!lcs_do_run_thread(card, LCS_STARTUP_THREAD))
-               return 0;
-       LCS_DBF_TEXT(4, trace, "lgwstaln");
-       if (card->dev)
-               netif_stop_queue(card->dev);
-       rc = lcs_send_startup(card, LCS_INITIATOR_LGW);
-       if (rc != 0) {
-               PRINT_ERR("Startup for LCS device %s initiated " \
-                         "by LGW failed!\nReseting card ...\n",
-                         card->dev->name);
-               /* do a card reset */
-               rc = lcs_resetcard(card);
-               if (rc == 0)
-                       goto Done;
-       }
-       rc = lcs_startlan(card);
-       if (rc == 0) {
-               netif_wake_queue(card->dev);
-               card->state = DEV_STATE_UP;
-       }
-Done:
-       if (rc == 0)
-               PRINT_INFO("LCS Startup for device %s succeeded!\n",
-                          card->dev->name);
-       else
-               PRINT_ERR("LCS Startup for device %s failed!\n",
-                         card->dev->name);
-       lcs_clear_thread_running_bit(card, LCS_STARTUP_THREAD);
-       return 0;
-}
-
-
-/**
- * send stoplan command initiated by Lan Gateway
- */
-static int
-lcs_lgw_stoplan_thread(void *data)
-{
-       struct lcs_card *card;
-       int rc;
-
-       card = (struct lcs_card *) data;
-       daemonize("lgwstop");
-
-       if (!lcs_do_run_thread(card, LCS_STOPLAN_THREAD))
-               return 0;
-       LCS_DBF_TEXT(4, trace, "lgwstop");
-       if (card->dev)
-               netif_stop_queue(card->dev);
-       if (lcs_send_stoplan(card, LCS_INITIATOR_LGW) == 0)
-               PRINT_INFO("Stoplan for %s initiated by LGW succeeded!\n",
-                          card->dev->name);
-       else
-               PRINT_ERR("Stoplan %s initiated by LGW failed!\n",
-                         card->dev->name);
-       /*Try to reset the card, stop it on failure */
-        rc = lcs_resetcard(card);
-        if (rc != 0)
-                rc = lcs_stopcard(card);
-       lcs_clear_thread_running_bit(card, LCS_STOPLAN_THREAD);
-        return rc;
-}
-
 /**
  * Kernel Thread helper functions for LGW initiated commands
  */
@@ -1791,15 +1729,12 @@ static void
 lcs_start_kernel_thread(struct lcs_card *card)
 {
        LCS_DBF_TEXT(5, trace, "krnthrd");
-       if (lcs_do_start_thread(card, LCS_STARTUP_THREAD))
-               kernel_thread(lcs_lgw_startup_thread, (void *) card, SIGCHLD);
-       if (lcs_do_start_thread(card, LCS_STARTLAN_THREAD))
-               kernel_thread(lcs_lgw_startlan_thread, (void *) card, SIGCHLD);
-       if (lcs_do_start_thread(card, LCS_STOPLAN_THREAD))
-               kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD);
+       if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD))
+               kernel_thread(lcs_recovery, (void *) card, SIGCHLD);
 #ifdef CONFIG_IP_MULTICAST
        if (lcs_do_start_thread(card, LCS_SET_MC_THREAD))
-               kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD);
+               kernel_thread(lcs_register_mc_addresses,
+                               (void *) card, SIGCHLD);
 #endif
 }
 
@@ -1813,19 +1748,14 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd)
        if (cmd->initiator == LCS_INITIATOR_LGW) {
                switch(cmd->cmd_code) {
                case LCS_CMD_STARTUP:
-                       if (!lcs_set_thread_start_bit(card,
-                                                     LCS_STARTUP_THREAD))
-                               schedule_work(&card->kernel_thread_starter);
-                       break;
                case LCS_CMD_STARTLAN:
-                       if (!lcs_set_thread_start_bit(card,
-                                                     LCS_STARTLAN_THREAD))
-                               schedule_work(&card->kernel_thread_starter);
+                       lcs_schedule_recovery(card);
                        break;
                case LCS_CMD_STOPLAN:
-                       if (!lcs_set_thread_start_bit(card,
-                                                     LCS_STOPLAN_THREAD))
-                               schedule_work(&card->kernel_thread_starter);
+                       PRINT_WARN("Stoplan for %s initiated by LGW.\n",
+                                       card->dev->name);
+                       if (card->dev)
+                               netif_carrier_off(card->dev);
                        break;
                default:
                        PRINT_INFO("UNRECOGNIZED LGW COMMAND\n");
@@ -1941,8 +1871,11 @@ lcs_stop_device(struct net_device *dev)
 
        LCS_DBF_TEXT(2, trace, "stopdev");
        card   = (struct lcs_card *) dev->priv;
-       netif_stop_queue(dev);
+       netif_carrier_off(dev);
+       netif_tx_disable(dev);
        dev->flags &= ~IFF_UP;
+       wait_event(card->write.wait_q,
+               (card->write.state != CH_STATE_RUNNING));
        rc = lcs_stopcard(card);
        if (rc)
                PRINT_ERR("Try it again!\n ");
@@ -1968,6 +1901,7 @@ lcs_open_device(struct net_device *dev)
 
        } else {
                dev->flags |= IFF_UP;
+               netif_carrier_on(dev);
                netif_wake_queue(dev);
                card->state = DEV_STATE_UP;
        }
@@ -2059,10 +1993,31 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char
 
 DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store);
 
+static ssize_t
+lcs_dev_recover_store(struct device *dev, struct device_attribute *attr,
+                     const char *buf, size_t count)
+{
+       struct lcs_card *card = dev->driver_data;
+       char *tmp;
+       int i;
+
+       if (!card)
+               return -EINVAL;
+       if (card->state != DEV_STATE_UP)
+               return -EPERM;
+       i = simple_strtoul(buf, &tmp, 16);
+       if (i == 1)
+               lcs_schedule_recovery(card);
+       return count;
+}
+
+static DEVICE_ATTR(recover, 0200, NULL, lcs_dev_recover_store);
+
 static struct attribute * lcs_attrs[] = {
        &dev_attr_portno.attr,
        &dev_attr_type.attr,
        &dev_attr_lancmd_timeout.attr,
+       &dev_attr_recover.attr,
        NULL,
 };
 
@@ -2099,6 +2054,12 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev)
        ccwgdev->dev.driver_data = card;
        ccwgdev->cdev[0]->handler = lcs_irq;
        ccwgdev->cdev[1]->handler = lcs_irq;
+       card->gdev = ccwgdev;
+       INIT_WORK(&card->kernel_thread_starter,
+                 (void *) lcs_start_kernel_thread, card);
+       card->thread_start_mask = 0;
+       card->thread_allowed_mask = 0;
+       card->thread_running_mask = 0;
         return 0;
 }
 
@@ -2200,6 +2161,7 @@ netdev_out:
        if (recover_state == DEV_STATE_RECOVER) {
                lcs_set_multicast_list(card->dev);
                card->dev->flags |= IFF_UP;
+               netif_carrier_on(card->dev);
                netif_wake_queue(card->dev);
                card->state = DEV_STATE_UP;
        } else {
@@ -2229,7 +2191,7 @@ out:
  * lcs_shutdown_device, called when setting the group device offline.
  */
 static int
-lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
+__lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode)
 {
        struct lcs_card *card;
        enum lcs_dev_states recover_state;
@@ -2239,9 +2201,11 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
        card = (struct lcs_card *)ccwgdev->dev.driver_data;
        if (!card)
                return -ENODEV;
-       lcs_set_allowed_threads(card, 0);
-       if (lcs_wait_for_threads(card, LCS_SET_MC_THREAD))
-               return -ERESTARTSYS;
+       if (recovery_mode == 0) {
+               lcs_set_allowed_threads(card, 0);
+               if (lcs_wait_for_threads(card, LCS_SET_MC_THREAD))
+                       return -ERESTARTSYS;
+       }
        LCS_DBF_HEX(3, setup, &card, sizeof(void*));
        recover_state = card->state;
 
@@ -2256,6 +2220,43 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
        return 0;
 }
 
+static int
+lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
+{
+       return __lcs_shutdown_device(ccwgdev, 0);
+}
+
+/**
+ * drive lcs recovery after startup and startlan initiated by Lan Gateway
+ */
+static int
+lcs_recovery(void *ptr)
+{
+       struct lcs_card *card;
+       struct ccwgroup_device *gdev;
+        int rc;
+
+       card = (struct lcs_card *) ptr;
+       daemonize("lcs_recover");
+
+       LCS_DBF_TEXT(4, trace, "recover1");
+       if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD))
+               return 0;
+       LCS_DBF_TEXT(4, trace, "recover2");
+       gdev = card->gdev;
+       PRINT_WARN("Recovery of device %s started...\n", gdev->dev.bus_id);
+       rc = __lcs_shutdown_device(gdev, 1);
+       rc = lcs_new_device(gdev);
+       if (!rc)
+               PRINT_INFO("Device %s successfully recovered!\n",
+                               card->dev->name);
+       else
+               PRINT_INFO("Device %s could not be recovered!\n",
+                               card->dev->name);
+       lcs_clear_thread_running_bit(card, LCS_RECOVERY_THREAD);
+       return 0;
+}
+
 /**
  * lcs_remove_device, free buffers and card
  */
index 2fad5e40c2e4e7d19ee567ccb28a4fbcd682878c..93143932983b4be1be7ed814147c4d26acbaf376 100644 (file)
@@ -73,13 +73,17 @@ do {                                       \
 /**
  * LCS sense byte definitions
  */
+#define LCS_SENSE_BYTE_0               0
+#define LCS_SENSE_BYTE_1               1
+#define LCS_SENSE_BYTE_2               2
+#define LCS_SENSE_BYTE_3               3
 #define LCS_SENSE_INTERFACE_DISCONNECT 0x01
 #define LCS_SENSE_EQUIPMENT_CHECK      0x10
 #define LCS_SENSE_BUS_OUT_CHECK                0x20
 #define LCS_SENSE_INTERVENTION_REQUIRED 0x40
 #define LCS_SENSE_CMD_REJECT           0x80
-#define LCS_SENSE_RESETTING_EVENT      0x0080
-#define LCS_SENSE_DEVICE_ONLINE                0x0020
+#define LCS_SENSE_RESETTING_EVENT      0x80
+#define LCS_SENSE_DEVICE_ONLINE                0x20
 
 /**
  * LCS packet type definitions
@@ -152,10 +156,9 @@ enum lcs_dev_states {
 
 enum lcs_threads {
        LCS_SET_MC_THREAD       = 1,
-       LCS_STARTLAN_THREAD     = 2,
-       LCS_STOPLAN_THREAD      = 4,
-       LCS_STARTUP_THREAD      = 8,
+       LCS_RECOVERY_THREAD     = 2,
 };
+
 /**
  * LCS struct declarations
  */
@@ -286,6 +289,7 @@ struct lcs_card {
        struct net_device_stats stats;
        unsigned short (*lan_type_trans)(struct sk_buff *skb,
                                         struct net_device *dev);
+       struct ccwgroup_device *gdev;
        struct lcs_channel read;
        struct lcs_channel write;
        struct lcs_buffer *tx_buffer;
index 260a93c8c442b6a882a520e07a4a13820bf97806..b452cc1afd550a5c7c24ed4bde87db498539952c 100644 (file)
@@ -30,7 +30,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */
-\f
+
 #undef DEBUG
 
 #include <linux/module.h>
@@ -65,7 +65,7 @@ MODULE_AUTHOR
     ("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
 MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
 
-\f
+
 #define PRINTK_HEADER " iucv: "       /* for debugging */
 
 static struct device_driver netiucv_driver = {
@@ -202,7 +202,7 @@ netiucv_printname(char *name)
        *p = '\0';
        return tmp;
 }
-\f
+
 /**
  * States of the interface statemachine.
  */
@@ -244,7 +244,7 @@ static const char *dev_event_names[] = {
        "Connection up",
        "Connection down",
 };
-\f
+
 /**
  * Events of the connection statemachine
  */
@@ -364,7 +364,7 @@ static const char *conn_state_names[] = {
        "Connect error",
 };
 
-\f
+
 /**
  * Debug Facility Stuff
  */
@@ -516,7 +516,7 @@ static void
 fsm_action_nop(fsm_instance *fi, int event, void *arg)
 {
 }
-\f
+
 /**
  * Actions of the connection statemachine
  *****************************************************************************/
@@ -993,7 +993,7 @@ static const fsm_node conn_fsm[] = {
 
 static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
 
-\f
+
 /**
  * Actions for interface - statemachine.
  *****************************************************************************/
@@ -1182,7 +1182,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
 
                fsm_newstate(conn->fsm, CONN_STATE_TX);
                conn->prof.send_stamp = xtime;
-               
+
                rc = iucv_send(conn->pathid, NULL, 0, 0, 1 /* single_flag */,
                        0, nskb->data, nskb->len);
                               /* Shut up, gcc! nskb is always below 2G. */
@@ -1220,7 +1220,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
 
        return rc;
 }
-\f
+
 /**
  * Interface API for upper network layers
  *****************************************************************************/
@@ -1291,7 +1291,7 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
 
        /**
         * If connection is not running, try to restart it
-        * and throw away packet. 
+        * and throw away packet.
         */
        if (fsm_getstate(privptr->fsm) != DEV_STATE_RUNNING) {
                fsm_event(privptr->fsm, DEV_EVENT_START, dev);
@@ -1538,7 +1538,7 @@ static ssize_t
 maxcq_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct netiucv_priv *priv = dev->driver_data;
-       
+
        IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
        priv->conn->prof.maxcqueue = 0;
        return count;
@@ -1559,7 +1559,7 @@ static ssize_t
 sdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct netiucv_priv *priv = dev->driver_data;
-       
+
        IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
        priv->conn->prof.doios_single = 0;
        return count;
@@ -1580,7 +1580,7 @@ static ssize_t
 mdoio_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct netiucv_priv *priv = dev->driver_data;
-       
+
        IUCV_DBF_TEXT(trace, 5, __FUNCTION__);
        priv->conn->prof.doios_multi = 0;
        return count;
@@ -1601,7 +1601,7 @@ static ssize_t
 txlen_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct netiucv_priv *priv = dev->driver_data;
-       
+
        IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
        priv->conn->prof.txlen = 0;
        return count;
@@ -1622,7 +1622,7 @@ static ssize_t
 txtime_write (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
        struct netiucv_priv *priv = dev->driver_data;
-       
+
        IUCV_DBF_TEXT(trace, 4, __FUNCTION__);
        priv->conn->prof.tx_time = 0;
        return count;
@@ -2000,7 +2000,7 @@ conn_write(struct device_driver *drv, const char *buf, size_t count)
        }
 
        PRINT_INFO("%s: '%s'\n", dev->name, netiucv_printname(username));
-       
+
        return count;
 
 out_free_ndev:
@@ -2099,7 +2099,7 @@ static int __init
 netiucv_init(void)
 {
        int ret;
-       
+
        ret = iucv_register_dbf_views();
        if (ret) {
                PRINT_WARN("netiucv_init failed, "
@@ -2128,7 +2128,7 @@ netiucv_init(void)
        }
        return ret;
 }
-       
+
 module_init(netiucv_init);
 module_exit(netiucv_exit);
 MODULE_LICENSE("GPL");
index 4df0fcd7b10b18a092aaeba16d6e1f80b120b9e4..619f4a0c7160d5692d09ede8b3b705a6d74790c8 100644 (file)
@@ -376,7 +376,7 @@ struct qeth_hdr_osn {
        __u8 reserved3[18];
        __u32 ccid;
 } __attribute__ ((packed));
-                                           
+
 struct qeth_hdr {
        union {
                struct qeth_hdr_layer2 l2;
@@ -825,7 +825,7 @@ struct qeth_card {
        int use_hard_stop;
        int (*orig_hard_header)(struct sk_buff *,struct net_device *,
                                unsigned short,void *,void *,unsigned);
-       struct qeth_osn_info osn_info; 
+       struct qeth_osn_info osn_info;
 };
 
 struct qeth_card_list_struct {
@@ -944,7 +944,7 @@ qeth_get_netdev_flags(struct qeth_card *card)
                return 0;
        switch (card->info.type) {
        case QETH_CARD_TYPE_IQD:
-       case QETH_CARD_TYPE_OSN:        
+       case QETH_CARD_TYPE_OSN:
                return IFF_NOARP;
 #ifdef CONFIG_QETH_IPV6
        default:
@@ -981,7 +981,7 @@ static inline int
 qeth_get_max_mtu_for_card(int cardtype)
 {
        switch (cardtype) {
-               
+
        case QETH_CARD_TYPE_UNKNOWN:
        case QETH_CARD_TYPE_OSAE:
        case QETH_CARD_TYPE_OSN:
@@ -1097,9 +1097,9 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
        int count = 0, rc = 0;
        int in[4];
 
-       rc = sscanf(buf, "%d.%d.%d.%d%n", 
+       rc = sscanf(buf, "%d.%d.%d.%d%n",
                    &in[0], &in[1], &in[2], &in[3], &count);
-       if (rc != 4  || count
+       if (rc != 4  || count<=0)
                return -EINVAL;
        for (count = 0; count < 4; count++) {
                if (in[count] > 255)
@@ -1131,7 +1131,7 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
 
        cnt = out = found = save_cnt = num2 = 0;
         end = start = (char *) buf;
-       in = (__u16 *) addr;    
+       in = (__u16 *) addr;
        memset(in, 0, 16);
         while (end) {
                 end = strchr(end,':');
@@ -1139,7 +1139,7 @@ qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
                         end = (char *)buf + (strlen(buf));
                         out = 1;
                 }
-                if ((end - start)) { 
+                if ((end - start)) {
                         memset(num, 0, 5);
                         memcpy(num, start, end - start);
                        if (!qeth_isxdigit(num))
@@ -1241,5 +1241,5 @@ qeth_osn_register(unsigned char *read_dev_no,
 
 extern void
 qeth_osn_deregister(struct net_device *);
-               
+
 #endif /* __QETH_H__ */
index 44e226f211e7b1cb2ab7baf182230720242f65c9..0bab60a203094239b6e4893533aa473f4b3d269e 100644 (file)
@@ -81,7 +81,7 @@ void
 qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
 {
        struct qeth_eddp_context_reference *ref;
-       
+
        QETH_DBF_TEXT(trace, 6, "eddprctx");
        while (!list_empty(&buf->ctx_list)){
                ref = list_entry(buf->ctx_list.next,
@@ -135,7 +135,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
                                           "buffer!\n");
                                goto out;
                        }
-               }               
+               }
                /* check if the whole next skb fits into current buffer */
                if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
                                        buf->next_element_to_fill)
@@ -148,7 +148,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
                         * and increment ctx's refcnt */
                        must_refcnt = 1;
                        continue;
-               }       
+               }
                if (must_refcnt){
                        must_refcnt = 0;
                        if (qeth_eddp_buf_ref_context(buf, ctx)){
@@ -266,7 +266,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
        int left_in_frag;
        int copy_len;
        u8 *src;
-       
+
        QETH_DBF_TEXT(trace, 5, "eddpcdtc");
        if (skb_shinfo(eddp->skb)->nr_frags == 0) {
                memcpy(dst, eddp->skb->data + eddp->skb_offset, len);
@@ -408,7 +408,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
        struct tcphdr *tcph;
        int data_len;
        u32 hcsum;
-       
+
        QETH_DBF_TEXT(trace, 5, "eddpftcp");
        eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
        if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
@@ -465,13 +465,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
                eddp->th.tcp.h.seq += data_len;
        }
 }
-                          
+
 static inline int
 qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
                           struct sk_buff *skb, struct qeth_hdr *qhdr)
 {
        struct qeth_eddp_data *eddp = NULL;
-       
+
        QETH_DBF_TEXT(trace, 5, "eddpficx");
        /* create our segmentation headers and copy original headers */
        if (skb->protocol == ETH_P_IP)
@@ -512,7 +512,7 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
                         int hdr_len)
 {
        int skbs_per_page;
-       
+
        QETH_DBF_TEXT(trace, 5, "eddpcanp");
        /* can we put multiple skbs in one page? */
        skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len);
@@ -588,7 +588,7 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
                             struct qeth_hdr *qhdr)
 {
        struct qeth_eddp_context *ctx = NULL;
-       
+
        QETH_DBF_TEXT(trace, 5, "creddpct");
        if (skb->protocol == ETH_P_IP)
                ctx = qeth_eddp_create_context_generic(card, skb,
index e422b41c656e26ba11185c225f350c0113d9cd38..61faf05517d63bdb3071856e0383c485c4148858 100644 (file)
@@ -42,7 +42,7 @@ qeth_create_device_attributes_osn(struct device *dev);
 
 extern void
 qeth_remove_device_attributes_osn(struct device *dev);
-                   
+
 extern int
 qeth_create_driver_attributes(void);
 
index cb14642d97aa8300a12e37238933b91271077d9c..9e671a48cd2f1368460bc49935e5905a0c86f7f6 100644 (file)
@@ -513,7 +513,7 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
 
        QETH_DBF_TEXT(setup, 3, "setoffl");
        QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
-       
+
        if (card->dev && netif_carrier_ok(card->dev))
                netif_carrier_off(card->dev);
        recover_flag = card->state;
@@ -604,13 +604,13 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
        list_for_each_entry(addr, &card->ip_list, entry) {
                if (card->options.layer2) {
                        if ((addr->type == todo->type) &&
-                           (memcmp(&addr->mac, &todo->mac, 
+                           (memcmp(&addr->mac, &todo->mac,
                                    OSA_ADDR_LEN) == 0)) {
                                found = 1;
                                break;
                        }
                        continue;
-               } 
+               }
                if ((addr->proto     == QETH_PROT_IPV4)  &&
                    (todo->proto     == QETH_PROT_IPV4)  &&
                    (addr->type      == todo->type)      &&
@@ -694,13 +694,13 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
                if (card->options.layer2) {
                        if ((tmp->type  == addr->type)  &&
                            (tmp->is_multicast == addr->is_multicast) &&
-                           (memcmp(&tmp->mac, &addr->mac, 
+                           (memcmp(&tmp->mac, &addr->mac,
                                    OSA_ADDR_LEN) == 0)) {
                                found = 1;
                                break;
                        }
                        continue;
-               }        
+               }
                if ((tmp->proto        == QETH_PROT_IPV4)     &&
                    (addr->proto       == QETH_PROT_IPV4)     &&
                    (tmp->type         == addr->type)         &&
@@ -1173,7 +1173,7 @@ qeth_determine_card_type(struct qeth_card *card)
                                           "due to hardware limitations!\n");
                                card->qdio.no_out_queues = 1;
                                card->qdio.default_out_queue = 0;
-                       } 
+                       }
                        return 0;
                }
                i++;
@@ -1198,7 +1198,7 @@ qeth_probe_device(struct ccwgroup_device *gdev)
                return -ENODEV;
 
        QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
-       
+
        card = qeth_alloc_card();
        if (!card) {
                put_device(dev);
@@ -1220,7 +1220,7 @@ qeth_probe_device(struct ccwgroup_device *gdev)
                put_device(dev);
                qeth_free_card(card);
                return rc;
-       }                           
+       }
        if ((rc = qeth_setup_card(card))){
                QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
                put_device(dev);
@@ -1843,7 +1843,7 @@ struct qeth_cmd_buffer *iob)
               &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
        QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
 }
-                                                   
+
 static int
 qeth_send_control_data(struct qeth_card *card, int len,
                       struct qeth_cmd_buffer *iob,
@@ -1937,7 +1937,7 @@ qeth_osn_send_control_data(struct qeth_card *card, int len,
                wake_up(&card->wait_q);
        }
        return rc;
-}                                      
+}
 
 static inline void
 qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
@@ -1966,7 +1966,7 @@ qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
        memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
        return qeth_osn_send_control_data(card, s1, iob);
 }
-                                                           
+
 static int
 qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
                  int (*reply_cb)
@@ -2579,7 +2579,7 @@ qeth_process_inbound_buffer(struct qeth_card *card,
                skb->dev = card->dev;
                if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
                        vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
-               else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)     
+               else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
                        qeth_rebuild_skb(card, skb, hdr);
                else { /*in case of OSN*/
                        skb_push(skb, sizeof(struct qeth_hdr));
@@ -2763,7 +2763,7 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
                index = i % QDIO_MAX_BUFFERS_PER_Q;
                buffer = &card->qdio.in_q->bufs[index];
                if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
-                     qeth_check_qdio_errors(buffer->buffer, 
+                     qeth_check_qdio_errors(buffer->buffer,
                                             qdio_err, siga_err,"qinerr")))
                        qeth_process_inbound_buffer(card, buffer, index);
                /* clear buffer and give back to hardware */
@@ -3187,7 +3187,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
        if (card->qdio.state == QETH_QDIO_ALLOCATED)
                return 0;
 
-       card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), 
+       card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
                                  GFP_KERNEL|GFP_DMA);
        if (!card->qdio.in_q)
                return - ENOMEM;
@@ -3476,7 +3476,7 @@ qeth_halt_channels(struct qeth_card *card)
        rc3 = qeth_halt_channel(&card->data);
        if (rc1)
                return rc1;
-       if (rc2) 
+       if (rc2)
                return rc2;
        return rc3;
 }
@@ -3491,7 +3491,7 @@ qeth_clear_channels(struct qeth_card *card)
        rc3 = qeth_clear_channel(&card->data);
        if (rc1)
                return rc1;
-       if (rc2) 
+       if (rc2)
                return rc2;
        return rc3;
 }
@@ -3798,10 +3798,10 @@ qeth_open(struct net_device *dev)
                QETH_DBF_TEXT(trace,4,"nomacadr");
                return -EPERM;
        }
-       card->dev->flags |= IFF_UP;
-       netif_start_queue(dev);
        card->data.state = CH_STATE_UP;
        card->state = CARD_STATE_UP;
+       card->dev->flags |= IFF_UP;
+       netif_start_queue(dev);
 
        if (!card->lan_online && netif_carrier_ok(dev))
                netif_carrier_off(dev);
@@ -3817,7 +3817,7 @@ qeth_stop(struct net_device *dev)
 
        card = (struct qeth_card *) dev->priv;
 
-       netif_stop_queue(dev);
+       netif_tx_disable(dev);
        card->dev->flags &= ~IFF_UP;
        if (card->state == CARD_STATE_UP)
                card->state = CARD_STATE_SOFTSETUP;
@@ -3958,7 +3958,7 @@ qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
 #endif
        *hdr = (struct qeth_hdr *)
                qeth_push_skb(card, skb, sizeof(struct qeth_hdr));
-       if (hdr == NULL)
+       if (*hdr == NULL)
                return -EINVAL;
        return 0;
 }
@@ -4098,7 +4098,7 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                }
        } else { /* passthrough */
                 if((skb->dev->type == ARPHRD_IEEE802_TR) &&
-                   !memcmp(skb->data + sizeof(struct qeth_hdr) + 
+                   !memcmp(skb->data + sizeof(struct qeth_hdr) +
                    sizeof(__u16), skb->dev->broadcast, 6)) {
                        hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
                                                QETH_HDR_PASSTHRU;
@@ -4385,7 +4385,7 @@ out:
 }
 
 static inline int
-qeth_get_elements_no(struct qeth_card *card, void *hdr, 
+qeth_get_elements_no(struct qeth_card *card, void *hdr,
                     struct sk_buff *skb, int elems)
 {
        int elements_needed = 0;
@@ -4416,6 +4416,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
        enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
        struct qeth_eddp_context *ctx = NULL;
        int tx_bytes = skb->len;
+       unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
+       unsigned short tso_size = skb_shinfo(skb)->tso_size;
        int rc;
 
        QETH_DBF_TEXT(trace, 6, "sendpkt");
@@ -4441,7 +4443,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                return 0;
        }
        cast_type = qeth_get_cast_type(card, skb);
-       if ((cast_type == RTN_BROADCAST) && 
+       if ((cast_type == RTN_BROADCAST) &&
            (card->info.broadcast_capable == 0)){
                card->stats.tx_dropped++;
                card->stats.tx_errors++;
@@ -4463,7 +4465,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                        card->stats.tx_errors++;
                        dev_kfree_skb_any(skb);
                        return NETDEV_TX_OK;
-               } 
+               }
                elements_needed++;
        } else {
                if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) {
@@ -4498,16 +4500,16 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                card->stats.tx_packets++;
                card->stats.tx_bytes += tx_bytes;
 #ifdef CONFIG_QETH_PERF_STATS
-               if (skb_shinfo(skb)->tso_size &&
+               if (tso_size &&
                   !(large_send == QETH_LARGE_SEND_NO)) {
-                       card->perf_stats.large_send_bytes += skb->len;
+                       card->perf_stats.large_send_bytes += tx_bytes;
                        card->perf_stats.large_send_cnt++;
                }
-               if (skb_shinfo(skb)->nr_frags > 0){
+               if (nr_frags > 0){
                        card->perf_stats.sg_skbs_sent++;
                        /* nr_frags + skb->data */
                        card->perf_stats.sg_frags_sent +=
-                               skb_shinfo(skb)->nr_frags + 1;
+                               nr_frags + 1;
                }
 #endif /* CONFIG_QETH_PERF_STATS */
        }
@@ -5373,7 +5375,7 @@ qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
         cmd = (struct qeth_ipa_cmd *) data;
         if (cmd->hdr.return_code) {
                PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
-                         "Continuing\n",cmd->data.setdelvlan.vlan_id, 
+                         "Continuing\n",cmd->data.setdelvlan.vlan_id,
                          QETH_CARD_IFNAME(card), cmd->hdr.return_code);
                QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
                QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
@@ -5393,7 +5395,7 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
        iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
        cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
         cmd->data.setdelvlan.vlan_id = i;
-       return qeth_send_ipa_cmd(card, iob, 
+       return qeth_send_ipa_cmd(card, iob,
                                 qeth_layer2_send_setdelvlan_cb, NULL);
 }
 
@@ -5457,7 +5459,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
  * Examine hardware response to SET_PROMISC_MODE
  */
 static int
-qeth_setadp_promisc_mode_cb(struct qeth_card *card, 
+qeth_setadp_promisc_mode_cb(struct qeth_card *card,
                            struct qeth_reply *reply,
                            unsigned long data)
 {
@@ -5468,10 +5470,10 @@ qeth_setadp_promisc_mode_cb(struct qeth_card *card,
 
        cmd = (struct qeth_ipa_cmd *) data;
        setparms = &(cmd->data.setadapterparms);
-       
+
         qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
-       if (cmd->hdr.return_code) { 
-               QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);      
+       if (cmd->hdr.return_code) {
+               QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
                setparms->data.mode = SET_PROMISC_MODE_OFF;
        }
        card->info.promisc_mode = setparms->data.mode;
@@ -5517,7 +5519,7 @@ qeth_set_multicast_list(struct net_device *dev)
 
        if (card->info.type == QETH_CARD_TYPE_OSN)
                return ;
-        
+
        QETH_DBF_TEXT(trace, 3, "setmulti");
        qeth_delete_mc_addresses(card);
        if (card->options.layer2) {
@@ -5575,7 +5577,7 @@ qeth_osn_assist(struct net_device *dev,
        struct qeth_cmd_buffer *iob;
        struct qeth_card *card;
        int rc;
-       
+
        QETH_DBF_TEXT(trace, 2, "osnsdmc");
        if (!dev)
                return -ENODEV;
@@ -5654,7 +5656,7 @@ qeth_osn_deregister(struct net_device * dev)
        card->osn_info.data_cb = NULL;
        return;
 }
-                                          
+
 static void
 qeth_delete_mc_addresses(struct qeth_card *card)
 {
@@ -5818,7 +5820,7 @@ qeth_add_multicast_ipv6(struct qeth_card *card)
        struct inet6_dev *in6_dev;
 
        QETH_DBF_TEXT(trace,4,"chkmcv6");
-       if (!qeth_is_supported(card, IPA_IPV6)) 
+       if (!qeth_is_supported(card, IPA_IPV6))
                return ;
        in6_dev = in6_dev_get(card->dev);
        if (in6_dev == NULL)
@@ -6359,12 +6361,9 @@ qeth_netdev_init(struct net_device *dev)
        dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
        dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
 #endif
-       dev->hard_header = card->orig_hard_header;
        if (qeth_get_netdev_flags(card) & IFF_NOARP) {
                dev->rebuild_header = NULL;
                dev->hard_header = NULL;
-               if (card->options.fake_ll)
-                       dev->hard_header = qeth_fake_header;
                dev->header_cache_update = NULL;
                dev->hard_header_cache = NULL;
        }
@@ -6373,6 +6372,9 @@ qeth_netdev_init(struct net_device *dev)
        if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
                card->dev->dev_id = card->info.unique_id & 0xffff;
 #endif
+       if (card->options.fake_ll &&
+               (qeth_get_netdev_flags(card) & IFF_NOARP))
+                       dev->hard_header = qeth_fake_header;
        dev->hard_header_parse = NULL;
        dev->set_mac_address = qeth_layer2_set_mac_address;
        dev->flags |= qeth_get_netdev_flags(card);
@@ -6477,6 +6479,9 @@ retry:
        /*network device will be recovered*/
        if (card->dev) {
                card->dev->hard_header = card->orig_hard_header;
+               if (card->options.fake_ll &&
+                   (qeth_get_netdev_flags(card) & IFF_NOARP))
+                       card->dev->hard_header = qeth_fake_header;
                return 0;
        }
        /* at first set_online allocate netdev */
@@ -6584,7 +6589,7 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
 
        cmd = (struct qeth_ipa_cmd *) data;
        if (!card->options.layer2 || card->info.guestlan ||
-           !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {    
+           !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
                memcpy(card->dev->dev_addr,
                       &cmd->data.setadapterparms.data.change_addr.addr,
                       OSA_ADDR_LEN);
@@ -7031,14 +7036,12 @@ qeth_softsetup_ipv6(struct qeth_card *card)
 
        QETH_DBF_TEXT(trace,3,"softipv6");
 
-       netif_stop_queue(card->dev);
        rc = qeth_send_startlan(card, QETH_PROT_IPV6);
        if (rc) {
                PRINT_ERR("IPv6 startlan failed on %s\n",
                          QETH_CARD_IFNAME(card));
                return rc;
        }
-       netif_wake_queue(card->dev);
        rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
        if (rc) {
                PRINT_ERR("IPv6 query ipassist failed on %s\n",
@@ -7352,7 +7355,8 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
                card->options.large_send = type;
                return 0;
        }
-       netif_stop_queue(card->dev);
+       if (card->state == CARD_STATE_UP)
+               netif_tx_disable(card->dev);
        card->options.large_send = type;
        switch (card->options.large_send) {
        case QETH_LARGE_SEND_EDDP:
@@ -7374,7 +7378,8 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
                card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
                break;
        }
-       netif_wake_queue(card->dev);
+       if (card->state == CARD_STATE_UP)
+               netif_wake_queue(card->dev);
        return rc;
 }
 
@@ -7427,7 +7432,7 @@ qeth_softsetup_card(struct qeth_card *card)
        if ((rc = qeth_setrouting_v6(card)))
                QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
 out:
-       netif_stop_queue(card->dev);
+       netif_tx_disable(card->dev);
        return 0;
 }
 
@@ -7567,7 +7572,7 @@ qeth_stop_card(struct qeth_card *card, int recovery_mode)
        if (card->read.state == CH_STATE_UP &&
            card->write.state == CH_STATE_UP &&
            (card->state == CARD_STATE_UP)) {
-               if (recovery_mode && 
+               if (recovery_mode &&
                    card->info.type != QETH_CARD_TYPE_OSN) {
                        qeth_stop(card->dev);
                } else {
@@ -7736,10 +7741,8 @@ static int
 qeth_register_netdev(struct qeth_card *card)
 {
        QETH_DBF_TEXT(setup, 3, "regnetd");
-       if (card->dev->reg_state != NETREG_UNINITIALIZED) {
-               qeth_netdev_init(card->dev);
+       if (card->dev->reg_state != NETREG_UNINITIALIZED)
                return 0;
-       }
        /* sysfs magic */
        SET_NETDEV_DEV(card->dev, &card->gdev->dev);
        return register_netdev(card->dev);
@@ -7750,7 +7753,7 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
 {
        QETH_DBF_TEXT(setup ,2, "startag");
 
-       if (recovery_mode && 
+       if (recovery_mode &&
            card->info.type != QETH_CARD_TYPE_OSN) {
                qeth_open(card->dev);
        } else {
index 011c41041029addb84d96eb478bd533780f261e2..0477c47471c5a7ccb60c00bbd4179ee73a5f47c6 100644 (file)
@@ -445,7 +445,7 @@ enum qeth_ipa_arp_return_codes {
 /* Helper functions */
 #define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
                           (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
-       
+
 /*****************************************************************************/
 /* END OF   IP Assist related definitions                                    */
 /*****************************************************************************/
@@ -490,7 +490,7 @@ extern unsigned char ULP_ENABLE[];
 /* Layer 2 defintions */
 #define QETH_PROT_LAYER2 0x08
 #define QETH_PROT_TCPIP  0x03
-#define QETH_PROT_OSN2   0x0a     
+#define QETH_PROT_OSN2   0x0a
 #define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50)
 #define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19)
 
index 360d782c7adacbc22e5fa074e6306dcde29fd810..66f2da14e6e3a0bd2bbd5250a9b25efa585637b2 100644 (file)
@@ -36,7 +36,7 @@ qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
 {
        struct device *dev = NULL;
        loff_t nr = 0;
-       
+
        down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
        if (*offset == 0)
                return SEQ_START_TOKEN;
@@ -60,8 +60,8 @@ static void *
 qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
 {
        struct device *prev, *next;
-       
-       if (it == SEQ_START_TOKEN) 
+
+       if (it == SEQ_START_TOKEN)
                prev = NULL;
        else
                prev = (struct device *) it;
@@ -180,7 +180,7 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
        struct device *device;
        struct qeth_card *card;
 
-       
+
        if (it == SEQ_START_TOKEN)
                return 0;
 
index 882d419e41603ed065dd319ae190527821ab1a52..185a9cfbcbdc76cff6128a60f1be96fb4bf6d743 100644 (file)
@@ -785,7 +785,7 @@ qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, con
        }
        if (card->options.large_send == type)
                return count;
-       if ((rc = qeth_set_large_send(card, type)))     
+       if ((rc = qeth_set_large_send(card, type)))
                return rc;
        return count;
 }
@@ -1682,7 +1682,7 @@ qeth_create_device_attributes(struct device *dev)
        if (card->info.type == QETH_CARD_TYPE_OSN)
                return sysfs_create_group(&dev->kobj,
                                          &qeth_osn_device_attr_group);
-       
+
        if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group)))
                return ret;
        if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){
@@ -1713,7 +1713,7 @@ qeth_remove_device_attributes(struct device *dev)
        if (card->info.type == QETH_CARD_TYPE_OSN)
                return sysfs_remove_group(&dev->kobj,
                                          &qeth_osn_device_attr_group);
-                     
+
        sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
        sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
        sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
index 1286ddea450b9e5b83d7642e9caed26c9817bc16..24ef40ca956276158d6852d72aff055cc0d26a46 100644 (file)
@@ -117,11 +117,11 @@ __qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
        int fragno;
        unsigned long addr;
        int element, cnt, dlen;
-       
+
        fragno = skb_shinfo(skb)->nr_frags;
        element = *next_element_to_fill;
        dlen = 0;
-       
+
        if (is_tso)
                buffer->element[element].flags =
                        SBAL_FLAGS_MIDDLE_FRAG;
index bd147207f25d4ea8b216102f260b95911938e0d3..b046ffa22101ccb3c8cbc9c6d6453abd8ef20e4d 100644 (file)
@@ -864,6 +864,9 @@ static unsigned int ata_id_xfermask(const u16 *id)
 /**
  *     ata_port_queue_task - Queue port_task
  *     @ap: The ata_port to queue port_task for
+ *     @fn: workqueue function to be scheduled
+ *     @data: data value to pass to workqueue function
+ *     @delay: delay time for workqueue function
  *
  *     Schedule @fn(@data) for execution after @delay jiffies using
  *     port_task.  There is one port_task per port and it's the
@@ -2739,6 +2742,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
  *     ata_dev_init_params - Issue INIT DEV PARAMS command
  *     @ap: Port associated with device @dev
  *     @dev: Device to which command will be sent
+ *     @heads: Number of heads (taskfile parameter)
+ *     @sectors: Number of sectors (taskfile parameter)
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
@@ -3638,6 +3643,8 @@ static void ata_pio_block(struct ata_port *ap)
 
                ata_pio_sector(qc);
        }
+
+       ata_altstatus(ap); /* flush */
 }
 
 static void ata_pio_error(struct ata_port *ap)
@@ -3754,11 +3761,14 @@ static void atapi_packet_task(void *_data)
                spin_lock_irqsave(&ap->host_set->lock, flags);
                ap->flags &= ~ATA_FLAG_NOINTR;
                ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+               ata_altstatus(ap); /* flush */
+
                if (qc->tf.protocol == ATA_PROT_ATAPI_DMA)
                        ap->ops->bmdma_start(qc);       /* initiate bmdma */
                spin_unlock_irqrestore(&ap->host_set->lock, flags);
        } else {
                ata_data_xfer(ap, qc->cdb, qc->dev->cdb_len, 1);
+               ata_altstatus(ap); /* flush */
 
                /* PIO commands are handled by polling */
                ap->hsm_task_state = HSM_ST;
@@ -4287,6 +4297,7 @@ static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
 int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
 {
        if (ap->flags & ATA_FLAG_SUSPENDED) {
+               ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 200000);
                ap->flags &= ~ATA_FLAG_SUSPENDED;
                ata_set_mode(ap);
        }
@@ -4302,6 +4313,7 @@ int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
  *     ata_device_suspend - prepare a device for suspend
  *     @ap: port the device is connected to
  *     @dev: the device to suspend
+ *     @state: target power management state
  *
  *     Flush the cache on the drive, if appropriate, then issue a
  *     standbynow command.
index d5fdcb9a88425fb3edac03a867a3cce74dd5fb34..9b8bca1ac1f01ae6a7a61166235c385e118ffc44 100644 (file)
@@ -37,7 +37,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "sata_mv"
-#define DRV_VERSION    "0.6"
+#define DRV_VERSION    "0.7"
 
 enum {
        /* BAR's are enumerated in terms of pci_resource_start() terms */
@@ -50,6 +50,12 @@ enum {
 
        MV_PCI_REG_BASE         = 0,
        MV_IRQ_COAL_REG_BASE    = 0x18000,      /* 6xxx part only */
+       MV_IRQ_COAL_CAUSE               = (MV_IRQ_COAL_REG_BASE + 0x08),
+       MV_IRQ_COAL_CAUSE_LO            = (MV_IRQ_COAL_REG_BASE + 0x88),
+       MV_IRQ_COAL_CAUSE_HI            = (MV_IRQ_COAL_REG_BASE + 0x8c),
+       MV_IRQ_COAL_THRESHOLD           = (MV_IRQ_COAL_REG_BASE + 0xcc),
+       MV_IRQ_COAL_TIME_THRESHOLD      = (MV_IRQ_COAL_REG_BASE + 0xd0),
+
        MV_SATAHC0_REG_BASE     = 0x20000,
        MV_FLASH_CTL            = 0x1046c,
        MV_GPIO_PORT_CTL        = 0x104f0,
@@ -302,9 +308,6 @@ struct mv_port_priv {
        dma_addr_t              crpb_dma;
        struct mv_sg            *sg_tbl;
        dma_addr_t              sg_tbl_dma;
-
-       unsigned                req_producer;           /* cp of req_in_ptr */
-       unsigned                rsp_consumer;           /* cp of rsp_out_ptr */
        u32                     pp_flags;
 };
 
@@ -937,8 +940,6 @@ static int mv_port_start(struct ata_port *ap)
        writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK,
                 port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 
-       pp->req_producer = pp->rsp_consumer = 0;
-
        /* Don't turn on EDMA here...do it before DMA commands only.  Else
         * we'll be unable to send non-data, PIO, etc due to restricted access
         * to shadow regs.
@@ -1022,16 +1023,16 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
        }
 }
 
-static inline unsigned mv_inc_q_index(unsigned *index)
+static inline unsigned mv_inc_q_index(unsigned index)
 {
-       *index = (*index + 1) & MV_MAX_Q_DEPTH_MASK;
-       return *index;
+       return (index + 1) & MV_MAX_Q_DEPTH_MASK;
 }
 
 static inline void mv_crqb_pack_cmd(u16 *cmdw, u8 data, u8 addr, unsigned last)
 {
-       *cmdw = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
+       u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
                (last ? CRQB_CMD_LAST : 0);
+       *cmdw = cpu_to_le16(tmp);
 }
 
 /**
@@ -1053,15 +1054,11 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
        u16 *cw;
        struct ata_taskfile *tf;
        u16 flags = 0;
+       unsigned in_index;
 
        if (ATA_PROT_DMA != qc->tf.protocol)
                return;
 
-       /* the req producer index should be the same as we remember it */
-       WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
-                 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
-               pp->req_producer);
-
        /* Fill in command request block
         */
        if (!(qc->tf.flags & ATA_TFLAG_WRITE))
@@ -1069,13 +1066,17 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
        WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
        flags |= qc->tag << CRQB_TAG_SHIFT;
 
-       pp->crqb[pp->req_producer].sg_addr =
+       /* get current queue index from hardware */
+       in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS)
+                       >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+
+       pp->crqb[in_index].sg_addr =
                cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
-       pp->crqb[pp->req_producer].sg_addr_hi =
+       pp->crqb[in_index].sg_addr_hi =
                cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
-       pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags);
+       pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags);
 
-       cw = &pp->crqb[pp->req_producer].ata_cmd[0];
+       cw = &pp->crqb[in_index].ata_cmd[0];
        tf = &qc->tf;
 
        /* Sadly, the CRQB cannot accomodate all registers--there are
@@ -1144,16 +1145,12 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
        struct mv_port_priv *pp = ap->private_data;
        struct mv_crqb_iie *crqb;
        struct ata_taskfile *tf;
+       unsigned in_index;
        u32 flags = 0;
 
        if (ATA_PROT_DMA != qc->tf.protocol)
                return;
 
-       /* the req producer index should be the same as we remember it */
-       WARN_ON(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >>
-                 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
-               pp->req_producer);
-
        /* Fill in Gen IIE command request block
         */
        if (!(qc->tf.flags & ATA_TFLAG_WRITE))
@@ -1162,7 +1159,11 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
        WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
        flags |= qc->tag << CRQB_TAG_SHIFT;
 
-       crqb = (struct mv_crqb_iie *) &pp->crqb[pp->req_producer];
+       /* get current queue index from hardware */
+       in_index = (readl(mv_ap_base(ap) + EDMA_REQ_Q_IN_PTR_OFS)
+                       >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
+
+       crqb = (struct mv_crqb_iie *) &pp->crqb[in_index];
        crqb->addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff);
        crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16);
        crqb->flags = cpu_to_le32(flags);
@@ -1210,6 +1211,7 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
 {
        void __iomem *port_mmio = mv_ap_base(qc->ap);
        struct mv_port_priv *pp = qc->ap->private_data;
+       unsigned in_index;
        u32 in_ptr;
 
        if (ATA_PROT_DMA != qc->tf.protocol) {
@@ -1221,23 +1223,20 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
                return ata_qc_issue_prot(qc);
        }
 
-       in_ptr = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+       in_ptr   = readl(port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
+       in_index = (in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
 
-       /* the req producer index should be the same as we remember it */
-       WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
-               pp->req_producer);
        /* until we do queuing, the queue should be empty at this point */
-       WARN_ON(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
-               ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >>
-                 EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
+       WARN_ON(in_index != ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS)
+               >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
 
-       mv_inc_q_index(&pp->req_producer);      /* now incr producer index */
+       in_index = mv_inc_q_index(in_index);    /* now incr producer index */
 
        mv_start_dma(port_mmio, pp);
 
        /* and write the request in pointer to kick the EDMA to life */
        in_ptr &= EDMA_REQ_Q_BASE_LO_MASK;
-       in_ptr |= pp->req_producer << EDMA_REQ_Q_PTR_SHIFT;
+       in_ptr |= in_index << EDMA_REQ_Q_PTR_SHIFT;
        writelfl(in_ptr, port_mmio + EDMA_REQ_Q_IN_PTR_OFS);
 
        return 0;
@@ -1260,28 +1259,26 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
 {
        void __iomem *port_mmio = mv_ap_base(ap);
        struct mv_port_priv *pp = ap->private_data;
+       unsigned out_index;
        u32 out_ptr;
        u8 ata_status;
 
-       out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+       out_ptr   = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
+       out_index = (out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK;
 
-       /* the response consumer index should be the same as we remember it */
-       WARN_ON(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
-               pp->rsp_consumer);
-
-       ata_status = pp->crpb[pp->rsp_consumer].flags >> CRPB_FLAG_STATUS_SHIFT;
+       ata_status = le16_to_cpu(pp->crpb[out_index].flags)
+                                       >> CRPB_FLAG_STATUS_SHIFT;
 
        /* increment our consumer index... */
-       pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer);
+       out_index = mv_inc_q_index(out_index);
 
        /* and, until we do NCQ, there should only be 1 CRPB waiting */
-       WARN_ON(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >>
-                 EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) !=
-               pp->rsp_consumer);
+       WARN_ON(out_index != ((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS)
+               >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK));
 
        /* write out our inc'd consumer index so EDMA knows we're caught up */
        out_ptr &= EDMA_RSP_Q_BASE_LO_MASK;
-       out_ptr |= pp->rsp_consumer << EDMA_RSP_Q_PTR_SHIFT;
+       out_ptr |= out_index << EDMA_RSP_Q_PTR_SHIFT;
        writelfl(out_ptr, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS);
 
        /* Return ATA status register for completed CRPB */
@@ -1291,6 +1288,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
 /**
  *      mv_err_intr - Handle error interrupts on the port
  *      @ap: ATA channel to manipulate
+ *      @reset_allowed: bool: 0 == don't trigger from reset here
  *
  *      In most cases, just clear the interrupt and move on.  However,
  *      some cases require an eDMA reset, which is done right before
@@ -1301,7 +1299,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_err_intr(struct ata_port *ap)
+static void mv_err_intr(struct ata_port *ap, int reset_allowed)
 {
        void __iomem *port_mmio = mv_ap_base(ap);
        u32 edma_err_cause, serr = 0;
@@ -1323,9 +1321,8 @@ static void mv_err_intr(struct ata_port *ap)
        writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
        /* check for fatal here and recover if needed */
-       if (EDMA_ERR_FATAL & edma_err_cause) {
+       if (reset_allowed && (EDMA_ERR_FATAL & edma_err_cause))
                mv_stop_and_reset(ap);
-       }
 }
 
 /**
@@ -1374,12 +1371,12 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                struct ata_port *ap = host_set->ports[port];
                struct mv_port_priv *pp = ap->private_data;
 
-               hard_port = port & MV_PORT_MASK;        /* range 0-3 */
+               hard_port = mv_hardport_from_port(port); /* range 0..3 */
                handled = 0;    /* ensure ata_status is set if handled++ */
 
                /* Note that DEV_IRQ might happen spuriously during EDMA,
-                * and should be ignored in such cases.  We could mask it,
-                * but it's pretty rare and may not be worth the overhead.
+                * and should be ignored in such cases.
+                * The cause of this is still under investigation.
                 */ 
                if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
                        /* EDMA: check for response queue interrupt */
@@ -1393,6 +1390,11 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                                ata_status = readb((void __iomem *)
                                           ap->ioaddr.status_addr);
                                handled = 1;
+                               /* ignore spurious intr if drive still BUSY */
+                               if (ata_status & ATA_BUSY) {
+                                       ata_status = 0;
+                                       handled = 0;
+                               }
                        }
                }
 
@@ -1406,7 +1408,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
                        shift++;        /* skip bit 8 in the HC Main IRQ reg */
                }
                if ((PORT0_ERR << shift) & relevant) {
-                       mv_err_intr(ap);
+                       mv_err_intr(ap, 1);
                        err_mask |= AC_ERR_OTHER;
                        handled = 1;
                }
@@ -1448,6 +1450,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
        struct ata_host_set *host_set = dev_instance;
        unsigned int hc, handled = 0, n_hcs;
        void __iomem *mmio = host_set->mmio_base;
+       struct mv_host_priv *hpriv;
        u32 irq_stat;
 
        irq_stat = readl(mmio + HC_MAIN_IRQ_CAUSE_OFS);
@@ -1469,6 +1472,17 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
                        handled++;
                }
        }
+
+       hpriv = host_set->private_data;
+       if (IS_60XX(hpriv)) {
+               /* deal with the interrupt coalescing bits */
+               if (irq_stat & (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE)) {
+                       writelfl(0, mmio + MV_IRQ_COAL_CAUSE_LO);
+                       writelfl(0, mmio + MV_IRQ_COAL_CAUSE_HI);
+                       writelfl(0, mmio + MV_IRQ_COAL_CAUSE);
+               }
+       }
+
        if (PCI_ERR & irq_stat) {
                printk(KERN_ERR DRV_NAME ": PCI ERROR; PCI IRQ cause=0x%08x\n",
                       readl(mmio + PCI_IRQ_CAUSE_OFS));
@@ -1867,7 +1881,8 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
 
        if (IS_60XX(hpriv)) {
                u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
-               ifctl |= (1 << 12) | (1 << 7);
+               ifctl |= (1 << 7);              /* enable gen2i speed */
+               ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
                writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL);
        }
 
@@ -2031,11 +2046,14 @@ static void mv_eng_timeout(struct ata_port *ap)
               ap->host_set->mmio_base, ap, qc, qc->scsicmd,
               &qc->scsicmd->cmnd);
 
-       mv_err_intr(ap);
+       mv_err_intr(ap, 0);
        mv_stop_and_reset(ap);
 
-       qc->err_mask |= AC_ERR_TIMEOUT;
-       ata_eh_qc_complete(qc);
+       WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
+       if (qc->flags & ATA_QCFLAG_ACTIVE) {
+               qc->err_mask |= AC_ERR_TIMEOUT;
+               ata_eh_qc_complete(qc);
+       }
 }
 
 /**
@@ -2229,7 +2247,8 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
                        void __iomem *port_mmio = mv_port_base(mmio, port);
 
                        u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
-                       ifctl |= (1 << 12);
+                       ifctl |= (1 << 7);              /* enable gen2i speed */
+                       ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
                        writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL);
                }
 
@@ -2330,6 +2349,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc) {
                return rc;
        }
+       pci_set_master(pdev);
 
        rc = pci_request_regions(pdev, DRV_NAME);
        if (rc) {
index d40e7c871c363274ec739314cb159aee32c3bd8a..56cb4900611659380e20cace52d1c395a714656f 100644 (file)
@@ -4054,7 +4054,7 @@ static int st_probe(struct device *dev)
        }
 
        sdev_printk(KERN_WARNING, SDp,
-                   "Attached scsi tape %s", tape_name(tpnt));
+                   "Attached scsi tape %s\n", tape_name(tpnt));
        printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
               tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
               queue_dma_alignment(SDp->request_queue) + 1);
index 969f949004318b1080f16643fd0b07d41f280d53..5cba59ad7dc5a38eff874cbc735ec140bdb2829c 100644 (file)
@@ -1164,14 +1164,16 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
        struct fs_uart_platform_info *pdata;
        struct platform_device* pdev = early_uart_get_pdev(co->index);
 
-       port =
-           (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
-       pinfo = (struct uart_cpm_port *)port;
        if (!pdev) {
                pr_info("cpm_uart: console: compat mode\n");
                /* compatibility - will be cleaned up */
                cpm_uart_init_portdesc();
+       }
 
+       port =
+           (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
+       pinfo = (struct uart_cpm_port *)port;
+       if (!pdev) {
                if (pinfo->set_lineif)
                        pinfo->set_lineif(pinfo);
        } else {
index 4b2de08f46d0ef7f58462e3144326743c3a6390f..cdba128250a96e5f2f98a07c5dcbf2318c65ff92 100644 (file)
@@ -213,7 +213,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
            L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
        if (is_con) {
                mem_addr = alloc_bootmem(memsz);
-               dma_addr = mem_addr;
+               dma_addr = virt_to_bus(mem_addr);
        }
        else
                mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
index 1c4396c2962d0de28ce661921655bd76d2c49820..2b4f96541b8e6a10f25a717c8909a742a0576515 100644 (file)
@@ -1730,3 +1730,4 @@ static void __exit sunsu_exit(void)
 
 module_init(sunsu_probe);
 module_exit(sunsu_exit);
+MODULE_LICENSE("GPL");
index 9ce1d01469b19d3c93e61193bd8bce400b9206a8..23334c8bc4c75e5c29fcf2415267d3c00397425c 100644 (file)
@@ -75,6 +75,18 @@ config SPI_BUTTERFLY
          inexpensive battery powered microcontroller evaluation board.
          This same cable can be used to flash new firmware.
 
+config SPI_MPC83xx
+       tristate "Freescale MPC83xx SPI controller"
+       depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
+       select SPI_BITBANG
+       help
+         This enables using the Freescale MPC83xx SPI controller in master
+         mode.
+
+         Note, this driver uniquely supports the SPI controller on the MPC83xx
+         family of PowerPC processors.  The MPC83xx uses a simple set of shift
+         registers for data (opposed to the CPM based descriptor model).
+
 config SPI_PXA2XX
        tristate "PXA2xx SSP SPI master"
        depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
@@ -83,11 +95,25 @@ config SPI_PXA2XX
          The driver can be configured to use any SSP port and additional
          documentation can be found a Documentation/spi/pxa2xx.
 
+config SPI_S3C24XX_GPIO
+       tristate "Samsung S3C24XX series SPI by GPIO"
+       depends on SPI_MASTER && ARCH_S3C2410 && SPI_BITBANG && EXPERIMENTAL
+       help
+         SPI driver for Samsung S3C24XX series ARM SoCs using
+         GPIO lines to provide the SPI bus. This can be used where
+         the inbuilt hardware cannot provide the transfer mode, or
+         where the board is using non hardware connected pins.
 #
 # Add new SPI master controllers in alphabetical order above this line
 #
 
 
+config SPI_S3C24XX
+       tristate "Samsung S3C24XX series SPI"
+       depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL
+       help
+         SPI driver for Samsung S3C24XX series ARM SoCs
+
 #
 # There are lots of SPI device types, with sensors and memory
 # being probably the most widely used ones.
index 1bca5f95de251d00c4775a8e3898da2751b29102..8f4cb67997b32afcc5207b49fb7ae2dfcb2654eb 100644 (file)
@@ -14,6 +14,9 @@ obj-$(CONFIG_SPI_MASTER)              += spi.o
 obj-$(CONFIG_SPI_BITBANG)              += spi_bitbang.o
 obj-$(CONFIG_SPI_BUTTERFLY)            += spi_butterfly.o
 obj-$(CONFIG_SPI_PXA2XX)               += pxa2xx_spi.o
+obj-$(CONFIG_SPI_MPC83xx)              += spi_mpc83xx.o
+obj-$(CONFIG_SPI_S3C24XX_GPIO)         += spi_s3c24xx_gpio.o
+obj-$(CONFIG_SPI_S3C24XX)              += spi_s3c24xx.o
 #      ... add above this line ...
 
 # SPI protocol drivers (device/link on bus)
index 596bf820b70c655b9720093e81936ec25f393d99..29aec77f98be53a758311f78d71cc86c26ec7a64 100644 (file)
@@ -363,25 +363,30 @@ static void unmap_dma_buffers(struct driver_data *drv_data)
 }
 
 /* caller already set message->status; dma and pio irqs are blocked */
-static void giveback(struct spi_message *message, struct driver_data *drv_data)
+static void giveback(struct driver_data *drv_data)
 {
        struct spi_transfer* last_transfer;
+       unsigned long flags;
+       struct spi_message *msg;
 
-       last_transfer = list_entry(message->transfers.prev,
+       spin_lock_irqsave(&drv_data->lock, flags);
+       msg = drv_data->cur_msg;
+       drv_data->cur_msg = NULL;
+       drv_data->cur_transfer = NULL;
+       drv_data->cur_chip = NULL;
+       queue_work(drv_data->workqueue, &drv_data->pump_messages);
+       spin_unlock_irqrestore(&drv_data->lock, flags);
+
+       last_transfer = list_entry(msg->transfers.prev,
                                        struct spi_transfer,
                                        transfer_list);
 
        if (!last_transfer->cs_change)
                drv_data->cs_control(PXA2XX_CS_DEASSERT);
 
-       message->state = NULL;
-       if (message->complete)
-               message->complete(message->context);
-
-       drv_data->cur_msg = NULL;
-       drv_data->cur_transfer = NULL;
-       drv_data->cur_chip = NULL;
-       queue_work(drv_data->workqueue, &drv_data->pump_messages);
+       msg->state = NULL;
+       if (msg->complete)
+               msg->complete(msg->context);
 }
 
 static int wait_ssp_rx_stall(void *ioaddr)
@@ -415,10 +420,11 @@ static void dma_handler(int channel, void *data, struct pt_regs *regs)
        if (irq_status & DCSR_BUSERR) {
 
                /* Disable interrupts, clear status and reset DMA */
+               write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
+               write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
                if (drv_data->ssp_type != PXA25x_SSP)
                        write_SSTO(0, reg);
                write_SSSR(drv_data->clear_sr, reg);
-               write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
                DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
                DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
 
@@ -454,8 +460,8 @@ static void dma_handler(int channel, void *data, struct pt_regs *regs)
                                "dma_handler: ssp rx stall failed\n");
 
                /* Clear and disable interrupts on SSP and DMA channels*/
-               write_SSSR(drv_data->clear_sr, reg);
                write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
+               write_SSSR(drv_data->clear_sr, reg);
                DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
                DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
                if (wait_dma_channel_stop(drv_data->rx_channel) == 0)
@@ -497,10 +503,11 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
        irq_status = read_SSSR(reg) & drv_data->mask_sr;
        if (irq_status & SSSR_ROR) {
                /* Clear and disable interrupts on SSP and DMA channels*/
+               write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
+               write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
                if (drv_data->ssp_type != PXA25x_SSP)
                        write_SSTO(0, reg);
                write_SSSR(drv_data->clear_sr, reg);
-               write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
                DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
                DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
                unmap_dma_buffers(drv_data);
@@ -526,10 +533,10 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
        if (irq_status & SSSR_TINT || drv_data->rx == drv_data->rx_end) {
 
                /* Clear and disable interrupts on SSP and DMA channels*/
+               write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
                if (drv_data->ssp_type != PXA25x_SSP)
                        write_SSTO(0, reg);
                write_SSSR(drv_data->clear_sr, reg);
-               write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
                DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
                DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
 
@@ -572,26 +579,30 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
 
 static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 {
-       u32 irq_status;
        struct spi_message *msg = drv_data->cur_msg;
        void *reg = drv_data->ioaddr;
-       irqreturn_t handled = IRQ_NONE;
        unsigned long limit = loops_per_jiffy << 1;
+       u32 irq_status;
+       u32 irq_mask = (read_SSCR1(reg) & SSCR1_TIE) ?
+                       drv_data->mask_sr : drv_data->mask_sr & ~SSSR_TFS;
 
-       while ((irq_status = (read_SSSR(reg) & drv_data->mask_sr))) {
+       while ((irq_status = read_SSSR(reg) & irq_mask)) {
 
                if (irq_status & SSSR_ROR) {
 
                        /* Clear and disable interrupts */
+                       write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
+                       write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
                        if (drv_data->ssp_type != PXA25x_SSP)
                                write_SSTO(0, reg);
                        write_SSSR(drv_data->clear_sr, reg);
-                       write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
 
                        if (flush(drv_data) == 0)
                                dev_err(&drv_data->pdev->dev,
                                        "interrupt_transfer: flush fail\n");
 
+                       /* Stop the SSP */
+
                        dev_warn(&drv_data->pdev->dev,
                                        "interrupt_transfer: fifo overun\n");
 
@@ -613,6 +624,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
                if (drv_data->tx == drv_data->tx_end) {
                        /* Disable tx interrupt */
                        write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg);
+                       irq_mask = drv_data->mask_sr & ~SSSR_TFS;
 
                        /* PXA25x_SSP has no timeout, read trailing bytes */
                        if (drv_data->ssp_type == PXA25x_SSP) {
@@ -630,10 +642,10 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
                                || (drv_data->rx == drv_data->rx_end)) {
 
                        /* Clear timeout */
+                       write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
                        if (drv_data->ssp_type != PXA25x_SSP)
                                write_SSTO(0, reg);
                        write_SSSR(drv_data->clear_sr, reg);
-                       write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
 
                        /* Update total byte transfered */
                        msg->actual_length += drv_data->len;
@@ -648,24 +660,29 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 
                        /* Schedule transfer tasklet */
                        tasklet_schedule(&drv_data->pump_transfers);
-
-                       return IRQ_HANDLED;
                }
-
-               /* We did something */
-               handled = IRQ_HANDLED;
        }
 
-       return handled;
+       /* We did something */
+       return IRQ_HANDLED;
 }
 
 static irqreturn_t ssp_int(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct driver_data *drv_data = (struct driver_data *)dev_id;
+       void *reg = drv_data->ioaddr;
 
        if (!drv_data->cur_msg) {
+
+               write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
+               write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg);
+               if (drv_data->ssp_type != PXA25x_SSP)
+                       write_SSTO(0, reg);
+               write_SSSR(drv_data->clear_sr, reg);
+
                dev_err(&drv_data->pdev->dev, "bad message state "
-                               "in interrupt handler\n");
+                               "in interrupt handler");
+
                /* Never fail */
                return IRQ_HANDLED;
        }
@@ -694,14 +711,14 @@ static void pump_transfers(unsigned long data)
        /* Handle for abort */
        if (message->state == ERROR_STATE) {
                message->status = -EIO;
-               giveback(message, drv_data);
+               giveback(drv_data);
                return;
        }
 
        /* Handle end of message */
        if (message->state == DONE_STATE) {
                message->status = 0;
-               giveback(message, drv_data);
+               giveback(drv_data);
                return;
        }
 
@@ -718,7 +735,7 @@ static void pump_transfers(unsigned long data)
        if (flush(drv_data) == 0) {
                dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n");
                message->status = -EIO;
-               giveback(message, drv_data);
+               giveback(drv_data);
                return;
        }
        drv_data->n_bytes = chip->n_bytes;
@@ -782,7 +799,7 @@ static void pump_transfers(unsigned long data)
 
                cr0 = clk_div
                        | SSCR0_Motorola
-                       | SSCR0_DataSize(bits & 0x0f)
+                       | SSCR0_DataSize(bits > 16 ? bits - 16 : bits)
                        | SSCR0_SSE
                        | (bits > 16 ? SSCR0_EDSS : 0);
 
@@ -890,8 +907,6 @@ static void pump_messages(void *data)
        drv_data->cur_msg = list_entry(drv_data->queue.next,
                                        struct spi_message, queue);
        list_del_init(&drv_data->cur_msg->queue);
-       drv_data->busy = 1;
-       spin_unlock_irqrestore(&drv_data->lock, flags);
 
        /* Initial message state*/
        drv_data->cur_msg->state = START_STATE;
@@ -905,6 +920,9 @@ static void pump_messages(void *data)
 
        /* Mark as busy and launch transfers */
        tasklet_schedule(&drv_data->pump_transfers);
+
+       drv_data->busy = 1;
+       spin_unlock_irqrestore(&drv_data->lock, flags);
 }
 
 static int transfer(struct spi_device *spi, struct spi_message *msg)
@@ -958,7 +976,7 @@ static int setup(struct spi_device *spi)
 
                chip->cs_control = null_cs_control;
                chip->enable_dma = 0;
-               chip->timeout = 5;
+               chip->timeout = SSP_TIMEOUT(1000);
                chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
                chip->dma_burst_size = drv_data->master_info->enable_dma ?
                                        DCMD_BURST8 : 0;
@@ -971,7 +989,7 @@ static int setup(struct spi_device *spi)
                if (chip_info->cs_control)
                        chip->cs_control = chip_info->cs_control;
 
-               chip->timeout = (chip_info->timeout_microsecs * 10000) / 2712;
+               chip->timeout = SSP_TIMEOUT(chip_info->timeout_microsecs);
 
                chip->threshold = SSCR1_RxTresh(chip_info->rx_threshold)
                                        | SSCR1_TxTresh(chip_info->tx_threshold);
@@ -1013,7 +1031,8 @@ static int setup(struct spi_device *spi)
 
        chip->cr0 = clk_div
                        | SSCR0_Motorola
-                       | SSCR0_DataSize(spi->bits_per_word & 0x0f)
+                       | SSCR0_DataSize(spi->bits_per_word > 16 ?
+                               spi->bits_per_word - 16 : spi->bits_per_word)
                        | SSCR0_SSE
                        | (spi->bits_per_word > 16 ? SSCR0_EDSS : 0);
        chip->cr1 |= (((spi->mode & SPI_CPHA) != 0) << 4)
@@ -1196,7 +1215,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
                goto out_error_master_alloc;
        }
 
-       drv_data->ioaddr = (void *)io_p2v(memory_resource->start);
+       drv_data->ioaddr = (void *)io_p2v((unsigned long)(memory_resource->start));
        drv_data->ssdr_physical = memory_resource->start + 0x00000010;
        if (platform_info->ssp_type == PXA25x_SSP) {
                drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE;
@@ -1218,7 +1237,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
                goto out_error_master_alloc;
        }
 
-       status = request_irq(irq, ssp_int, SA_INTERRUPT, dev->bus_id, drv_data);
+       status = request_irq(irq, ssp_int, 0, dev->bus_id, drv_data);
        if (status < 0) {
                dev_err(&pdev->dev, "can not get IRQ\n");
                goto out_error_master_alloc;
index 7a3f733051e9ce8a2c6102fcf7ddd9add2d620b6..1cea4a6799fe66c3e6fd94eaf56b3ed52b13e2cb 100644 (file)
@@ -338,18 +338,18 @@ static struct class spi_master_class = {
  * spi_alloc_master - allocate SPI master controller
  * @dev: the controller, possibly using the platform_bus
  * @size: how much driver-private data to preallocate; the pointer to this
- *     memory is in the class_data field of the returned class_device,
+ *     memory is in the class_data field of the returned class_device,
  *     accessible with spi_master_get_devdata().
  *
  * This call is used only by SPI master controller drivers, which are the
  * only ones directly touching chip registers.  It's how they allocate
- * an spi_master structure, prior to calling spi_add_master().
+ * an spi_master structure, prior to calling spi_register_master().
  *
  * This must be called from context that can sleep.  It returns the SPI
  * master structure on success, else NULL.
  *
  * The caller is responsible for assigning the bus number and initializing
- * the master's methods before calling spi_add_master(); and (after errors
+ * the master's methods before calling spi_register_master(); and (after errors
  * adding the device) calling spi_master_put() to prevent a memory leak.
  */
 struct spi_master * __init_or_module
index ff9e5faa4dc9f369ec30e829279646547f1fba73..a006a1ee27acb6f4ca59f4a89693673650a84e86 100644 (file)
@@ -321,6 +321,7 @@ static void butterfly_attach(struct parport *p)
         * (firmware resets at45, acts as spi slave) or neither (we ignore
         * both, AVR uses AT45).  Here we expect firmware for the first option.
         */
+
        pp->info[0].max_speed_hz = 15 * 1000 * 1000;
        strcpy(pp->info[0].modalias, "mtd_dataflash");
        pp->info[0].platform_data = &flash;
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
new file mode 100644 (file)
index 0000000..5d92a7e
--- /dev/null
@@ -0,0 +1,483 @@
+/*
+ * MPC83xx SPI controller driver.
+ *
+ * Maintainer: Kumar Gala
+ *
+ * Copyright (C) 2006 Polycom, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+
+/* SPI Controller registers */
+struct mpc83xx_spi_reg {
+       u8 res1[0x20];
+       __be32 mode;
+       __be32 event;
+       __be32 mask;
+       __be32 command;
+       __be32 transmit;
+       __be32 receive;
+};
+
+/* SPI Controller mode register definitions */
+#define        SPMODE_CI_INACTIVEHIGH  (1 << 29)
+#define        SPMODE_CP_BEGIN_EDGECLK (1 << 28)
+#define        SPMODE_DIV16            (1 << 27)
+#define        SPMODE_REV              (1 << 26)
+#define        SPMODE_MS               (1 << 25)
+#define        SPMODE_ENABLE           (1 << 24)
+#define        SPMODE_LEN(x)           ((x) << 20)
+#define        SPMODE_PM(x)            ((x) << 16)
+
+/*
+ * Default for SPI Mode:
+ *     SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk
+ */
+#define        SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \
+                        SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf))
+
+/* SPIE register values */
+#define        SPIE_NE         0x00000200      /* Not empty */
+#define        SPIE_NF         0x00000100      /* Not full */
+
+/* SPIM register values */
+#define        SPIM_NE         0x00000200      /* Not empty */
+#define        SPIM_NF         0x00000100      /* Not full */
+
+/* SPI Controller driver's private data. */
+struct mpc83xx_spi {
+       /* bitbang has to be first */
+       struct spi_bitbang bitbang;
+       struct completion done;
+
+       struct mpc83xx_spi_reg __iomem *base;
+
+       /* rx & tx bufs from the spi_transfer */
+       const void *tx;
+       void *rx;
+
+       /* functions to deal with different sized buffers */
+       void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
+       u32(*get_tx) (struct mpc83xx_spi *);
+
+       unsigned int count;
+       u32 irq;
+
+       unsigned nsecs;         /* (clock cycle time)/2 */
+
+       u32 sysclk;
+       void (*activate_cs) (u8 cs, u8 polarity);
+       void (*deactivate_cs) (u8 cs, u8 polarity);
+};
+
+static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val)
+{
+       out_be32(reg, val);
+}
+
+static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg)
+{
+       return in_be32(reg);
+}
+
+#define MPC83XX_SPI_RX_BUF(type)                                         \
+void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
+{                                                                        \
+       type * rx = mpc83xx_spi->rx;                                      \
+       *rx++ = (type)data;                                               \
+       mpc83xx_spi->rx = rx;                                             \
+}
+
+#define MPC83XX_SPI_TX_BUF(type)                               \
+u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \
+{                                                              \
+       u32 data;                                               \
+       const type * tx = mpc83xx_spi->tx;                      \
+       data = *tx++;                                           \
+       mpc83xx_spi->tx = tx;                                   \
+       return data;                                            \
+}
+
+MPC83XX_SPI_RX_BUF(u8)
+MPC83XX_SPI_RX_BUF(u16)
+MPC83XX_SPI_RX_BUF(u32)
+MPC83XX_SPI_TX_BUF(u8)
+MPC83XX_SPI_TX_BUF(u16)
+MPC83XX_SPI_TX_BUF(u32)
+
+static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
+{
+       struct mpc83xx_spi *mpc83xx_spi;
+       u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+
+       mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+       if (value == BITBANG_CS_INACTIVE) {
+               if (mpc83xx_spi->deactivate_cs)
+                       mpc83xx_spi->deactivate_cs(spi->chip_select, pol);
+       }
+
+       if (value == BITBANG_CS_ACTIVE) {
+               u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+               u32 len = spi->bits_per_word;
+               if (len == 32)
+                       len = 0;
+               else
+                       len = len - 1;
+
+               /* mask out bits we are going to set */
+               regval &= ~0x38ff0000;
+
+               if (spi->mode & SPI_CPHA)
+                       regval |= SPMODE_CP_BEGIN_EDGECLK;
+               if (spi->mode & SPI_CPOL)
+                       regval |= SPMODE_CI_INACTIVEHIGH;
+
+               regval |= SPMODE_LEN(len);
+
+               if ((mpc83xx_spi->sysclk / spi->max_speed_hz) >= 64) {
+                       u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 64);
+                       regval |= SPMODE_PM(pm) | SPMODE_DIV16;
+               } else {
+                       u8 pm = mpc83xx_spi->sysclk / (spi->max_speed_hz * 4);
+                       regval |= SPMODE_PM(pm);
+               }
+
+               mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+               if (mpc83xx_spi->activate_cs)
+                       mpc83xx_spi->activate_cs(spi->chip_select, pol);
+       }
+}
+
+static
+int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+{
+       struct mpc83xx_spi *mpc83xx_spi;
+       u32 regval;
+       u8 bits_per_word;
+       u32 hz;
+
+       mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+       if (t) {
+               bits_per_word = t->bits_per_word;
+               hz = t->speed_hz;
+       } else {
+               bits_per_word = 0;
+               hz = 0;
+       }
+
+       /* spi_transfer level calls that work per-word */
+       if (!bits_per_word)
+               bits_per_word = spi->bits_per_word;
+
+       /* Make sure its a bit width we support [4..16, 32] */
+       if ((bits_per_word < 4)
+           || ((bits_per_word > 16) && (bits_per_word != 32)))
+               return -EINVAL;
+
+       if (bits_per_word <= 8) {
+               mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
+               mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
+       } else if (bits_per_word <= 16) {
+               mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16;
+               mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16;
+       } else if (bits_per_word <= 32) {
+               mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32;
+               mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32;
+       } else
+               return -EINVAL;
+
+       /* nsecs = (clock period)/2 */
+       if (!hz)
+               hz = spi->max_speed_hz;
+       mpc83xx_spi->nsecs = (1000000000 / 2) / hz;
+       if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000)
+               return -EINVAL;
+
+       if (bits_per_word == 32)
+               bits_per_word = 0;
+       else
+               bits_per_word = bits_per_word - 1;
+
+       regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
+
+       /* Mask out bits_per_wordgth */
+       regval &= 0xff0fffff;
+       regval |= SPMODE_LEN(bits_per_word);
+
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+
+       return 0;
+}
+
+static int mpc83xx_spi_setup(struct spi_device *spi)
+{
+       struct spi_bitbang *bitbang;
+       struct mpc83xx_spi *mpc83xx_spi;
+       int retval;
+
+       if (!spi->max_speed_hz)
+               return -EINVAL;
+
+       bitbang = spi_master_get_devdata(spi->master);
+       mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+       if (!spi->bits_per_word)
+               spi->bits_per_word = 8;
+
+       retval = mpc83xx_spi_setup_transfer(spi, NULL);
+       if (retval < 0)
+               return retval;
+
+       dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
+               __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
+               spi->bits_per_word, 2 * mpc83xx_spi->nsecs);
+
+       /* NOTE we _need_ to call chipselect() early, ideally with adapter
+        * setup, unless the hardware defaults cooperate to avoid confusion
+        * between normal (active low) and inverted chipselects.
+        */
+
+       /* deselect chip (low or high) */
+       spin_lock(&bitbang->lock);
+       if (!bitbang->busy) {
+               bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
+               ndelay(mpc83xx_spi->nsecs);
+       }
+       spin_unlock(&bitbang->lock);
+
+       return 0;
+}
+
+static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
+{
+       struct mpc83xx_spi *mpc83xx_spi;
+       u32 word;
+
+       mpc83xx_spi = spi_master_get_devdata(spi->master);
+
+       mpc83xx_spi->tx = t->tx_buf;
+       mpc83xx_spi->rx = t->rx_buf;
+       mpc83xx_spi->count = t->len;
+       INIT_COMPLETION(mpc83xx_spi->done);
+
+       /* enable rx ints */
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);
+
+       /* transmit word */
+       word = mpc83xx_spi->get_tx(mpc83xx_spi);
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
+
+       wait_for_completion(&mpc83xx_spi->done);
+
+       /* disable rx ints */
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+
+       return t->len - mpc83xx_spi->count;
+}
+
+irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data,
+                           struct pt_regs * ptregs)
+{
+       struct mpc83xx_spi *mpc83xx_spi = context_data;
+       u32 event;
+       irqreturn_t ret = IRQ_NONE;
+
+       /* Get interrupt events(tx/rx) */
+       event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event);
+
+       /* We need handle RX first */
+       if (event & SPIE_NE) {
+               u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive);
+
+               if (mpc83xx_spi->rx)
+                       mpc83xx_spi->get_rx(rx_data, mpc83xx_spi);
+
+               ret = IRQ_HANDLED;
+       }
+
+       if ((event & SPIE_NF) == 0)
+               /* spin until TX is done */
+               while (((event =
+                        mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) &
+                                               SPIE_NF) == 0)
+                        cpu_relax();
+
+       mpc83xx_spi->count -= 1;
+       if (mpc83xx_spi->count) {
+               if (mpc83xx_spi->tx) {
+                       u32 word = mpc83xx_spi->get_tx(mpc83xx_spi);
+                       mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit,
+                                             word);
+               }
+       } else {
+               complete(&mpc83xx_spi->done);
+       }
+
+       /* Clear the events */
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event);
+
+       return ret;
+}
+
+static int __init mpc83xx_spi_probe(struct platform_device *dev)
+{
+       struct spi_master *master;
+       struct mpc83xx_spi *mpc83xx_spi;
+       struct fsl_spi_platform_data *pdata;
+       struct resource *r;
+       u32 regval;
+       int ret = 0;
+
+       /* Get resources(memory, IRQ) associated with the device */
+       master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi));
+
+       if (master == NULL) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       platform_set_drvdata(dev, master);
+       pdata = dev->dev.platform_data;
+
+       if (pdata == NULL) {
+               ret = -ENODEV;
+               goto free_master;
+       }
+
+       r = platform_get_resource(dev, IORESOURCE_MEM, 0);
+       if (r == NULL) {
+               ret = -ENODEV;
+               goto free_master;
+       }
+
+       mpc83xx_spi = spi_master_get_devdata(master);
+       mpc83xx_spi->bitbang.master = spi_master_get(master);
+       mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
+       mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer;
+       mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs;
+       mpc83xx_spi->sysclk = pdata->sysclk;
+       mpc83xx_spi->activate_cs = pdata->activate_cs;
+       mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
+       mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
+       mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
+
+       mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup;
+       init_completion(&mpc83xx_spi->done);
+
+       mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
+       if (mpc83xx_spi->base == NULL) {
+               ret = -ENOMEM;
+               goto put_master;
+       }
+
+       mpc83xx_spi->irq = platform_get_irq(dev, 0);
+
+       if (mpc83xx_spi->irq < 0) {
+               ret = -ENXIO;
+               goto unmap_io;
+       }
+
+       /* Register for SPI Interrupt */
+       ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
+                         0, "mpc83xx_spi", mpc83xx_spi);
+
+       if (ret != 0)
+               goto unmap_io;
+
+       master->bus_num = pdata->bus_num;
+       master->num_chipselect = pdata->max_chipselect;
+
+       /* SPI controller initializations */
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0);
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff);
+
+       /* Enable SPI interface */
+       regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
+       mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
+
+       ret = spi_bitbang_start(&mpc83xx_spi->bitbang);
+
+       if (ret != 0)
+               goto free_irq;
+
+       printk(KERN_INFO
+              "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
+              dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq);
+
+       return ret;
+
+free_irq:
+       free_irq(mpc83xx_spi->irq, mpc83xx_spi);
+unmap_io:
+       iounmap(mpc83xx_spi->base);
+put_master:
+       spi_master_put(master);
+free_master:
+       kfree(master);
+err:
+       return ret;
+}
+
+static int __devexit mpc83xx_spi_remove(struct platform_device *dev)
+{
+       struct mpc83xx_spi *mpc83xx_spi;
+       struct spi_master *master;
+
+       master = platform_get_drvdata(dev);
+       mpc83xx_spi = spi_master_get_devdata(master);
+
+       spi_bitbang_stop(&mpc83xx_spi->bitbang);
+       free_irq(mpc83xx_spi->irq, mpc83xx_spi);
+       iounmap(mpc83xx_spi->base);
+       spi_master_put(mpc83xx_spi->bitbang.master);
+
+       return 0;
+}
+
+static struct platform_driver mpc83xx_spi_driver = {
+       .probe = mpc83xx_spi_probe,
+       .remove = __devexit_p(mpc83xx_spi_remove),
+       .driver = {
+                  .name = "mpc83xx_spi",
+       },
+};
+
+static int __init mpc83xx_spi_init(void)
+{
+       return platform_driver_register(&mpc83xx_spi_driver);
+}
+
+static void __exit mpc83xx_spi_exit(void)
+{
+       platform_driver_unregister(&mpc83xx_spi_driver);
+}
+
+module_init(mpc83xx_spi_init);
+module_exit(mpc83xx_spi_exit);
+
+MODULE_AUTHOR("Kumar Gala");
+MODULE_DESCRIPTION("Simple MPC83xx SPI Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
new file mode 100644 (file)
index 0000000..5fc1456
--- /dev/null
@@ -0,0 +1,453 @@
+/* linux/drivers/spi/spi_s3c24xx.c
+ *
+ * Copyright (c) 2006 Ben Dooks
+ * Copyright (c) 2006 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.
+ *
+*/
+
+
+//#define DEBUG
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/hardware.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/regs-spi.h>
+#include <asm/arch/spi.h>
+
+struct s3c24xx_spi {
+       /* bitbang has to be first */
+       struct spi_bitbang       bitbang;
+       struct completion        done;
+
+       void __iomem            *regs;
+       int                      irq;
+       int                      len;
+       int                      count;
+
+       /* data buffers */
+       const unsigned char     *tx;
+       unsigned char           *rx;
+
+       struct clk              *clk;
+       struct resource         *ioarea;
+       struct spi_master       *master;
+       struct spi_device       *curdev;
+       struct device           *dev;
+       struct s3c2410_spi_info *pdata;
+};
+
+#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT)
+#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP)
+
+static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev)
+{
+       return spi_master_get_devdata(sdev->master);
+}
+
+static void s3c24xx_spi_chipsel(struct spi_device *spi, int value)
+{
+       struct s3c24xx_spi *hw = to_hw(spi);
+       unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
+       unsigned int spcon;
+
+       switch (value) {
+       case BITBANG_CS_INACTIVE:
+               if (hw->pdata->set_cs)
+                       hw->pdata->set_cs(hw->pdata, value, cspol);
+               else
+                       s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol ^ 1);
+               break;
+
+       case BITBANG_CS_ACTIVE:
+               spcon = readb(hw->regs + S3C2410_SPCON);
+
+               if (spi->mode & SPI_CPHA)
+                       spcon |= S3C2410_SPCON_CPHA_FMTB;
+               else
+                       spcon &= ~S3C2410_SPCON_CPHA_FMTB;
+
+               if (spi->mode & SPI_CPOL)
+                       spcon |= S3C2410_SPCON_CPOL_HIGH;
+               else
+                       spcon &= ~S3C2410_SPCON_CPOL_HIGH;
+
+               spcon |= S3C2410_SPCON_ENSCK;
+
+               /* write new configration */
+
+               writeb(spcon, hw->regs + S3C2410_SPCON);
+
+               if (hw->pdata->set_cs)
+                       hw->pdata->set_cs(hw->pdata, value, cspol);
+               else
+                       s3c2410_gpio_setpin(hw->pdata->pin_cs, cspol);
+
+               break;
+
+       }
+}
+
+static int s3c24xx_spi_setupxfer(struct spi_device *spi,
+                                struct spi_transfer *t)
+{
+       struct s3c24xx_spi *hw = to_hw(spi);
+       unsigned int bpw;
+       unsigned int hz;
+       unsigned int div;
+
+       bpw = t ? t->bits_per_word : spi->bits_per_word;
+       hz  = t ? t->speed_hz : spi->max_speed_hz;
+
+       if (bpw != 8) {
+               dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw);
+               return -EINVAL;
+       }
+
+       div = clk_get_rate(hw->clk) / hz;
+
+       /* is clk = pclk / (2 * (pre+1)), or is it
+        *    clk = (pclk * 2) / ( pre + 1) */
+
+       div = (div / 2) - 1;
+
+       if (div < 0)
+               div = 1;
+
+       if (div > 255)
+               div = 255;
+
+       dev_dbg(&spi->dev, "setting pre-scaler to %d (hz %d)\n", div, hz);
+       writeb(div, hw->regs + S3C2410_SPPRE);
+
+       spin_lock(&hw->bitbang.lock);
+       if (!hw->bitbang.busy) {
+               hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE);
+               /* need to ndelay for 0.5 clocktick ? */
+       }
+       spin_unlock(&hw->bitbang.lock);
+
+       return 0;
+}
+
+static int s3c24xx_spi_setup(struct spi_device *spi)
+{
+       int ret;
+
+       if (!spi->bits_per_word)
+               spi->bits_per_word = 8;
+
+       if ((spi->mode & SPI_LSB_FIRST) != 0)
+               return -EINVAL;
+
+       ret = s3c24xx_spi_setupxfer(spi, NULL);
+       if (ret < 0) {
+               dev_err(&spi->dev, "setupxfer returned %d\n", ret);
+               return ret;
+       }
+
+       dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n",
+               __FUNCTION__, spi->mode, spi->bits_per_word,
+               spi->max_speed_hz);
+
+       return 0;
+}
+
+static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count)
+{
+       return hw->tx ? hw->tx[count] : 0xff;
+}
+
+static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
+{
+       struct s3c24xx_spi *hw = to_hw(spi);
+
+       dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
+               t->tx_buf, t->rx_buf, t->len);
+
+       hw->tx = t->tx_buf;
+       hw->rx = t->rx_buf;
+       hw->len = t->len;
+       hw->count = 0;
+
+       /* send the first byte */
+       writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
+       wait_for_completion(&hw->done);
+
+       return hw->count;
+}
+
+static irqreturn_t s3c24xx_spi_irq(int irq, void *dev, struct pt_regs *regs)
+{
+       struct s3c24xx_spi *hw = dev;
+       unsigned int spsta = readb(hw->regs + S3C2410_SPSTA);
+       unsigned int count = hw->count;
+
+       if (spsta & S3C2410_SPSTA_DCOL) {
+               dev_dbg(hw->dev, "data-collision\n");
+               complete(&hw->done);
+               goto irq_done;
+       }
+
+       if (!(spsta & S3C2410_SPSTA_READY)) {
+               dev_dbg(hw->dev, "spi not ready for tx?\n");
+               complete(&hw->done);
+               goto irq_done;
+       }
+
+       hw->count++;
+
+       if (hw->rx)
+               hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
+
+       count++;
+
+       if (count < hw->len)
+               writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT);
+       else
+               complete(&hw->done);
+
+ irq_done:
+       return IRQ_HANDLED;
+}
+
+static int s3c24xx_spi_probe(struct platform_device *pdev)
+{
+       struct s3c24xx_spi *hw;
+       struct spi_master *master;
+       struct spi_board_info *bi;
+       struct resource *res;
+       int err = 0;
+       int i;
+
+       master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
+       if (master == NULL) {
+               dev_err(&pdev->dev, "No memory for spi_master\n");
+               err = -ENOMEM;
+               goto err_nomem;
+       }
+
+       hw = spi_master_get_devdata(master);
+       memset(hw, 0, sizeof(struct s3c24xx_spi));
+
+       hw->master = spi_master_get(master);
+       hw->pdata = pdev->dev.platform_data;
+       hw->dev = &pdev->dev;
+
+       if (hw->pdata == NULL) {
+               dev_err(&pdev->dev, "No platform data supplied\n");
+               err = -ENOENT;
+               goto err_no_pdata;
+       }
+
+       platform_set_drvdata(pdev, hw);
+       init_completion(&hw->done);
+
+       /* setup the state for the bitbang driver */
+
+       hw->bitbang.master         = hw->master;
+       hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer;
+       hw->bitbang.chipselect     = s3c24xx_spi_chipsel;
+       hw->bitbang.txrx_bufs      = s3c24xx_spi_txrx;
+       hw->bitbang.master->setup  = s3c24xx_spi_setup;
+
+       dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
+
+       /* find and map our resources */
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");
+               err = -ENOENT;
+               goto err_no_iores;
+       }
+
+       hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1,
+                                       pdev->name);
+
+       if (hw->ioarea == NULL) {
+               dev_err(&pdev->dev, "Cannot reserve region\n");
+               err = -ENXIO;
+               goto err_no_iores;
+       }
+
+       hw->regs = ioremap(res->start, (res->end - res->start)+1);
+       if (hw->regs == NULL) {
+               dev_err(&pdev->dev, "Cannot map IO\n");
+               err = -ENXIO;
+               goto err_no_iomap;
+       }
+
+       hw->irq = platform_get_irq(pdev, 0);
+       if (hw->irq < 0) {
+               dev_err(&pdev->dev, "No IRQ specified\n");
+               err = -ENOENT;
+               goto err_no_irq;
+       }
+
+       err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw);
+       if (err) {
+               dev_err(&pdev->dev, "Cannot claim IRQ\n");
+               goto err_no_irq;
+       }
+
+       hw->clk = clk_get(&pdev->dev, "spi");
+       if (IS_ERR(hw->clk)) {
+               dev_err(&pdev->dev, "No clock for device\n");
+               err = PTR_ERR(hw->clk);
+               goto err_no_clk;
+       }
+
+       /* for the moment, permanently enable the clock */
+
+       clk_enable(hw->clk);
+
+       /* program defaults into the registers */
+
+       writeb(0xff, hw->regs + S3C2410_SPPRE);
+       writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
+       writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);
+
+       /* setup any gpio we can */
+
+       if (!hw->pdata->set_cs) {
+               s3c2410_gpio_setpin(hw->pdata->pin_cs, 1);
+               s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT);
+       }
+
+       /* register our spi controller */
+
+       err = spi_bitbang_start(&hw->bitbang);
+       if (err) {
+               dev_err(&pdev->dev, "Failed to register SPI master\n");
+               goto err_register;
+       }
+
+       dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown);
+
+       /* register all the devices associated */
+
+       bi = &hw->pdata->board_info[0];
+       for (i = 0; i < hw->pdata->board_size; i++, bi++) {
+               dev_info(hw->dev, "registering %s\n", bi->modalias);
+
+               bi->controller_data = hw;
+               spi_new_device(master, bi);
+       }
+
+       return 0;
+
+ err_register:
+       clk_disable(hw->clk);
+       clk_put(hw->clk);
+
+ err_no_clk:
+       free_irq(hw->irq, hw);
+
+ err_no_irq:
+       iounmap(hw->regs);
+
+ err_no_iomap:
+       release_resource(hw->ioarea);
+       kfree(hw->ioarea);
+
+ err_no_iores:
+ err_no_pdata:
+       spi_master_put(hw->master);;
+
+ err_nomem:
+       return err;
+}
+
+static int s3c24xx_spi_remove(struct platform_device *dev)
+{
+       struct s3c24xx_spi *hw = platform_get_drvdata(dev);
+
+       platform_set_drvdata(dev, NULL);
+
+       spi_unregister_master(hw->master);
+
+       clk_disable(hw->clk);
+       clk_put(hw->clk);
+
+       free_irq(hw->irq, hw);
+       iounmap(hw->regs);
+
+       release_resource(hw->ioarea);
+       kfree(hw->ioarea);
+
+       spi_master_put(hw->master);
+       return 0;
+}
+
+
+#ifdef CONFIG_PM
+
+static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+       struct s3c24xx_spi *hw = platform_get_drvdata(pdev);
+
+       clk_disable(hw->clk);
+       return 0;
+}
+
+static int s3c24xx_spi_resume(struct platform_device *pdev)
+{
+       struct s3c24xx_spi *hw = platform_get_drvdata(pdev);
+
+       clk_enable(hw->clk);
+       return 0;
+}
+
+#else
+#define s3c24xx_spi_suspend NULL
+#define s3c24xx_spi_resume  NULL
+#endif
+
+static struct platform_driver s3c24xx_spidrv = {
+       .probe          = s3c24xx_spi_probe,
+       .remove         = s3c24xx_spi_remove,
+       .suspend        = s3c24xx_spi_suspend,
+       .resume         = s3c24xx_spi_resume,
+       .driver         = {
+               .name   = "s3c2410-spi",
+               .owner  = THIS_MODULE,
+       },
+};
+
+static int __init s3c24xx_spi_init(void)
+{
+        return platform_driver_register(&s3c24xx_spidrv);
+}
+
+static void __exit s3c24xx_spi_exit(void)
+{
+        platform_driver_unregister(&s3c24xx_spidrv);
+}
+
+module_init(s3c24xx_spi_init);
+module_exit(s3c24xx_spi_exit);
+
+MODULE_DESCRIPTION("S3C24XX SPI Driver");
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c
new file mode 100644 (file)
index 0000000..aacdceb
--- /dev/null
@@ -0,0 +1,188 @@
+/* linux/drivers/spi/spi_s3c24xx_gpio.c
+ *
+ * Copyright (c) 2006 Ben Dooks
+ * Copyright (c) 2006 Simtec Electronics
+ *
+ * S3C24XX GPIO based SPI driver
+ *
+ * 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/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include <asm/arch/regs-gpio.h>
+#include <asm/arch/spi-gpio.h>
+#include <asm/arch/hardware.h>
+
+struct s3c2410_spigpio {
+       struct spi_bitbang               bitbang;
+
+       struct s3c2410_spigpio_info     *info;
+       struct platform_device          *dev;
+};
+
+static inline struct s3c2410_spigpio *spidev_to_sg(struct spi_device *spi)
+{
+       return spi->controller_data;
+}
+
+static inline void setsck(struct spi_device *dev, int on)
+{
+       struct s3c2410_spigpio *sg = spidev_to_sg(dev);
+       s3c2410_gpio_setpin(sg->info->pin_clk, on ? 1 : 0);
+}
+
+static inline void setmosi(struct spi_device *dev, int on)
+{
+       struct s3c2410_spigpio *sg = spidev_to_sg(dev);
+       s3c2410_gpio_setpin(sg->info->pin_mosi, on ? 1 : 0);
+}
+
+static inline u32 getmiso(struct spi_device *dev)
+{
+       struct s3c2410_spigpio *sg = spidev_to_sg(dev);
+       return s3c2410_gpio_getpin(sg->info->pin_miso) ? 1 : 0;
+}
+
+#define spidelay(x) ndelay(x)
+
+#define        EXPAND_BITBANG_TXRX
+#include <linux/spi/spi_bitbang.h>
+
+
+static u32 s3c2410_spigpio_txrx_mode0(struct spi_device *spi,
+                                     unsigned nsecs, u32 word, u8 bits)
+{
+       return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+}
+
+static u32 s3c2410_spigpio_txrx_mode1(struct spi_device *spi,
+                                     unsigned nsecs, u32 word, u8 bits)
+{
+       return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
+}
+
+static void s3c2410_spigpio_chipselect(struct spi_device *dev, int value)
+{
+       struct s3c2410_spigpio *sg = spidev_to_sg(dev);
+
+       if (sg->info && sg->info->chip_select)
+               (sg->info->chip_select)(sg->info, value);
+}
+
+static int s3c2410_spigpio_probe(struct platform_device *dev)
+{
+       struct spi_master       *master;
+       struct s3c2410_spigpio  *sp;
+       int ret;
+       int i;
+
+       master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio));
+       if (master == NULL) {
+               dev_err(&dev->dev, "failed to allocate spi master\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       sp = spi_master_get_devdata(master);
+
+       platform_set_drvdata(dev, sp);
+
+       /* copy in the plkatform data */
+       sp->info = dev->dev.platform_data;
+
+       /* setup spi bitbang adaptor */
+       sp->bitbang.master = spi_master_get(master);
+       sp->bitbang.chipselect = s3c2410_spigpio_chipselect;
+
+       sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0;
+       sp->bitbang.txrx_word[SPI_MODE_1] = s3c2410_spigpio_txrx_mode1;
+
+       /* set state of spi pins */
+       s3c2410_gpio_setpin(sp->info->pin_clk, 0);
+       s3c2410_gpio_setpin(sp->info->pin_mosi, 0);
+
+       s3c2410_gpio_cfgpin(sp->info->pin_clk, S3C2410_GPIO_OUTPUT);
+       s3c2410_gpio_cfgpin(sp->info->pin_mosi, S3C2410_GPIO_OUTPUT);
+       s3c2410_gpio_cfgpin(sp->info->pin_miso, S3C2410_GPIO_INPUT);
+
+       ret = spi_bitbang_start(&sp->bitbang);
+       if (ret)
+               goto err_no_bitbang;
+
+       /* register the chips to go with the board */
+
+       for (i = 0; i < sp->info->board_size; i++) {
+               dev_info(&dev->dev, "registering %p: %s\n",
+                        &sp->info->board_info[i],
+                        sp->info->board_info[i].modalias);
+
+               sp->info->board_info[i].controller_data = sp;
+               spi_new_device(master, sp->info->board_info + i);
+       }
+
+       return 0;
+
+ err_no_bitbang:
+       spi_master_put(sp->bitbang.master);
+ err:
+       return ret;
+
+}
+
+static int s3c2410_spigpio_remove(struct platform_device *dev)
+{
+       struct s3c2410_spigpio *sp = platform_get_drvdata(dev);
+
+       spi_bitbang_stop(&sp->bitbang);
+       spi_master_put(sp->bitbang.master);
+
+       return 0;
+}
+
+/* all gpio should be held over suspend/resume, so we should
+ * not need to deal with this
+*/
+
+#define s3c2410_spigpio_suspend NULL
+#define s3c2410_spigpio_resume NULL
+
+
+static struct platform_driver s3c2410_spigpio_drv = {
+       .probe          = s3c2410_spigpio_probe,
+        .remove                = s3c2410_spigpio_remove,
+        .suspend       = s3c2410_spigpio_suspend,
+        .resume                = s3c2410_spigpio_resume,
+        .driver                = {
+               .name   = "s3c24xx-spi-gpio",
+               .owner  = THIS_MODULE,
+        },
+};
+
+static int __init s3c2410_spigpio_init(void)
+{
+        return platform_driver_register(&s3c2410_spigpio_drv);
+}
+
+static void __exit s3c2410_spigpio_exit(void)
+{
+        platform_driver_unregister(&s3c2410_spigpio_drv);
+}
+
+module_init(s3c2410_spigpio_init);
+module_exit(s3c2410_spigpio_exit);
+
+MODULE_DESCRIPTION("S3C24XX SPI Driver");
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL");
index 6dd6666961787434653fcde4add8eb0e25bb2ab0..c4670e1d46545f12cdfe0ef9cdd89c106d1ca594 100644 (file)
@@ -317,6 +317,7 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun
                                }
 
                                schedule();
+                               set_current_state(TASK_INTERRUPTIBLE);
                        }
 
                        set_current_state(TASK_RUNNING);
index 3d04b2def0f165d5ab7cbc2afadace2fa7896eb8..789450bb0bc9c020aec0320bf6125a85417a7bb5 100644 (file)
@@ -214,10 +214,13 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
  */
 int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
 {
-       struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
-       u32 *palette = fbdev->regs->lcd_pallettebase;
+       struct au1100fb_device *fbdev;
+       u32 *palette;
        u32 value;
 
+       fbdev = to_au1100fb_device(fbi);
+       palette = fbdev->regs->lcd_pallettebase;
+
        if (regno > (AU1100_LCD_NBR_PALETTE_ENTRIES - 1))
                return -EINVAL;
 
@@ -316,9 +319,11 @@ int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
  */
 int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
 {
-       struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+       struct au1100fb_device *fbdev;
        int dy;
 
+       fbdev = to_au1100fb_device(fbi);
+
        print_dbg("fb_pan_display %p %p", var, fbi);
 
        if (!var || !fbdev) {
@@ -382,10 +387,12 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
  */
 int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 {
-       struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+       struct au1100fb_device *fbdev;
        unsigned int len;
        unsigned long start=0, off;
 
+       fbdev = to_au1100fb_device(fbi);
+
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
                return -EINVAL;
        }
@@ -467,7 +474,7 @@ int au1100fb_drv_probe(struct device *dev)
 
        if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
                                DRIVER_NAME)) {
-               print_err("fail to lock memory region at 0x%08x",
+               print_err("fail to lock memory region at 0x%08lx",
                                au1100fb_fix.mmio_start);
                return -EBUSY;
        }
@@ -595,13 +602,13 @@ int au1100fb_drv_remove(struct device *dev)
        return 0;
 }
 
-int au1100fb_drv_suspend(struct device *dev, u32 state, u32 level)
+int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
 {
        /* TODO */
        return 0;
 }
 
-int au1100fb_drv_resume(struct device *dev, u32 level)
+int au1100fb_drv_resume(struct device *dev)
 {
        /* TODO */
        return 0;
index ca020719d20b14959b3d1daa31d4e1c91742df2e..953eb8c171d6233acdd1df9e8927cdaa25d5cc14 100644 (file)
@@ -2631,7 +2631,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
                                        scr_memcpyw((u16 *) q, (u16 *) p,
                                                    vc->vc_size_row);
                                }
-                               softback_in = p;
+                               softback_in = softback_curr = p;
                                update_region(vc, vc->vc_origin,
                                              logo_lines * vc->vc_cols);
                        }
index 788297e9d59e16eef99a896ba4d63927f2d2f70b..44aa2ffff973e52b7f438fdef634d3cc5c0b6f7d 100644 (file)
@@ -76,8 +76,8 @@
  *
  * Experiment with v_offset to find out which works best for you.
  */
-static u32 v_offset_default __initdata; /* For 32 MiB Aper size, 8 should be the default */
-static u32 voffset          __initdata = 0;
+static u32 v_offset_default __devinitdata; /* For 32 MiB Aper size, 8 should be the default */
+static u32 voffset          __devinitdata;
 
 static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor);
 static int  __devinit i810fb_init_pci (struct pci_dev *dev,
index 8073a73f6f350804abeacd00d5e132284d073ac1..440272ad10e725a206e58491e0e6b1bf96a1d5a8 100644 (file)
@@ -316,14 +316,24 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
                case M_PIXEL_PLL_B:
                case M_PIXEL_PLL_C:
                        {
-                               u_int8_t tmp;
+                               u_int8_t tmp, xpwrctrl;
                                unsigned long flags;
                                
                                matroxfb_DAC_lock_irqsave(flags);
+
+                               xpwrctrl = matroxfb_DAC_in(PMINFO M1064_XPWRCTRL);
+                               matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl & ~M1064_XPWRCTRL_PANELPDN);
+                               mga_outb(M_SEQ_INDEX, M_SEQ1);
+                               mga_outb(M_SEQ_DATA, mga_inb(M_SEQ_DATA) | M_SEQ1_SCROFF);
                                tmp = matroxfb_DAC_in(PMINFO M1064_XPIXCLKCTRL);
+                               tmp |= M1064_XPIXCLKCTRL_DIS;
                                if (!(tmp & M1064_XPIXCLKCTRL_PLL_UP)) {
-                                       matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp | M1064_XPIXCLKCTRL_PLL_UP);
+                                       tmp |= M1064_XPIXCLKCTRL_PLL_UP;
                                }
+                               matroxfb_DAC_out(PMINFO M1064_XPIXCLKCTRL, tmp);
+                               matroxfb_DAC_out(PMINFO M1064_XDVICLKCTRL, 0);
+                               matroxfb_DAC_out(PMINFO M1064_XPWRCTRL, xpwrctrl);
+
                                matroxfb_DAC_unlock_irqrestore(flags);
                        }
                        {
@@ -418,6 +428,15 @@ static int __g450_setclk(WPMINFO unsigned int fout, unsigned int pll,
                                   frequency to higher - with <= lowest wins, while
                                   with < highest one wins */
                                if (delta <= deltaarray[idx-1]) {
+                                       /* all else being equal except VCO,
+                                        * choose VCO not near (within 1/16th or so) VCOmin
+                                        * (freqs near VCOmin aren't as stable)
+                                        */
+                                       if (delta == deltaarray[idx-1]
+                                           && vco != g450_mnp2vco(PMINFO mnparray[idx-1])
+                                           && vco < (pi->vcomin * 17 / 16)) {
+                                               break;
+                                       }
                                        mnparray[idx] = mnparray[idx-1];
                                        deltaarray[idx] = deltaarray[idx-1];
                                } else {
index 2e7238aa243209dfe74072c4c608149eafbb0405..56513a5d220b03d44531c2b677441bd3f3b2380a 100644 (file)
@@ -40,6 +40,7 @@ void DAC1064_global_restore(WPMINFO2);
 #define M1064_XCURCOL1RED      0x0C
 #define M1064_XCURCOL1GREEN    0x0D
 #define M1064_XCURCOL1BLUE     0x0E
+#define M1064_XDVICLKCTRL      0x0F
 #define M1064_XCURCOL2RED      0x10
 #define M1064_XCURCOL2GREEN    0x11
 #define M1064_XCURCOL2BLUE     0x12
@@ -144,6 +145,7 @@ void DAC1064_global_restore(WPMINFO2);
 #define M1064_XVIDPLLN         0x8F
 
 #define M1064_XPWRCTRL         0xA0
+#define     M1064_XPWRCTRL_PANELPDN    0x04
 
 #define M1064_XPANMODE         0xA2
 
index 3a3e1804c56a507a23b320527d9c7373e4ca1266..b71737178d0d9bcbbfc328d62e88aae7433dbc7c 100644 (file)
@@ -672,6 +672,8 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv);
 
 #define M_SEQ_INDEX    0x1FC4
 #define M_SEQ_DATA     0x1FC5
+#define     M_SEQ1             0x01
+#define        M_SEQ1_SCROFF           0x20
 
 #define M_MISC_REG_READ        0x1FCC
 
index 743e7ad26acc3299f32e5903b9c4bc474a249fcb..f85421bf7cb5365319d8de5076a5dbed38fe4cfb 100644 (file)
@@ -55,7 +55,7 @@ static struct fb_var_screeninfo maxinefb_defined = {
 };
 
 static struct fb_fix_screeninfo maxinefb_fix = {
-       .id =           "Maxine onboard graphics 1024x768x8",
+       .id =           "Maxine",
        .smem_len =     (1024*768),
        .type =         FB_TYPE_PACKED_PIXELS,
        .visual =       FB_VISUAL_PSEUDOCOLOR,
@@ -107,8 +107,6 @@ static int maxinefb_setcolreg(unsigned regno, unsigned red, unsigned green,
 
 static struct fb_ops maxinefb_ops = {
        .owner          = THIS_MODULE,
-       .fb_get_fix     = gen_get_fix,
-       .fb_get_var     = gen_get_var,
        .fb_setcolreg   = maxinefb_setcolreg,
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
index d4c2d636c479dc2aaaa986656a8659424aac56a6..a42143ca01698e1ba64769d5d9eb1bc0aa095320 100644 (file)
@@ -416,10 +416,9 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        return retval;
        }
 
-       retval = -EIO;
        bh = affs_bread(sb, old_dentry->d_inode->i_ino);
        if (!bh)
-               goto done;
+               return -EIO;
 
        /* Remove header from its parent directory. */
        affs_lock_dir(old_dir);
index 69f44dcdb0b4c92f504e118a4eae080528cf68b0..b1c902e319c13dfc82200753f54b4f99102dfb51 100644 (file)
@@ -428,7 +428,6 @@ static int load_flat_file(struct linux_binprm * bprm,
        loff_t fpos;
        unsigned long start_code, end_code;
        int ret;
-       int exec_fileno;
 
        hdr = ((struct flat_hdr *) bprm->buf);          /* exec-header */
        inode = bprm->file->f_dentry->d_inode;
@@ -502,21 +501,12 @@ static int load_flat_file(struct linux_binprm * bprm,
                goto err;
        }
 
-       /* check file descriptor */
-       exec_fileno = get_unused_fd();
-       if (exec_fileno < 0) {
-               ret = -EMFILE;
-               goto err;
-       }
-       get_file(bprm->file);
-       fd_install(exec_fileno, bprm->file);
-
        /* Flush all traces of the currently running executable */
        if (id == 0) {
                result = flush_old_exec(bprm);
                if (result) {
                        ret = result;
-                       goto err_close;
+                       goto err;
                }
 
                /* OK, This is the point of no return */
@@ -548,7 +538,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                                textpos = (unsigned long) -ENOMEM;
                        printk("Unable to mmap process text, errno %d\n", (int)-textpos);
                        ret = textpos;
-                       goto err_close;
+                       goto err;
                }
 
                down_write(&current->mm->mmap_sem);
@@ -564,7 +554,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                                        (int)-datapos);
                        do_munmap(current->mm, textpos, text_len);
                        ret = realdatastart;
-                       goto err_close;
+                       goto err;
                }
                datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
 
@@ -587,7 +577,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                        do_munmap(current->mm, textpos, text_len);
                        do_munmap(current->mm, realdatastart, data_len + extra);
                        ret = result;
-                       goto err_close;
+                       goto err;
                }
 
                reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
@@ -606,7 +596,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                        printk("Unable to allocate RAM for process text/data, errno %d\n",
                                        (int)-textpos);
                        ret = textpos;
-                       goto err_close;
+                       goto err;
                }
 
                realdatastart = textpos + ntohl(hdr->data_start);
@@ -652,7 +642,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                        do_munmap(current->mm, textpos, text_len + data_len + extra +
                                MAX_SHARED_LIBS * sizeof(unsigned long));
                        ret = result;
-                       goto err_close;
+                       goto err;
                }
        }
 
@@ -717,7 +707,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                                addr = calc_reloc(*rp, libinfo, id, 0);
                                if (addr == RELOC_FAILED) {
                                        ret = -ENOEXEC;
-                                       goto err_close;
+                                       goto err;
                                }
                                *rp = addr;
                        }
@@ -747,7 +737,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                        rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
                        if (rp == (unsigned long *)RELOC_FAILED) {
                                ret = -ENOEXEC;
-                               goto err_close;
+                               goto err;
                        }
 
                        /* Get the pointer's value.  */
@@ -762,7 +752,7 @@ static int load_flat_file(struct linux_binprm * bprm,
                                addr = calc_reloc(addr, libinfo, id, 0);
                                if (addr == RELOC_FAILED) {
                                        ret = -ENOEXEC;
-                                       goto err_close;
+                                       goto err;
                                }
 
                                /* Write back the relocated pointer.  */
@@ -783,8 +773,6 @@ static int load_flat_file(struct linux_binprm * bprm,
                        stack_len);
 
        return 0;
-err_close:
-       sys_close(exec_fileno);
 err:
        return ret;
 }
index eb8fbc53f2cd73273c8639c4dcb0648b30d15f70..098c12b2d60a9d8028a6a8fbdb2b03ecca84e3ba 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1116,6 +1116,9 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
        bp->bio1.bi_io_vec = &bp->bv1;
        bp->bio2.bi_io_vec = &bp->bv2;
 
+       bp->bio1.bi_max_vecs = 1;
+       bp->bio2.bi_max_vecs = 1;
+
        bp->bio1.bi_end_io = bio_pair_end_1;
        bp->bio2.bi_end_io = bio_pair_end_2;
 
index 1a27ecb46c9a71d7458b9119b345a8a4f6ec104c..7271bb0257f64f149d1fd3f9857416c1513787ae 100644 (file)
@@ -1,3 +1,10 @@
+Version 1.43
+------------
+POSIX locking to servers which support CIFS POSIX Extensions
+(disabled by default controlled by proc/fs/cifs/Experimental).
+Handle conversion of long share names (especially Asian languages)
+to Unicode during mount. 
+
 Version 1.42
 ------------
 Fix slow oplock break when mounted to different servers at the same time and
index 4e829dc672a645622c078466244a71d611c1e8c9..c98755dca868743c25822124c1bc06d8b225a9ed 100644 (file)
@@ -99,5 +99,5 @@ extern ssize_t        cifs_getxattr(struct dentry *, const char *, void *, size_t);
 extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
 extern int cifs_ioctl (struct inode * inode, struct file * filep,
                       unsigned int command, unsigned long arg);
-#define CIFS_VERSION   "1.42"
+#define CIFS_VERSION   "1.43"
 #endif                         /* _CIFSFS_H */
index 2879ba343ca7acf5a4c4372c16a6ef3a7237ad9e..310ea2f0e0bfd27d6eacd91ffe0f695a0ca89322 100644 (file)
@@ -267,7 +267,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
                        const int waitFlag);
 extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                        const __u16 smb_file_id, const int get_flag,
-                       const __u64 len, const __u64 offset
+                       const __u64 len, struct file_lock *
                        const __u16 lock_type, const int waitFlag);
 extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
 extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
index fd36892eda55a282fc207842e0ff62787c746703..925881e00ff210e08822cc456337be1734f801d8 100644 (file)
@@ -1355,7 +1355,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
 int
 CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                const __u16 smb_file_id, const int get_flag, const __u64 len,
-               const __u64 lkoffset, const __u16 lock_type, const int waitFlag)
+               struct file_lock *pLockData, const __u16 lock_type, 
+               const int waitFlag)
 {
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
        struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
@@ -1366,6 +1367,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
        __u16 params, param_offset, offset, byte_count, count;
 
        cFYI(1, ("Posix Lock"));
+
+       if(pLockData == NULL)
+               return EINVAL;
+
        rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
 
        if (rc)
@@ -1404,10 +1409,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
 
        parm_data->lock_type = cpu_to_le16(lock_type);
        if(waitFlag)
-               parm_data->lock_flags = 1;
+               parm_data->lock_flags = cpu_to_le16(1);
        parm_data->pid = cpu_to_le32(current->tgid);
-       parm_data->start = lkoffset;
-       parm_data->length = len;  /* normalize negative numbers */
+       parm_data->start = cpu_to_le64(pLockData->fl_start);
+       parm_data->length = cpu_to_le64(len);  /* normalize negative numbers */
 
        pSMB->DataOffset = cpu_to_le16(offset);
        pSMB->Fid = smb_file_id;
@@ -1419,8 +1424,33 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                        (struct smb_hdr *) pSMBr, &bytes_returned, 0);
        if (rc) {
                cFYI(1, ("Send error in Posix Lock = %d", rc));
-       }
+       } else if (get_flag) {
+               /* lock structure can be returned on get */
+               __u16 data_offset;
+               __u16 data_count;
+               rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
+               if (rc || (pSMBr->ByteCount < sizeof(struct cifs_posix_lock))) {
+                       rc = -EIO;      /* bad smb */
+                       goto plk_err_exit;
+               }
+               if(pLockData == NULL) {
+                       rc = -EINVAL;
+                       goto plk_err_exit;
+               }
+               data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+               data_count  = le16_to_cpu(pSMBr->t2.DataCount);
+               if(data_count < sizeof(struct cifs_posix_lock)) {
+                       rc = -EIO;
+                       goto plk_err_exit;
+               }
+               parm_data = (struct cifs_posix_lock *)
+                       ((char *)&pSMBr->hdr.Protocol + data_offset);
+               if(parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
+                       pLockData->fl_type = F_UNLCK;
+       }
+plk_err_exit:
        if (pSMB)
                cifs_small_buf_release(pSMB);
 
index d2ec806a4f32b516cc7a320b39fb3974bc5dd2e2..bae1479318d10fc6fd34a141a564aeb49252ba80 100644 (file)
@@ -2148,6 +2148,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
 /* We look for obvious messed up bcc or strings in response so we do not go off
    the end since (at least) WIN2K and Windows XP have a major bug in not null
    terminating last Unicode string in response  */
+                               if(ses->serverOS)
+                                       kfree(ses->serverOS);
                                ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL);
                                if(ses->serverOS == NULL)
                                        goto sesssetup_nomem;
@@ -2160,6 +2162,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                if (remaining_words > 0) {
                                        len = UniStrnlen((wchar_t *)bcc_ptr,
                                                         remaining_words-1);
+                                       if(ses->serverNOS)
+                                               kfree(ses->serverNOS);
                                        ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL);
                                        if(ses->serverNOS == NULL)
                                                goto sesssetup_nomem;
@@ -2177,6 +2181,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        if (remaining_words > 0) {
                                                len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
           /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
+                                               if(ses->serverDomain)
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain =
                                                    kzalloc(2*(len+1),GFP_KERNEL);
                                                if(ses->serverDomain == NULL)
@@ -2187,15 +2193,22 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                ses->serverDomain[2*len] = 0;
                                                ses->serverDomain[1+(2*len)] = 0;
                                        } /* else no more room so create dummy domain string */
-                                       else
+                                       else {
+                                               if(ses->serverDomain)
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain = 
                                                        kzalloc(2, GFP_KERNEL);
+                                       }
                                } else {        /* no room so create dummy domain and NOS string */
                                        /* if these kcallocs fail not much we
                                           can do, but better to not fail the
                                           sesssetup itself */
+                                       if(ses->serverDomain)
+                                               kfree(ses->serverDomain);
                                        ses->serverDomain =
                                            kzalloc(2, GFP_KERNEL);
+                                       if(ses->serverNOS)
+                                               kfree(ses->serverNOS);
                                        ses->serverNOS =
                                            kzalloc(2, GFP_KERNEL);
                                }
@@ -2204,6 +2217,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                if (((long) bcc_ptr + len) - (long)
                                    pByteArea(smb_buffer_response)
                                            <= BCC(smb_buffer_response)) {
+                                       if(ses->serverOS)
+                                               kfree(ses->serverOS);
                                        ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
                                        if(ses->serverOS == NULL)
                                                goto sesssetup_nomem;
@@ -2214,6 +2229,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        bcc_ptr++;
 
                                        len = strnlen(bcc_ptr, 1024);
+                                       if(ses->serverNOS)
+                                               kfree(ses->serverNOS);
                                        ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
                                        if(ses->serverNOS == NULL)
                                                goto sesssetup_nomem;
@@ -2223,6 +2240,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        bcc_ptr++;
 
                                        len = strnlen(bcc_ptr, 1024);
+                                       if(ses->serverDomain)
+                                               kfree(ses->serverDomain);
                                        ses->serverDomain = kzalloc(len + 1,GFP_KERNEL);
                                        if(ses->serverDomain == NULL)
                                                goto sesssetup_nomem;
@@ -2427,6 +2446,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
 /* We look for obvious messed up bcc or strings in response so we do not go off
    the end since (at least) WIN2K and Windows XP have a major bug in not null
    terminating last Unicode string in response  */
+                                       if(ses->serverOS)
+                                               kfree(ses->serverOS);
                                        ses->serverOS =
                                            kzalloc(2 * (len + 1), GFP_KERNEL);
                                        cifs_strfromUCS_le(ses->serverOS,
@@ -2441,6 +2462,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                len = UniStrnlen((wchar_t *)bcc_ptr,
                                                                 remaining_words
                                                                 - 1);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(2 * (len + 1),
                                                            GFP_KERNEL);
@@ -2454,7 +2477,9 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                remaining_words -= len + 1;
                                                if (remaining_words > 0) {
                                                        len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
-                            /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
+                     /* last string not null terminated (e.g.Windows XP/2000) */
+                                                       if(ses->serverDomain)
+                                                               kfree(ses->serverDomain);
                                                        ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
                                                        cifs_strfromUCS_le(ses->serverDomain,
                                                             (__le16 *)bcc_ptr, 
@@ -2463,11 +2488,18 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                        ses->serverDomain[2*len] = 0;
                                                        ses->serverDomain[1+(2*len)] = 0;
                                                } /* else no more room so create dummy domain string */
-                                               else
+                                               else {
+                                                       if(ses->serverDomain)
+                                                               kfree(ses->serverDomain);
                                                        ses->serverDomain =
                                                            kzalloc(2,GFP_KERNEL);
-                                       } else {        /* no room so create dummy domain and NOS string */
+                                               }
+                                       } else {/* no room use dummy domain&NOS */
+                                               if(ses->serverDomain)
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain = kzalloc(2, GFP_KERNEL);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS = kzalloc(2, GFP_KERNEL);
                                        }
                                } else {        /* ASCII */
@@ -2476,6 +2508,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        if (((long) bcc_ptr + len) - (long)
                                            pByteArea(smb_buffer_response)
                                            <= BCC(smb_buffer_response)) {
+                                               if(ses->serverOS)
+                                                       kfree(ses->serverOS);
                                                ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
                                                strncpy(ses->serverOS, bcc_ptr, len);
 
@@ -2484,6 +2518,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
                                                strncpy(ses->serverNOS, bcc_ptr, len);
                                                bcc_ptr += len;
@@ -2491,6 +2527,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
+                                               if(ses->serverDomain)
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
                                                strncpy(ses->serverDomain, bcc_ptr, len);
                                                bcc_ptr += len;
@@ -2728,6 +2766,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
 /* We look for obvious messed up bcc or strings in response so we do not go off
    the end since (at least) WIN2K and Windows XP have a major bug in not null
    terminating last Unicode string in response  */
+                                       if(ses->serverOS)
+                                               kfree(ses->serverOS);
                                        ses->serverOS =
                                            kzalloc(2 * (len + 1), GFP_KERNEL);
                                        cifs_strfromUCS_le(ses->serverOS,
@@ -2743,6 +2783,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                                 bcc_ptr,
                                                                 remaining_words
                                                                 - 1);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(2 * (len + 1),
                                                            GFP_KERNEL);
@@ -2760,6 +2802,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                if (remaining_words > 0) {
                                                        len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
            /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
+                                                       if(ses->serverDomain)
+                                                               kfree(ses->serverDomain);
                                                        ses->serverDomain =
                                                            kzalloc(2 *
                                                                    (len +
@@ -2777,13 +2821,20 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                                [1 + (2 * len)]
                                                            = 0;
                                                } /* else no more room so create dummy domain string */
-                                               else
+                                               else {
+                                                       if(ses->serverDomain)
+                                                               kfree(ses->serverDomain);
                                                        ses->serverDomain =
                                                            kzalloc(2,
                                                                    GFP_KERNEL);
+                                               }
                                        } else {        /* no room so create dummy domain and NOS string */
+                                               if(ses->serverDomain);
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain =
                                                    kzalloc(2, GFP_KERNEL);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(2, GFP_KERNEL);
                                        }
@@ -2792,6 +2843,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                        if (((long) bcc_ptr + len) - (long)
                                            pByteArea(smb_buffer_response)
                                            <= BCC(smb_buffer_response)) {
+                                               if(ses->serverOS)
+                                                       kfree(ses->serverOS);
                                                ses->serverOS =
                                                    kzalloc(len + 1,
                                                            GFP_KERNEL);
@@ -2803,6 +2856,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(len + 1,
                                                            GFP_KERNEL);
@@ -2812,6 +2867,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
+                                               if(ses->serverDomain)
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain =
                                                    kzalloc(len + 1,
                                                            GFP_KERNEL);
@@ -3116,6 +3173,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
 /* We look for obvious messed up bcc or strings in response so we do not go off
   the end since (at least) WIN2K and Windows XP have a major bug in not null
   terminating last Unicode string in response  */
+                                       if(ses->serverOS)
+                                               kfree(ses->serverOS);
                                        ses->serverOS =
                                            kzalloc(2 * (len + 1), GFP_KERNEL);
                                        cifs_strfromUCS_le(ses->serverOS,
@@ -3131,6 +3190,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                                 bcc_ptr,
                                                                 remaining_words
                                                                 - 1);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS =
                                                    kzalloc(2 * (len + 1),
                                                            GFP_KERNEL);
@@ -3147,6 +3208,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                if (remaining_words > 0) {
                                                        len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
      /* last string not always null terminated (e.g. for Windows XP & 2000) */
+                                                       if(ses->serverDomain)
+                                                               kfree(ses->serverDomain);
                                                        ses->serverDomain =
                                                            kzalloc(2 *
                                                                    (len +
@@ -3172,10 +3235,17 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                                          len)]
                                                            = 0;
                                                } /* else no more room so create dummy domain string */
-                                               else
+                                               else {
+                                                       if(ses->serverDomain)
+                                                               kfree(ses->serverDomain);
                                                        ses->serverDomain = kzalloc(2,GFP_KERNEL);
+                                               }
                                        } else {  /* no room so create dummy domain and NOS string */
+                                               if(ses->serverDomain)
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain = kzalloc(2, GFP_KERNEL);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS = kzalloc(2, GFP_KERNEL);
                                        }
                                } else {        /* ASCII */
@@ -3183,6 +3253,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        if (((long) bcc_ptr + len) - 
                         (long) pByteArea(smb_buffer_response) 
                             <= BCC(smb_buffer_response)) {
+                                               if(ses->serverOS)
+                                                       kfree(ses->serverOS);
                                                ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
                                                strncpy(ses->serverOS,bcc_ptr, len);
 
@@ -3191,6 +3263,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
+                                               if(ses->serverNOS)
+                                                       kfree(ses->serverNOS);
                                                ses->serverNOS = kzalloc(len+1,GFP_KERNEL);
                                                strncpy(ses->serverNOS, bcc_ptr, len);  
                                                bcc_ptr += len;
@@ -3198,6 +3272,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                bcc_ptr++;
 
                                                len = strnlen(bcc_ptr, 1024);
+                                               if(ses->serverDomain)
+                                                       kfree(ses->serverDomain);
                                                ses->serverDomain = kzalloc(len+1,GFP_KERNEL);
                                                strncpy(ses->serverDomain, bcc_ptr, len);
                                                bcc_ptr += len;
@@ -3282,7 +3358,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                bcc_ptr++; /* align */
        }
 
-       if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+       if(ses->server->secMode & 
+                       (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
                smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
 
        if (ses->capabilities & CAP_STATUS32) {
@@ -3294,8 +3371,10 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
        if (ses->capabilities & CAP_UNICODE) {
                smb_buffer->Flags2 |= SMBFLG2_UNICODE;
                length =
-                   cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage);
-               bcc_ptr += 2 * length;  /* convert num of 16 bit words to bytes */
+                   cifs_strtoUCS((__le16 *) bcc_ptr, tree, 
+                       6 /* max utf8 char length in bytes */ * 
+                       (/* server len*/ + 256 /* share len */), nls_codepage);
+               bcc_ptr += 2 * length;  /* convert num 16 bit words to bytes */
                bcc_ptr += 2;   /* skip trailing null */
        } else {                /* ASCII */
                strcpy(bcc_ptr, tree);
index e152bf6afa60fadc91c2080231858d9b5653f0fb..e2b4ce1dad6680cc54d8af516e7cf876533361fd 100644 (file)
@@ -84,6 +84,8 @@ static inline int cifs_get_disposition(unsigned int flags)
                return FILE_OVERWRITE_IF;
        else if ((flags & O_CREAT) == O_CREAT)
                return FILE_OPEN_IF;
+       else if ((flags & O_TRUNC) == O_TRUNC)
+               return FILE_OVERWRITE;
        else
                return FILE_OPEN;
 }
@@ -656,7 +658,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                        else
                                posix_lock_type = CIFS_WRLCK;
                        rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
-                                       length, pfLock->fl_start,
+                                       length, pfLock,
                                        posix_lock_type, wait_flag);
                        FreeXid(xid);
                        return rc;
@@ -704,7 +706,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
                        return -EOPNOTSUPP;
                }
                rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
-                                     length, pfLock->fl_start,
+                                     length, pfLock,
                                      posix_lock_type, wait_flag);
        } else
                rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
@@ -904,8 +906,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                if (rc != 0)
                                        break;
                        }
-                       if(experimEnabled || (pTcon->ses->server->secMode & 
-                        (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
+                       if(experimEnabled || (pTcon->ses->server &&
+                               ((pTcon->ses->server->secMode & 
+                               (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+                               == 0))) {
                                struct kvec iov[2];
                                unsigned int len;
 
index 01f39f87f372ec08bfd932dd92a3dc5e646d20d6..b1f64786a613e598b5b5a06684f58d5cea8c0d5c 100644 (file)
@@ -2030,109 +2030,115 @@ union compat_nfsctl_res {
        struct knfsd_fh         cr32_getfs;
 };
 
-static int compat_nfs_svc_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg)
-{
-       int err;
-
-       err = access_ok(VERIFY_READ, &arg->ca32_svc, sizeof(arg->ca32_svc));
-       err |= get_user(karg->ca_version, &arg->ca32_version);
-       err |= __get_user(karg->ca_svc.svc_port, &arg->ca32_svc.svc32_port);
-       err |= __get_user(karg->ca_svc.svc_nthreads, &arg->ca32_svc.svc32_nthreads);
-       return (err) ? -EFAULT : 0;
+static int compat_nfs_svc_trans(struct nfsctl_arg *karg,
+                               struct compat_nfsctl_arg __user *arg)
+{
+       if (!access_ok(VERIFY_READ, &arg->ca32_svc, sizeof(arg->ca32_svc)) ||
+               get_user(karg->ca_version, &arg->ca32_version) ||
+               __get_user(karg->ca_svc.svc_port, &arg->ca32_svc.svc32_port) ||
+               __get_user(karg->ca_svc.svc_nthreads,
+                               &arg->ca32_svc.svc32_nthreads))
+               return -EFAULT;
+       return 0;
 }
 
-static int compat_nfs_clnt_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg)
-{
-       int err;
-
-       err = access_ok(VERIFY_READ, &arg->ca32_client, sizeof(arg->ca32_client));
-       err |= get_user(karg->ca_version, &arg->ca32_version);
-       err |= __copy_from_user(&karg->ca_client.cl_ident[0],
-                         &arg->ca32_client.cl32_ident[0],
-                         NFSCLNT_IDMAX);
-       err |= __get_user(karg->ca_client.cl_naddr, &arg->ca32_client.cl32_naddr);
-       err |= __copy_from_user(&karg->ca_client.cl_addrlist[0],
-                         &arg->ca32_client.cl32_addrlist[0],
-                         (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
-       err |= __get_user(karg->ca_client.cl_fhkeytype,
-                     &arg->ca32_client.cl32_fhkeytype);
-       err |= __get_user(karg->ca_client.cl_fhkeylen,
-                     &arg->ca32_client.cl32_fhkeylen);
-       err |= __copy_from_user(&karg->ca_client.cl_fhkey[0],
-                         &arg->ca32_client.cl32_fhkey[0],
-                         NFSCLNT_KEYMAX);
+static int compat_nfs_clnt_trans(struct nfsctl_arg *karg,
+                               struct compat_nfsctl_arg __user *arg)
+{
+       if (!access_ok(VERIFY_READ, &arg->ca32_client,
+                       sizeof(arg->ca32_client)) ||
+               get_user(karg->ca_version, &arg->ca32_version) ||
+               __copy_from_user(&karg->ca_client.cl_ident[0],
+                               &arg->ca32_client.cl32_ident[0],
+                               NFSCLNT_IDMAX) ||
+               __get_user(karg->ca_client.cl_naddr,
+                               &arg->ca32_client.cl32_naddr) ||
+               __copy_from_user(&karg->ca_client.cl_addrlist[0],
+                               &arg->ca32_client.cl32_addrlist[0],
+                               (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)) ||
+               __get_user(karg->ca_client.cl_fhkeytype,
+                               &arg->ca32_client.cl32_fhkeytype) ||
+               __get_user(karg->ca_client.cl_fhkeylen,
+                               &arg->ca32_client.cl32_fhkeylen) ||
+               __copy_from_user(&karg->ca_client.cl_fhkey[0],
+                               &arg->ca32_client.cl32_fhkey[0],
+                               NFSCLNT_KEYMAX))
+               return -EFAULT;
 
-       return (err) ? -EFAULT : 0;
+       return 0;
 }
 
-static int compat_nfs_exp_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg)
-{
-       int err;
-
-       err = access_ok(VERIFY_READ, &arg->ca32_export, sizeof(arg->ca32_export));
-       err |= get_user(karg->ca_version, &arg->ca32_version);
-       err |= __copy_from_user(&karg->ca_export.ex_client[0],
-                         &arg->ca32_export.ex32_client[0],
-                         NFSCLNT_IDMAX);
-       err |= __copy_from_user(&karg->ca_export.ex_path[0],
-                         &arg->ca32_export.ex32_path[0],
-                         NFS_MAXPATHLEN);
-       err |= __get_user(karg->ca_export.ex_dev,
-                     &arg->ca32_export.ex32_dev);
-       err |= __get_user(karg->ca_export.ex_ino,
-                     &arg->ca32_export.ex32_ino);
-       err |= __get_user(karg->ca_export.ex_flags,
-                     &arg->ca32_export.ex32_flags);
-       err |= __get_user(karg->ca_export.ex_anon_uid,
-                     &arg->ca32_export.ex32_anon_uid);
-       err |= __get_user(karg->ca_export.ex_anon_gid,
-                     &arg->ca32_export.ex32_anon_gid);
+static int compat_nfs_exp_trans(struct nfsctl_arg *karg,
+                               struct compat_nfsctl_arg __user *arg)
+{
+       if (!access_ok(VERIFY_READ, &arg->ca32_export,
+                               sizeof(arg->ca32_export)) ||
+               get_user(karg->ca_version, &arg->ca32_version) ||
+               __copy_from_user(&karg->ca_export.ex_client[0],
+                               &arg->ca32_export.ex32_client[0],
+                               NFSCLNT_IDMAX) ||
+               __copy_from_user(&karg->ca_export.ex_path[0],
+                               &arg->ca32_export.ex32_path[0],
+                               NFS_MAXPATHLEN) ||
+               __get_user(karg->ca_export.ex_dev,
+                               &arg->ca32_export.ex32_dev) ||
+               __get_user(karg->ca_export.ex_ino,
+                               &arg->ca32_export.ex32_ino) ||
+               __get_user(karg->ca_export.ex_flags,
+                               &arg->ca32_export.ex32_flags) ||
+               __get_user(karg->ca_export.ex_anon_uid,
+                               &arg->ca32_export.ex32_anon_uid) ||
+               __get_user(karg->ca_export.ex_anon_gid,
+                               &arg->ca32_export.ex32_anon_gid))
+               return -EFAULT;
        SET_UID(karg->ca_export.ex_anon_uid, karg->ca_export.ex_anon_uid);
        SET_GID(karg->ca_export.ex_anon_gid, karg->ca_export.ex_anon_gid);
 
-       return (err) ? -EFAULT : 0;
+       return 0;
 }
 
-static int compat_nfs_getfd_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg)
-{
-       int err;
-
-       err = access_ok(VERIFY_READ, &arg->ca32_getfd, sizeof(arg->ca32_getfd));
-       err |= get_user(karg->ca_version, &arg->ca32_version);
-       err |= __copy_from_user(&karg->ca_getfd.gd_addr,
-                         &arg->ca32_getfd.gd32_addr,
-                         (sizeof(struct sockaddr)));
-       err |= __copy_from_user(&karg->ca_getfd.gd_path,
-                         &arg->ca32_getfd.gd32_path,
-                         (NFS_MAXPATHLEN+1));
-       err |= __get_user(karg->ca_getfd.gd_version,
-                     &arg->ca32_getfd.gd32_version);
+static int compat_nfs_getfd_trans(struct nfsctl_arg *karg,
+                               struct compat_nfsctl_arg __user *arg)
+{
+       if (!access_ok(VERIFY_READ, &arg->ca32_getfd,
+                       sizeof(arg->ca32_getfd)) ||
+               get_user(karg->ca_version, &arg->ca32_version) ||
+               __copy_from_user(&karg->ca_getfd.gd_addr,
+                               &arg->ca32_getfd.gd32_addr,
+                               (sizeof(struct sockaddr))) ||
+               __copy_from_user(&karg->ca_getfd.gd_path,
+                               &arg->ca32_getfd.gd32_path,
+                               (NFS_MAXPATHLEN+1)) ||
+               __get_user(karg->ca_getfd.gd_version,
+                               &arg->ca32_getfd.gd32_version))
+               return -EFAULT;
 
-       return (err) ? -EFAULT : 0;
+       return 0;
 }
 
-static int compat_nfs_getfs_trans(struct nfsctl_arg *karg, struct compat_nfsctl_arg __user *arg)
+static int compat_nfs_getfs_trans(struct nfsctl_arg *karg,
+                               struct compat_nfsctl_arg __user *arg)
 {
-       int err;
-
-       err = access_ok(VERIFY_READ, &arg->ca32_getfs, sizeof(arg->ca32_getfs));
-       err |= get_user(karg->ca_version, &arg->ca32_version);
-       err |= __copy_from_user(&karg->ca_getfs.gd_addr,
-                         &arg->ca32_getfs.gd32_addr,
-                         (sizeof(struct sockaddr)));
-       err |= __copy_from_user(&karg->ca_getfs.gd_path,
-                         &arg->ca32_getfs.gd32_path,
-                         (NFS_MAXPATHLEN+1));
-       err |= __get_user(karg->ca_getfs.gd_maxlen,
-                     &arg->ca32_getfs.gd32_maxlen);
+       if (!access_ok(VERIFY_READ,&arg->ca32_getfs,sizeof(arg->ca32_getfs)) ||
+               get_user(karg->ca_version, &arg->ca32_version) ||
+               __copy_from_user(&karg->ca_getfs.gd_addr,
+                               &arg->ca32_getfs.gd32_addr,
+                               (sizeof(struct sockaddr))) ||
+               __copy_from_user(&karg->ca_getfs.gd_path,
+                               &arg->ca32_getfs.gd32_path,
+                               (NFS_MAXPATHLEN+1)) ||
+               __get_user(karg->ca_getfs.gd_maxlen,
+                               &arg->ca32_getfs.gd32_maxlen))
+               return -EFAULT;
 
-       return (err) ? -EFAULT : 0;
+       return 0;
 }
 
 /* This really doesn't need translations, we are only passing
  * back a union which contains opaque nfs file handle data.
  */
-static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, union compat_nfsctl_res __user *res)
+static int compat_nfs_getfh_res_trans(union nfsctl_res *kres,
+                               union compat_nfsctl_res __user *res)
 {
        int err;
 
@@ -2141,8 +2147,9 @@ static int compat_nfs_getfh_res_trans(union nfsctl_res *kres, union compat_nfsct
        return (err) ? -EFAULT : 0;
 }
 
-asmlinkage long compat_sys_nfsservctl(int cmd, struct compat_nfsctl_arg __user *arg,
-                                       union compat_nfsctl_res __user *res)
+asmlinkage long compat_sys_nfsservctl(int cmd,
+                               struct compat_nfsctl_arg __user *arg,
+                               union compat_nfsctl_res __user *res)
 {
        struct nfsctl_arg *karg;
        union nfsctl_res *kres;
index b06b54f1bbbbda611e39252d2df5a86b6afaa3c8..4c39009350f3e59529363108800c003de2e2d2d0 100644 (file)
@@ -102,7 +102,7 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent,
                if (acceptable(context, result))
                        return result;
                if (S_ISDIR(result->d_inode->i_mode)) {
-                       /* there is no other dentry, so fail */
+                       err = -EACCES;
                        goto err_result;
                }
 
index 8aac5334680d18603b987cd1afb759d1b59cf574..34b39e9a1e5a01588db869c02c85f2407d12221a 100644 (file)
@@ -767,7 +767,6 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
        if (input->group != sbi->s_groups_count) {
                ext3_warning(sb, __FUNCTION__,
                             "multiple resizers run on filesystem!");
-               unlock_super(sb);
                err = -EBUSY;
                goto exit_journal;
        }
index 1f50302849c53ce8c674fd71416777713de9009b..732ec4bd5774507f8c06c6e05cc90d4d2004a84b 100644 (file)
@@ -848,7 +848,11 @@ static int inotify_release(struct inode *ignored, struct file *file)
                inode = watch->inode;
                mutex_lock(&inode->inotify_mutex);
                mutex_lock(&dev->mutex);
-               remove_watch_no_event(watch, dev);
+
+               /* make sure we didn't race with another list removal */
+               if (likely(idr_find(&dev->idr, watch->wd)))
+                       remove_watch_no_event(watch, dev);
+
                mutex_unlock(&dev->mutex);
                mutex_unlock(&inode->inotify_mutex);
                put_inotify_watch(watch);
@@ -890,8 +894,7 @@ static int inotify_ignore(struct inotify_device *dev, s32 wd)
        mutex_lock(&dev->mutex);
 
        /* make sure that we did not race */
-       watch = idr_find(&dev->idr, wd);
-       if (likely(watch))
+       if (likely(idr_find(&dev->idr, wd) == watch))
                remove_watch(watch, dev);
 
        mutex_unlock(&dev->mutex);
index f28696f235c4be9932a8da84807cc2033e11a3dc..2b220dd6b4e7290976dc3e37765eeb6d9ec08a5e 100644 (file)
@@ -542,7 +542,7 @@ add_failed:
 static int metapage_releasepage(struct page *page, gfp_t gfp_mask)
 {
        struct metapage *mp;
-       int busy = 0;
+       int ret = 1;
        unsigned int offset;
 
        for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) {
@@ -552,30 +552,20 @@ static int metapage_releasepage(struct page *page, gfp_t gfp_mask)
                        continue;
 
                jfs_info("metapage_releasepage: mp = 0x%p", mp);
-               if (mp->count || mp->nohomeok) {
+               if (mp->count || mp->nohomeok ||
+                   test_bit(META_dirty, &mp->flag)) {
                        jfs_info("count = %ld, nohomeok = %d", mp->count,
                                 mp->nohomeok);
-                       busy = 1;
+                       ret = 0;
                        continue;
                }
-               wait_on_page_writeback(page);
-               //WARN_ON(test_bit(META_dirty, &mp->flag));
-               if (test_bit(META_dirty, &mp->flag)) {
-                       dump_mem("dirty mp in metapage_releasepage", mp,
-                                sizeof(struct metapage));
-                       dump_mem("page", page, sizeof(struct page));
-                       dump_stack();
-               }
                if (mp->lsn)
                        remove_from_logsync(mp);
                remove_metapage(page, mp);
                INCREMENT(mpStat.pagefree);
                free_metapage(mp);
        }
-       if (busy)
-               return -1;
-
-       return 0;
+       return ret;
 }
 
 static void metapage_invalidatepage(struct page *page, unsigned long offset)
index 4e0578121d9a621f0d36737582140e4573c464db..3eec30000f3fb3955e029283e8a26bee184b66ba 100644 (file)
@@ -1066,9 +1066,11 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
                rv = nfserr_perm;
        else if (IS_ERR(exp))
                rv = nfserrno(PTR_ERR(exp));
-       else
+       else {
                rv = fh_compose(fhp, exp,
                                fsid_key->ek_dentry, NULL);
+               exp_put(exp);
+       }
        cache_put(&fsid_key->h, &svc_expkey_cache);
        return rv;
 }
index 6aa92d0e68764a7b4ef0ab7de0f34003570f71f8..1d65f13f458c402c608cc3ca0b94bbf1c7e9806c 100644 (file)
@@ -1922,11 +1922,10 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
                value = kmalloc(size, GFP_KERNEL);
                if (!value)
                        return -ENOMEM;
-               size = posix_acl_to_xattr(acl, value, size);
-               if (size < 0) {
-                       error = size;
+               error = posix_acl_to_xattr(acl, value, size);
+               if (error < 0)
                        goto getout;
-               }
+               size = error;
        } else
                size = 0;
 
index f4837fa29420428a5b4c70c7b360b467bd49fae0..5541101b58aef8c962ebc416539daefe12cc3fd8 100644 (file)
@@ -148,6 +148,7 @@ struct termios {
 #define HUPCL  00040000
 
 #define CLOCAL 00100000
+#define CMSPAR   010000000000          /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
 
 /* c_lflag bits */
index 6e19f46d54d1c2aaf947aca24fdc01c4569390fc..c85fc06a043c10dc00392d72b3ef726aa40eece9 100644 (file)
@@ -49,7 +49,7 @@ static inline int __ixp23xx_arch_is_coherent(void)
 {
        extern unsigned int processor_id;
 
-       if (((processor_id & 15) >= 2) || machine_is_roadrunner())
+       if (((processor_id & 15) >= 4) || machine_is_roadrunner())
                return 1;
 
        return 0;
index 1e70908b816f59b1bf172c9445d294c6aab3bb81..915590c391c8c8a4f6f7972912e7ce3cbf247d5c 100644 (file)
 #define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/2/(x+1))<<8)&0x0000ff00)
 #define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
 #define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
+#define SSP_TIMEOUT_SCALE (2712)
 #elif defined(CONFIG_PXA27x)
 #define CLOCK_SPEED_HZ 13000000
 #define SSP1_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
 #define SSP2_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
 #define SSP3_SerClkDiv(x) (((CLOCK_SPEED_HZ/(x+1))<<8)&0x000fff00)
+#define SSP_TIMEOUT_SCALE (769)
 #endif
 
+#define SSP_TIMEOUT(x) ((x*10000)/SSP_TIMEOUT_SCALE)
 #define SSP1_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(1)))))
 #define SSP2_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(2)))))
 #define SSP3_VIRT ((void *)(io_p2v(__PREG(SSCR0_P(3)))))
diff --git a/include/asm-arm/arch-s3c2410/spi-gpio.h b/include/asm-arm/arch-s3c2410/spi-gpio.h
new file mode 100644 (file)
index 0000000..258c00b
--- /dev/null
@@ -0,0 +1,31 @@
+/* linux/include/asm-arm/arch-s3c2410/spi.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - SPI Controller platfrom_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SPIGPIO_H
+#define __ASM_ARCH_SPIGPIO_H __FILE__
+
+struct s3c2410_spigpio_info;
+struct spi_board_info;
+
+struct s3c2410_spigpio_info {
+       unsigned long            pin_clk;
+       unsigned long            pin_mosi;
+       unsigned long            pin_miso;
+
+       unsigned long            board_size;
+       struct spi_board_info   *board_info;
+
+       void (*chip_select)(struct s3c2410_spigpio_info *spi, int cs);
+};
+
+
+#endif /* __ASM_ARCH_SPIGPIO_H */
diff --git a/include/asm-arm/arch-s3c2410/spi.h b/include/asm-arm/arch-s3c2410/spi.h
new file mode 100644 (file)
index 0000000..4029a1a
--- /dev/null
@@ -0,0 +1,29 @@
+/* linux/include/asm-arm/arch-s3c2410/spi.h
+ *
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * S3C2410 - SPI Controller platform_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_SPI_H
+#define __ASM_ARCH_SPI_H __FILE__
+
+struct s3c2410_spi_info;
+struct spi_board_info;
+
+struct s3c2410_spi_info {
+       unsigned long            pin_cs;        /* simple gpio cs */
+
+       unsigned long            board_size;
+       struct spi_board_info   *board_info;
+
+       void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
+};
+
+
+#endif /* __ASM_ARCH_SPI_H */
index 43ad4e55878c7961a535e6ce427b842adecb2372..406ca97a8ab29f99d381565ab3c9b745c1f147a3 100644 (file)
@@ -142,6 +142,9 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw)
        : "cc");
 }
 
+/* write_can_lock - would write_trylock() succeed? */
+#define __raw_write_can_lock(x)                ((x)->lock == 0x80000000)
+
 /*
  * Read locks are a bit more hairy:
  *  - Exclusively load the lock value.
@@ -198,4 +201,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
 
 #define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
 
+/* read_can_lock - would read_trylock() succeed? */
+#define __raw_read_can_lock(x)         ((x)->lock < 0x80000000)
+
 #endif /* __ASM_SPINLOCK_H */
index 95b3abf4851bb9cc70596edd3a239076910939ee..7c9568d30307ff46ffafec33122de19d4f4f9e29 100644 (file)
@@ -127,6 +127,12 @@ static inline int cpu_is_xsc3(void)
 }
 #endif
 
+#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
+#define        cpu_is_xscale() 0
+#else
+#define        cpu_is_xscale() 1
+#endif
+
 #define set_cr(x)                                      \
        __asm__ __volatile__(                           \
        "mcr    p15, 0, %0, c1, c0, 0   @ set CR"       \
index 358e4d309ceb179776f2a7036dabce02cdfad1d2..c2059a3a06216cb936a163255501e20d464c6b21 100644 (file)
@@ -159,17 +159,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
 #define lazy_mmu_prot_update(pte)      do { } while (0)
 #endif
 
-#ifndef __HAVE_ARCH_MULTIPLE_ZERO_PAGE
+#ifndef __HAVE_ARCH_MOVE_PTE
 #define move_pte(pte, prot, old_addr, new_addr)        (pte)
-#else
-#define move_pte(pte, prot, old_addr, new_addr)                                \
-({                                                                     \
-       pte_t newpte = (pte);                                           \
-       if (pte_present(pte) && pfn_valid(pte_pfn(pte)) &&              \
-                       pte_page(pte) == ZERO_PAGE(old_addr))           \
-               newpte = mk_pte(ZERO_PAGE(new_addr), (prot));           \
-       newpte;                                                         \
-})
 #endif
 
 /*
index 818b9a97e214280c0c6a93af52699028e32a95bb..dff2a0a52f8f300e6979b79a2848c88c71b42cd6 100644 (file)
@@ -51,6 +51,7 @@
 #define PRID_IMP_R4300         0x0b00
 #define PRID_IMP_VR41XX                0x0c00
 #define PRID_IMP_R12000                0x0e00
+#define PRID_IMP_R14000                0x0f00
 #define PRID_IMP_R8000         0x1000
 #define PRID_IMP_PR4450                0x1200
 #define PRID_IMP_R4600         0x2000
@@ -87,6 +88,7 @@
 #define PRID_IMP_24K           0x9300
 #define PRID_IMP_34K           0x9500
 #define PRID_IMP_24KE          0x9600
+#define PRID_IMP_74K           0x9700
 
 /*
  * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
 #define CPU_34K                        60
 #define CPU_PR4450             61
 #define CPU_SB1A               62
-#define CPU_LAST               62
+#define CPU_74K                        63
+#define CPU_R14000             64
+#define CPU_LAST               64
 
 /*
  * ISA Level encodings
index a554089991f26ce3407da2e1d26b9904dd025800..12d118f1bc9c7768d3a2e14b9ed0458e5569feb6 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/futex.h>
 #include <asm/errno.h>
 #include <asm/uaccess.h>
+#include <asm/war.h>
 
 #ifdef CONFIG_SMP
 #define __FUTEX_SMP_SYNC "     sync                                    \n"
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)             \
 {                                                                      \
-       __asm__ __volatile__(                                           \
-       "       .set    push                                    \n"     \
-       "       .set    noat                                    \n"     \
-       "       .set    mips3                                   \n"     \
-       "1:     ll      %1, (%3)        # __futex_atomic_op1    \n"     \
-       "       .set    mips0                                   \n"     \
-       "       " insn  "                                       \n"     \
-       "       .set    mips3                                   \n"     \
-       "2:     sc      $1, (%3)                                \n"     \
-       "       beqzl   $1, 1b                                  \n"     \
-       __FUTEX_SMP_SYNC                                                \
-       "3:                                                     \n"     \
-       "       .set    pop                                     \n"     \
-       "       .set    mips0                                   \n"     \
-       "       .section .fixup,\"ax\"                          \n"     \
-       "4:     li      %0, %5                                  \n"     \
-       "       j       2b                                      \n"     \
-       "       .previous                                       \n"     \
-       "       .section __ex_table,\"a\"                       \n"     \
-       "       "__UA_ADDR "\t1b, 4b                            \n"     \
-       "       "__UA_ADDR "\t2b, 4b                            \n"     \
-       "       .previous                                       \n"     \
-       : "=r" (ret), "=r" (oldval)                                     \
-       : "0" (0), "r" (uaddr), "Jr" (oparg), "i" (-EFAULT));           \
+       if (cpu_has_llsc && R10000_LLSC_WAR) {                          \
+               __asm__ __volatile__(                                   \
+               "       .set    push                            \n"     \
+               "       .set    noat                            \n"     \
+               "       .set    mips3                           \n"     \
+               "1:     ll      %1, (%3)        # __futex_atomic_op     \n" \
+               "       .set    mips0                           \n"     \
+               "       " insn  "                               \n"     \
+               "       .set    mips3                           \n"     \
+               "2:     sc      $1, (%3)                        \n"     \
+               "       beqzl   $1, 1b                          \n"     \
+               __FUTEX_SMP_SYNC                                        \
+               "3:                                             \n"     \
+               "       .set    pop                             \n"     \
+               "       .set    mips0                           \n"     \
+               "       .section .fixup,\"ax\"                  \n"     \
+               "4:     li      %0, %5                          \n"     \
+               "       j       2b                              \n"     \
+               "       .previous                               \n"     \
+               "       .section __ex_table,\"a\"               \n"     \
+               "       "__UA_ADDR "\t1b, 4b                    \n"     \
+               "       "__UA_ADDR "\t2b, 4b                    \n"     \
+               "       .previous                               \n"     \
+               : "=r" (ret), "=r" (oldval)                             \
+               : "0" (0), "r" (uaddr), "Jr" (oparg), "i" (-EFAULT));   \
+       } else if (cpu_has_llsc) {                                      \
+               __asm__ __volatile__(                                   \
+               "       .set    push                            \n"     \
+               "       .set    noat                            \n"     \
+               "       .set    mips3                           \n"     \
+               "1:     ll      %1, (%3)        # __futex_atomic_op     \n" \
+               "       .set    mips0                           \n"     \
+               "       " insn  "                               \n"     \
+               "       .set    mips3                           \n"     \
+               "2:     sc      $1, (%3)                        \n"     \
+               "       beqz    $1, 1b                          \n"     \
+               __FUTEX_SMP_SYNC                                        \
+               "3:                                             \n"     \
+               "       .set    pop                             \n"     \
+               "       .set    mips0                           \n"     \
+               "       .section .fixup,\"ax\"                  \n"     \
+               "4:     li      %0, %5                          \n"     \
+               "       j       2b                              \n"     \
+               "       .previous                               \n"     \
+               "       .section __ex_table,\"a\"               \n"     \
+               "       "__UA_ADDR "\t1b, 4b                    \n"     \
+               "       "__UA_ADDR "\t2b, 4b                    \n"     \
+               "       .previous                               \n"     \
+               : "=r" (ret), "=r" (oldval)                             \
+               : "0" (0), "r" (uaddr), "Jr" (oparg), "i" (-EFAULT));   \
+       } else                                                          \
+               ret = -ENOSYS;                                          \
 }
 
 static inline int
@@ -102,7 +131,69 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
 static inline int
 futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
 {
-       return -ENOSYS;
+       int retval;
+
+       if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+               return -EFAULT;
+
+       if (cpu_has_llsc && R10000_LLSC_WAR) {
+               __asm__ __volatile__(
+               "# futex_atomic_cmpxchg_inatomic                        \n"
+               "       .set    push                                    \n"
+               "       .set    noat                                    \n"
+               "       .set    mips3                                   \n"
+               "1:     ll      %0, %2                                  \n"
+               "       bne     %0, %z3, 3f                             \n"
+               "       .set    mips0                                   \n"
+               "       move    $1, %z4                                 \n"
+               "       .set    mips3                                   \n"
+               "2:     sc      $1, %1                                  \n"
+               "       beqzl   $1, 1b                                  \n"
+               __FUTEX_SMP_SYNC
+               "3:                                                     \n"
+               "       .set    pop                                     \n"
+               "       .section .fixup,\"ax\"                          \n"
+               "4:     li      %0, %5                                  \n"
+               "       j       3b                                      \n"
+               "       .previous                                       \n"
+               "       .section __ex_table,\"a\"                       \n"
+               "       "__UA_ADDR "\t1b, 4b                            \n"
+               "       "__UA_ADDR "\t2b, 4b                            \n"
+               "       .previous                                       \n"
+               : "=&r" (retval), "=R" (*uaddr)
+               : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT)
+               : "memory");
+       } else if (cpu_has_llsc) {
+               __asm__ __volatile__(
+               "# futex_atomic_cmpxchg_inatomic                        \n"
+               "       .set    push                                    \n"
+               "       .set    noat                                    \n"
+               "       .set    mips3                                   \n"
+               "1:     ll      %0, %2                                  \n"
+               "       bne     %0, %z3, 3f                             \n"
+               "       .set    mips0                                   \n"
+               "       move    $1, %z4                                 \n"
+               "       .set    mips3                                   \n"
+               "2:     sc      $1, %1                                  \n"
+               "       beqz    $1, 1b                                  \n"
+               __FUTEX_SMP_SYNC
+               "3:                                                     \n"
+               "       .set    pop                                     \n"
+               "       .section .fixup,\"ax\"                          \n"
+               "4:     li      %0, %5                                  \n"
+               "       j       3b                                      \n"
+               "       .previous                                       \n"
+               "       .section __ex_table,\"a\"                       \n"
+               "       "__UA_ADDR "\t1b, 4b                            \n"
+               "       "__UA_ADDR "\t2b, 4b                            \n"
+               "       .previous                                       \n"
+               : "=&r" (retval), "=R" (*uaddr)
+               : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT)
+               : "memory");
+       } else
+               return -ENOSYS;
+
+       return retval;
 }
 
 #endif
index e0745f4ff6240292f0cdb510534bb67aee2157b7..1ed8d0f62577d4e01246d2834e2da4fed935ac85 100644 (file)
@@ -6,6 +6,7 @@
  * for more details.
  *
  * Copyright (C) 1996, 2000 by Ralf Baechle
+ * Copyright (C) 2006 by Thiemo Seufer
  */
 #ifndef _ASM_INST_H
 #define _ASM_INST_H
@@ -21,14 +22,14 @@ enum major_op {
        cop0_op, cop1_op, cop2_op, cop1x_op,
        beql_op, bnel_op, blezl_op, bgtzl_op,
        daddi_op, daddiu_op, ldl_op, ldr_op,
-       major_1c_op, jalx_op, major_1e_op, major_1f_op,
+       spec2_op, jalx_op, mdmx_op, spec3_op,
        lb_op, lh_op, lwl_op, lw_op,
        lbu_op, lhu_op, lwr_op, lwu_op,
        sb_op, sh_op, swl_op, sw_op,
        sdl_op, sdr_op, swr_op, cache_op,
        ll_op, lwc1_op, lwc2_op, pref_op,
        lld_op, ldc1_op, ldc2_op, ld_op,
-       sc_op, swc1_op, swc2_op, rdhwr_op,
+       sc_op, swc1_op, swc2_op, major_3b_op,
        scd_op, sdc1_op, sdc2_op, sd_op
 };
 
@@ -37,7 +38,7 @@ enum major_op {
  */
 enum spec_op {
        sll_op, movc_op, srl_op, sra_op,
-       sllv_op, srlv_op, srav_op, spec1_unused_op, /* Opcode 0x07 is unused */
+       sllv_op, pmon_op, srlv_op, srav_op,
        jr_op, jalr_op, movz_op, movn_op,
        syscall_op, break_op, spim_op, sync_op,
        mfhi_op, mthi_op, mflo_op, mtlo_op,
@@ -54,6 +55,28 @@ enum spec_op {
        dsll32_op, spec8_unused_op, dsrl32_op, dsra32_op
 };
 
+/*
+ * func field of spec2 opcode.
+ */
+enum spec2_op {
+       madd_op, maddu_op, mul_op, spec2_3_unused_op,
+       msub_op, msubu_op, /* more unused ops */
+       clz_op = 0x20, clo_op,
+       dclz_op = 0x24, dclo_op,
+       sdbpp_op = 0x3f
+};
+
+/*
+ * func field of spec3 opcode.
+ */
+enum spec3_op {
+       ext_op, dextm_op, dextu_op, dext_op,
+       ins_op, dinsm_op, dinsu_op, dins_op,
+       bshfl_op = 0x20,
+       dbshfl_op = 0x24,
+       rdhwr_op = 0x3f
+};
+
 /*
  * rt field of bcond opcodes.
  */
@@ -151,8 +174,8 @@ enum cop1x_func {
  * func field for mad opcodes (MIPS IV).
  */
 enum mad_func {
-       madd_op      = 0x08, msub_op      = 0x0a,
-       nmadd_op     = 0x0c, nmsub_op     = 0x0e
+       madd_fp_op      = 0x08, msub_fp_op      = 0x0a,
+       nmadd_fp_op     = 0x0c, nmsub_fp_op     = 0x0e
 };
 
 /*
index a2ef579f6b1a26d8e87d3b5c19b405629dfe0b29..5af7517fce8a8a83cd426013633e59221a88b6ef 100644 (file)
 #define ST0_DL                 (_ULCAST_(1) << 24)
 
 /*
- * Enable the MIPS DSP ASE
+ * Enable the MIPS MDMX and DSP ASEs
  */
 #define ST0_MX                 0x01000000
 
index 702a28fa7a3489d01c2ff986c7dfd0adefebe0bc..f80fe75c780063c28805cd4ee183a2f3c0ab7e95 100644 (file)
@@ -70,7 +70,15 @@ extern unsigned long zero_page_mask;
 #define ZERO_PAGE(vaddr) \
        (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
 
-#define __HAVE_ARCH_MULTIPLE_ZERO_PAGE
+#define __HAVE_ARCH_MOVE_PTE
+#define move_pte(pte, prot, old_addr, new_addr)                                \
+({                                                                     \
+       pte_t newpte = (pte);                                           \
+       if (pte_present(pte) && pfn_valid(pte_pfn(pte)) &&              \
+                       pte_page(pte) == ZERO_PAGE(old_addr))           \
+               newpte = mk_pte(ZERO_PAGE(new_addr), (prot));           \
+       newpte;                                                         \
+})
 
 extern void paging_init(void);
 
@@ -82,10 +90,11 @@ extern void paging_init(void);
 #define pmd_page(pmd)          (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
 #define pmd_page_kernel(pmd)   pmd_val(pmd)
 
-#define pte_none(pte)          (!(pte_val(pte) & ~_PAGE_GLOBAL))
-#define pte_present(pte)       (pte_val(pte) & _PAGE_PRESENT)
-
 #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
+
+#define pte_none(pte)          (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL))
+#define pte_present(pte)       ((pte).pte_low & _PAGE_PRESENT)
+
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
        ptep->pte_high = pte.pte_high;
@@ -93,27 +102,35 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
        ptep->pte_low = pte.pte_low;
        //printk("pte_high %x pte_low %x\n", ptep->pte_high, ptep->pte_low);
 
-       if (pte_val(pte) & _PAGE_GLOBAL) {
+       if (pte.pte_low & _PAGE_GLOBAL) {
                pte_t *buddy = ptep_buddy(ptep);
                /*
                 * Make sure the buddy is global too (if it's !none,
                 * it better already be global)
                 */
-               if (pte_none(*buddy))
-                       buddy->pte_low |= _PAGE_GLOBAL;
+               if (pte_none(*buddy)) {
+                       buddy->pte_low  |= _PAGE_GLOBAL;
+                       buddy->pte_high |= _PAGE_GLOBAL;
+               }
        }
 }
 #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
+       pte_t null = __pte(0);
+
        /* Preserve global status for the pair */
-       if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
-               set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL));
-       else
-               set_pte_at(mm, addr, ptep, __pte(0));
+       if (ptep_buddy(ptep)->pte_low & _PAGE_GLOBAL)
+               null.pte_low = null.pte_high = _PAGE_GLOBAL;
+
+       set_pte_at(mm, addr, ptep, null);
 }
 #else
+
+#define pte_none(pte)          (!(pte_val(pte) & ~_PAGE_GLOBAL))
+#define pte_present(pte)       (pte_val(pte) & _PAGE_PRESENT)
+
 /*
  * Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
@@ -174,75 +191,76 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  */
 static inline int pte_user(pte_t pte)  { BUG(); return 0; }
 #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1)
-static inline int pte_read(pte_t pte)  { return (pte).pte_low & _PAGE_READ; }
-static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_WRITE; }
-static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_MODIFIED; }
-static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; }
-static inline int pte_file(pte_t pte)  { return (pte).pte_low & _PAGE_FILE; }
+static inline int pte_read(pte_t pte)  { return pte.pte_low & _PAGE_READ; }
+static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; }
+static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)  { return pte.pte_low & _PAGE_FILE; }
+
 static inline pte_t pte_wrprotect(pte_t pte)
 {
-       (pte).pte_low &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
-       (pte).pte_high &= ~_PAGE_SILENT_WRITE;
+       pte.pte_low  &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
+       pte.pte_high &= ~_PAGE_SILENT_WRITE;
        return pte;
 }
 
 static inline pte_t pte_rdprotect(pte_t pte)
 {
-       (pte).pte_low &= ~(_PAGE_READ | _PAGE_SILENT_READ);
-       (pte).pte_high &= ~_PAGE_SILENT_READ;
+       pte.pte_low  &= ~(_PAGE_READ | _PAGE_SILENT_READ);
+       pte.pte_high &= ~_PAGE_SILENT_READ;
        return pte;
 }
 
 static inline pte_t pte_mkclean(pte_t pte)
 {
-       (pte).pte_low &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
-       (pte).pte_high &= ~_PAGE_SILENT_WRITE;
+       pte.pte_low  &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE);
+       pte.pte_high &= ~_PAGE_SILENT_WRITE;
        return pte;
 }
 
 static inline pte_t pte_mkold(pte_t pte)
 {
-       (pte).pte_low &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
-       (pte).pte_high &= ~_PAGE_SILENT_READ;
+       pte.pte_low  &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
+       pte.pte_high &= ~_PAGE_SILENT_READ;
        return pte;
 }
 
 static inline pte_t pte_mkwrite(pte_t pte)
 {
-       (pte).pte_low |= _PAGE_WRITE;
-       if ((pte).pte_low & _PAGE_MODIFIED) {
-               (pte).pte_low |= _PAGE_SILENT_WRITE;
-               (pte).pte_high |= _PAGE_SILENT_WRITE;
+       pte.pte_low |= _PAGE_WRITE;
+       if (pte.pte_low & _PAGE_MODIFIED) {
+               pte.pte_low  |= _PAGE_SILENT_WRITE;
+               pte.pte_high |= _PAGE_SILENT_WRITE;
        }
        return pte;
 }
 
 static inline pte_t pte_mkread(pte_t pte)
 {
-       (pte).pte_low |= _PAGE_READ;
-       if ((pte).pte_low & _PAGE_ACCESSED) {
-               (pte).pte_low |= _PAGE_SILENT_READ;
-               (pte).pte_high |= _PAGE_SILENT_READ;
+       pte.pte_low |= _PAGE_READ;
+       if (pte.pte_low & _PAGE_ACCESSED) {
+               pte.pte_low  |= _PAGE_SILENT_READ;
+               pte.pte_high |= _PAGE_SILENT_READ;
        }
        return pte;
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
-       (pte).pte_low |= _PAGE_MODIFIED;
-       if ((pte).pte_low & _PAGE_WRITE) {
-               (pte).pte_low |= _PAGE_SILENT_WRITE;
-               (pte).pte_high |= _PAGE_SILENT_WRITE;
+       pte.pte_low |= _PAGE_MODIFIED;
+       if (pte.pte_low & _PAGE_WRITE) {
+               pte.pte_low  |= _PAGE_SILENT_WRITE;
+               pte.pte_high |= _PAGE_SILENT_WRITE;
        }
        return pte;
 }
 
 static inline pte_t pte_mkyoung(pte_t pte)
 {
-       (pte).pte_low |= _PAGE_ACCESSED;
-       if ((pte).pte_low & _PAGE_READ)
-               (pte).pte_low |= _PAGE_SILENT_READ;
-               (pte).pte_high |= _PAGE_SILENT_READ;
+       pte.pte_low |= _PAGE_ACCESSED;
+       if (pte.pte_low & _PAGE_READ)
+               pte.pte_low  |= _PAGE_SILENT_READ;
+               pte.pte_high |= _PAGE_SILENT_READ;
        return pte;
 }
 #else
index 8edabb0be23f64f8cb576178fde9c2643b93e12b..cefa657dd04a86268923122e5bb8fce3ec1fa480 100644 (file)
@@ -55,8 +55,14 @@ struct sigcontext {
 struct sigcontext {
        unsigned long   sc_regs[32];
        unsigned long   sc_fpregs[32];
-       unsigned long   sc_hi[4];
-       unsigned long   sc_lo[4];
+       unsigned long   sc_mdhi;
+       unsigned long   sc_hi1;
+       unsigned long   sc_hi2;
+       unsigned long   sc_hi3;
+       unsigned long   sc_mdlo;
+       unsigned long   sc_lo1;
+       unsigned long   sc_lo2;
+       unsigned long   sc_lo3;
        unsigned long   sc_pc;
        unsigned int    sc_fpc_csr;
        unsigned int    sc_used_math;
index ebf6055481dcb0f4547ecd5c9f1d6e7c1afea896..6d533b07aaf52daa3e1911df34fffcc6bf788d4d 100644 (file)
@@ -153,6 +153,7 @@ struct termios {
 #define HUPCL  00040000
 
 #define CLOCAL 00100000
+#define CMSPAR   010000000000          /* mark or space (stick) parity */
 #define CRTSCTS          020000000000          /* flow control */
 
 /* c_lflag bits */
index 908acb44cb8a11919637ea95673fba336557290b..edde2462bf52d59709e4c1cf6ffd1e61205707a6 100644 (file)
 #define __NR_readlinkat                296
 #define __NR_fchmodat          297
 #define __NR_faccessat         298
+#define __NR_get_robust_list   299
+#define __NR_set_robust_list   300
 
-#define __NR_syscalls          299
+#define __NR_syscalls          301
 
 #ifdef __KERNEL__
 #define __NR__exit __NR_exit
index f5611a721fbd6e5024d172faaffd4e0ee3a5fc28..45a576507785df07ed0969b9e97b1eb5248f391c 100644 (file)
 #define __NR_pselect6          297
 #define __NR_ppoll             298
 #define __NR_unshare           299
+#define __NR_set_robust_list   300
+#define __NR_get_robust_list   301
 
-/* WARNING: You MAY NOT add syscall numbers larger than 299, since
+/* WARNING: You MAY NOT add syscall numbers larger than 301, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 299 entries (starting at zero).  Therefore
- *          find a free slot in the 0-299 range.
+ *          sized to have 301 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-301 range.
  */
 
 #define _syscall0(type,name) \
index c7d5804ba76df1a1e458746cea57a828cbe93ac2..a8d39f23d43b7755023541770b35e3fa1e2c88b2 100644 (file)
@@ -4,7 +4,146 @@
 #include <linux/config.h>
 
 #ifdef CONFIG_PCI
-#include <asm-generic/dma-mapping.h>
+
+/* we implement the API below in terms of the existing PCI one,
+ * so include it */
+#include <linux/pci.h>
+/* need struct page definitions */
+#include <linux/mm.h>
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       return pci_dma_supported(to_pci_dev(dev), mask);
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 dma_mask)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
+}
+
+static inline void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+                  gfp_t flag)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       return pci_iommu_ops->alloc_consistent(to_pci_dev(dev), size, dma_handle, flag);
+}
+
+static inline void
+dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+                   dma_addr_t dma_handle)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+                enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+            unsigned long offset, size_t size,
+            enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction);
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+              enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction);
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+          enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+            enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
+}
+
+static inline void
+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
+                       enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle,
+                                   size, (int)direction);
+}
+
+static inline void
+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
+                          enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle,
+                                      size, (int)direction);
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+                   enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, nelems, (int)direction);
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
+                      enum dma_data_direction direction)
+{
+       BUG_ON(dev->bus != &pci_bus_type);
+
+       pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, nelems, (int)direction);
+}
+
+static inline int
+dma_mapping_error(dma_addr_t dma_addr)
+{
+       return pci_dma_mapping_error(dma_addr);
+}
+
 #else
 
 struct device;
index 7c5a589ea437a62e082a0808c99c3e15719b101e..e1ea67bc32f22f515db611a2874358679932133a 100644 (file)
@@ -42,7 +42,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
 struct pci_dev;
 
 struct pci_iommu_ops {
-       void *(*alloc_consistent)(struct pci_dev *, size_t, dma_addr_t *);
+       void *(*alloc_consistent)(struct pci_dev *, size_t, dma_addr_t *, gfp_t);
        void (*free_consistent)(struct pci_dev *, size_t, void *, dma_addr_t);
        dma_addr_t (*map_single)(struct pci_dev *, void *, size_t, int);
        void (*unmap_single)(struct pci_dev *, dma_addr_t, size_t, int);
@@ -59,7 +59,7 @@ extern struct pci_iommu_ops *pci_iommu_ops;
  */
 static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
 {
-       return pci_iommu_ops->alloc_consistent(hwdev, size, dma_handle);
+       return pci_iommu_ops->alloc_consistent(hwdev, size, dma_handle, GFP_ATOMIC);
 }
 
 /* Free and unmap a consistent DMA buffer.
index c44e7466534e9dab3f4d1cd3c5936cec1b45a80b..cd464f469a2c2b27fe5d157e684e30b2b4fbf051 100644 (file)
@@ -689,6 +689,23 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *p
 #define pte_clear(mm,addr,ptep)                \
        set_pte_at((mm), (addr), (ptep), __pte(0UL))
 
+#ifdef DCACHE_ALIASING_POSSIBLE
+#define __HAVE_ARCH_MOVE_PTE
+#define move_pte(pte, prot, old_addr, new_addr)                                \
+({                                                                     \
+       pte_t newpte = (pte);                                           \
+       if (tlb_type != hypervisor && pte_present(pte)) {               \
+               unsigned long this_pfn = pte_pfn(pte);                  \
+                                                                       \
+               if (pfn_valid(this_pfn) &&                              \
+                   (((old_addr) ^ (new_addr)) & (1 << 13)))            \
+                       flush_dcache_page_all(current->mm,              \
+                                             pfn_to_page(this_pfn));   \
+       }                                                               \
+       newpte;                                                         \
+})
+#endif
+
 extern pgd_t swapper_pg_dir[2048];
 extern pmd_t swapper_low_pmd_dir[2048];
 
index 68705748bec0f164b52a2bebc83b8c265fbe1d73..998ef4ab0e068fbcf564f4b0fbdf05a2744f3663 100644 (file)
 #define __NR_pselect6          297
 #define __NR_ppoll             298
 #define __NR_unshare           299
+#define __NR_set_robust_list   300
+#define __NR_get_robust_list   301
 
-/* WARNING: You MAY NOT add syscall numbers larger than 299, since
+/* WARNING: You MAY NOT add syscall numbers larger than 301, since
  *          all of the syscall tables in the Sparc kernel are
- *          sized to have 299 entries (starting at zero).  Therefore
- *          find a free slot in the 0-299 range.
+ *          sized to have 301 entries (starting at zero).  Therefore
+ *          find a free slot in the 0-301 range.
  */
 
 #define _syscall0(type,name) \
index c98633af07d26abb0ee6776f90c6eef7dd60008f..b4f8f4a41a6e93fbebddbd3a399b1c932dd23387 100644 (file)
@@ -159,7 +159,7 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
 
 /* 1GB for 64bit, 8MB for 32bit */
-#define STACK_RND_MASK (is_compat_task() ? 0x7ff : 0x3fffff)
+#define STACK_RND_MASK (test_thread_flag(TIF_IA32) ? 0x7ff : 0x3fffff)
 
 #endif
 
index 2d716080be4af7bd98fad2a5a45cd4b884812cd0..33d8f2087b6ea92557c6497a605e3f925e7700e4 100644 (file)
@@ -19,5 +19,4 @@ int request_firmware_nowait(
        void (*cont)(const struct firmware *fw, void *context));
 
 void release_firmware(const struct firmware *fw);
-void register_firmware(const char *name, const u8 *data, size_t size);
 #endif
index 3de2bfb2410ffcdc0449a7b5cbe5d1eee1dc54a2..f813bc8266aa592455caba8d264b90419544c5cc 100644 (file)
@@ -213,6 +213,10 @@ extern int dir_notify_enable;
 #define FIBMAP    _IO(0x00,1)  /* bmap access */
 #define FIGETBSZ   _IO(0x00,2) /* get the block size used for bmap */
 
+#define SYNC_FILE_RANGE_WAIT_BEFORE    1
+#define SYNC_FILE_RANGE_WRITE          2
+#define SYNC_FILE_RANGE_WAIT_AFTER     4
+
 #ifdef __KERNEL__
 
 #include <linux/linkage.h>
@@ -758,9 +762,6 @@ extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
 extern int fcntl_getlease(struct file *filp);
 
 /* fs/sync.c */
-#define SYNC_FILE_RANGE_WAIT_BEFORE    1
-#define SYNC_FILE_RANGE_WRITE          2
-#define SYNC_FILE_RANGE_WAIT_AFTER     4
 extern int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte,
                        unsigned int flags);
 
index a3a0e078f79d61b9eff557494f06e095ce09bc2c..16fbe59edeb1853958afacdfee91981195adf124 100644 (file)
@@ -110,5 +110,16 @@ struct fsl_usb2_platform_data {
 #define FSL_USB2_PORT0_ENABLED 0x00000001
 #define FSL_USB2_PORT1_ENABLED 0x00000002
 
+struct fsl_spi_platform_data {
+       u32     initial_spmode; /* initial SPMODE value */
+       u16     bus_num;
+
+       /* board specific information */
+       u16     max_chipselect;
+       void    (*activate_cs)(u8 cs, u8 polarity);
+       void    (*deactivate_cs)(u8 cs, u8 polarity);
+       u32     sysclk;
+};
+
 #endif                         /* _FSL_DEVICE_H_ */
 #endif                         /* __KERNEL__ */
index 50e338d2ffda9cb5a835d67849e38ae0ceba1647..ce1a756c4c30ba260b316c750178fb51aaf69f0c 100644 (file)
@@ -345,6 +345,8 @@ struct input_absinfo {
 #define KEY_SAVE               234
 #define KEY_DOCUMENTS          235
 
+#define KEY_BATTERY            236
+
 #define KEY_UNKNOWN            240
 
 #define BTN_MISC               0x100
@@ -577,14 +579,9 @@ struct input_absinfo {
  * Switch events
  */
 
-#define SW_0                   0x00
-#define SW_1                   0x01
-#define SW_2                   0x02
-#define SW_3                   0x03
-#define SW_4                   0x04
-#define SW_5                   0x05
-#define SW_6                   0x06
-#define SW_7                   0x07
+#define SW_LID                 0x00  /* set = lid shut */
+#define SW_TABLET_MODE         0x01  /* set = tablet mode */
+#define SW_HEADPHONE_INSERT    0x02  /* set = inserted */
 #define SW_MAX                 0x0f
 
 /*
index bdc556d884989c9e51f6c46b915f4efb146e162b..03a14a30c46a1230d57443007783e466b519450b 100644 (file)
@@ -69,6 +69,7 @@ struct mmc_data {
        unsigned int            timeout_ns;     /* data timeout (in ns, max 80ms) */
        unsigned int            timeout_clks;   /* data timeout (in clocks) */
        unsigned int            blksz_bits;     /* data block size */
+       unsigned int            blksz;          /* data block size */
        unsigned int            blocks;         /* number of blocks */
        unsigned int            error;          /* data error */
        unsigned int            flags;
index b5c21122c2996bcee2a449188748f35e561ca0c9..36740354d4db474c7034beaff63f558891f1f6bc 100644 (file)
@@ -22,6 +22,7 @@
 #else
 #define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
 #endif
+#define MAX_ORDER_NR_PAGES (1 << (MAX_ORDER - 1))
 
 struct free_area {
        struct list_head        free_list;
index d6fe048376ab02010a1709b6dcce4e94f4b70601..590dc6dca3157d1f3cc96c708576325e6fc5e088 100644 (file)
 #define PCI_DEVICE_ID_VIA_8380_0       0x0204
 #define PCI_DEVICE_ID_VIA_3238_0       0x0238
 #define PCI_DEVICE_ID_VIA_PT880                0x0258
+#define PCI_DEVICE_ID_VIA_PT880ULTRA   0x0308
 #define PCI_DEVICE_ID_VIA_PX8X0_0      0x0259
 #define PCI_DEVICE_ID_VIA_3269_0       0x0269
 #define PCI_DEVICE_ID_VIA_K8T800PRO_0  0x0282
index 3996960fc5654e3da43c6b53259101f893bddd2f..60d49e5456e79c273e6732d1fcf0b15dce1159f4 100644 (file)
@@ -52,6 +52,7 @@ struct utimbuf;
 struct mq_attr;
 struct compat_stat;
 struct compat_timeval;
+struct robust_list_head;
 
 #include <linux/config.h>
 #include <linux/types.h>
@@ -581,5 +582,10 @@ asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags);
 
 asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
                                        unsigned int flags);
+asmlinkage long sys_get_robust_list(int pid,
+                                   struct robust_list_head __user **head_ptr,
+                                   size_t __user *len_ptr);
+asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
+                                   size_t len);
 
 #endif
index d7670ec1ec1e1dfc2c348179f92c17e8dac81d9a..ad7fa9c86c1008157211021ce5f23829368d6ff0 100644 (file)
@@ -1141,8 +1141,13 @@ extern char *v4l2_type_names[];
 /*  Compatibility layer interface  --  v4l1-compat module */
 typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file,
                           unsigned int cmd, void *arg);
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
 int v4l_compat_translate_ioctl(struct inode *inode, struct file *file,
                               int cmd, void *arg, v4l2_kioctl driver_ioctl);
+#else
+#define v4l_compat_translate_ioctl(inode,file,cmd,arg,ioctl) -EINVAL
+#endif
 
 /* 32 Bits compatibility layer for 64 bits processors */
 extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd,
index 530ae3f4248ccb6afb3dfe84cee7c1264e32ca38..fab5aed8ca315cc71217dae905e2dda1ac598201 100644 (file)
@@ -73,11 +73,6 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
 int vt_waitactive(int vt);
 void change_console(struct vc_data *new_vc);
 void reset_vc(struct vc_data *vc);
-#ifdef CONFIG_VT
-int is_console_suspend_safe(void);
-#else
-static inline int is_console_suspend_safe(void) { return 1; }
-#endif
 
 /*
  * vc_screen.c shares this temporary buffer with the console write code so that
index 8662b8f43df5d6dc009f068b4b127f6a86589b69..e65cbedb6abcec07e08caedce8ed7785fabcce57 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <linux/config.h>
 
+struct sock;
+
 #if defined(CONFIG_COMPAT)
 
 #include <linux/compat.h>
@@ -23,7 +25,6 @@ struct compat_cmsghdr {
        compat_int_t    cmsg_type;
 };
 
-struct sock;
 extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *);
 
 #else /* defined(CONFIG_COMPAT) */
index 86aefb1fda5e0bba0f24210eb9864b63801fe913..c0c895d379ba1b10ed5a7b39e8c4da3405aea23e 100644 (file)
@@ -112,7 +112,7 @@ struct lsap_cb {
 
        struct timer_list watchdog_timer;
 
-       IRLMP_STATE     lsap_state;  /* Connection state */
+       LSAP_STATE      lsap_state;  /* Connection state */
        notify_t        notify;      /* Indication/Confirm entry points */
        struct qos_info qos;         /* QoS for this connection */
 
index 34a1a09e5aeff93927fb058be18e79e6afbf32df..807d6f1ef4b505bd302de0281aee75fc71a2b50a 100644 (file)
@@ -99,6 +99,7 @@ typedef enum {
        SCTP_CMD_DEL_NON_PRIMARY, /* Removes non-primary peer transports. */
        SCTP_CMD_T3_RTX_TIMERS_STOP, /* Stops T3-rtx pending timers */
        SCTP_CMD_FORCE_PRIM_RETRAN,  /* Forces retrans. over primary path. */
+       SCTP_CMD_SET_SK_ERR,     /* Set sk_err */
        SCTP_CMD_LAST
 } sctp_verb_t;
 
index e673b2c984e931c9a80d7c5e677bfdc1984fa4c3..aa6033ca7cd859d3614406a54b0d4885e79a94dc 100644 (file)
@@ -461,12 +461,12 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu)
  * there is room for a param header too.
  */
 #define sctp_walk_params(pos, chunk, member)\
-_sctp_walk_params((pos), (chunk), WORD_ROUND(ntohs((chunk)->chunk_hdr.length)), member)
+_sctp_walk_params((pos), (chunk), ntohs((chunk)->chunk_hdr.length), member)
 
 #define _sctp_walk_params(pos, chunk, end, member)\
 for (pos.v = chunk->member;\
      pos.v <= (void *)chunk + end - sizeof(sctp_paramhdr_t) &&\
-     pos.v <= (void *)chunk + end - WORD_ROUND(ntohs(pos.p->length)) &&\
+     pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
      ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
      pos.v += WORD_ROUND(ntohs(pos.p->length)))
 
@@ -477,7 +477,7 @@ _sctp_walk_errors((err), (chunk_hdr), ntohs((chunk_hdr)->length))
 for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
            sizeof(sctp_chunkhdr_t));\
      (void *)err <= (void *)chunk_hdr + end - sizeof(sctp_errhdr_t) &&\
-     (void *)err <= (void *)chunk_hdr + end - WORD_ROUND(ntohs(err->length)) &&\
+     (void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
      ntohs(err->length) >= sizeof(sctp_errhdr_t); \
      err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
 
index 72248d1b9e3f7a18198796ad1134c9abb2fd4b4e..ab81fdd4572bb4b65dad432d69f58f222d3f1aee 100644 (file)
@@ -2231,19 +2231,25 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
  * So only GFP_KERNEL allocations, if all nodes in the cpuset are
  * short of memory, might require taking the callback_mutex mutex.
  *
- * The first loop over the zonelist in mm/page_alloc.c:__alloc_pages()
- * calls here with __GFP_HARDWALL always set in gfp_mask, enforcing
- * hardwall cpusets - no allocation on a node outside the cpuset is
- * allowed (unless in interrupt, of course).
- *
- * The second loop doesn't even call here for GFP_ATOMIC requests
- * (if the __alloc_pages() local variable 'wait' is set).  That check
- * and the checks below have the combined affect in the second loop of
- * the __alloc_pages() routine that:
+ * The first call here from mm/page_alloc:get_page_from_freelist()
+ * has __GFP_HARDWALL set in gfp_mask, enforcing hardwall cpusets, so
+ * no allocation on a node outside the cpuset is allowed (unless in
+ * interrupt, of course).
+ *
+ * The second pass through get_page_from_freelist() doesn't even call
+ * here for GFP_ATOMIC calls.  For those calls, the __alloc_pages()
+ * variable 'wait' is not set, and the bit ALLOC_CPUSET is not set
+ * in alloc_flags.  That logic and the checks below have the combined
+ * affect that:
  *     in_interrupt - any node ok (current task context irrelevant)
  *     GFP_ATOMIC   - any node ok
  *     GFP_KERNEL   - any node in enclosing mem_exclusive cpuset ok
  *     GFP_USER     - only nodes in current tasks mems allowed ok.
+ *
+ * Rule:
+ *    Don't call cpuset_zone_allowed() if you can't sleep, unless you
+ *    pass in the __GFP_HARDWALL flag set in gfp_flag, which disables
+ *    the code that might scan up ancestor cpusets and sleep.
  **/
 
 int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
@@ -2255,6 +2261,7 @@ int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
        if (in_interrupt())
                return 1;
        node = z->zone_pgdat->node_id;
+       might_sleep_if(!(gfp_mask & __GFP_HARDWALL));
        if (node_isset(node, current->mems_allowed))
                return 1;
        if (gfp_mask & __GFP_HARDWALL)  /* If hardwall request, stop here */
index b7f0388bd71c80d32eb29f79b0c0319705a8bd7c..01fa2ae98a8571d7e2d7a4e71c03a423792a0d67 100644 (file)
@@ -456,6 +456,7 @@ hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(hrtimer_start);
 
 /**
  * hrtimer_try_to_cancel - try to deactivate a timer
@@ -484,6 +485,7 @@ int hrtimer_try_to_cancel(struct hrtimer *timer)
        return ret;
 
 }
+EXPORT_SYMBOL_GPL(hrtimer_try_to_cancel);
 
 /**
  * hrtimer_cancel - cancel a timer and wait for the handler to finish.
@@ -504,6 +506,7 @@ int hrtimer_cancel(struct hrtimer *timer)
                cpu_relax();
        }
 }
+EXPORT_SYMBOL_GPL(hrtimer_cancel);
 
 /**
  * hrtimer_get_remaining - get remaining time for the timer
@@ -522,6 +525,7 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)
 
        return rem;
 }
+EXPORT_SYMBOL_GPL(hrtimer_get_remaining);
 
 #ifdef CONFIG_NO_IDLE_HZ
 /**
@@ -580,6 +584,7 @@ void hrtimer_init(struct hrtimer *timer, clockid_t clock_id,
        timer->base = &bases[clock_id];
        timer->node.rb_parent = HRTIMER_INACTIVE;
 }
+EXPORT_SYMBOL_GPL(hrtimer_init);
 
 /**
  * hrtimer_get_res - get the timer resolution for a clock
@@ -599,6 +604,7 @@ int hrtimer_get_res(const clockid_t which_clock, struct timespec *tp)
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(hrtimer_get_res);
 
 /*
  * Expire the per base hrtimer-queue:
index 4c64f85698aee2205c442f3fec09d18a3db5d4a3..c13f1bd2df7d3cd483c47fd76a8163d90ed3cd44 100644 (file)
@@ -664,48 +664,6 @@ static int effective_prio(task_t *p)
        return prio;
 }
 
-/*
- * We place interactive tasks back into the active array, if possible.
- *
- * To guarantee that this does not starve expired tasks we ignore the
- * interactivity of a task if the first expired task had to wait more
- * than a 'reasonable' amount of time. This deadline timeout is
- * load-dependent, as the frequency of array switched decreases with
- * increasing number of running tasks. We also ignore the interactivity
- * if a better static_prio task has expired, and switch periodically
- * regardless, to ensure that highly interactive tasks do not starve
- * the less fortunate for unreasonably long periods.
- */
-static inline int expired_starving(runqueue_t *rq)
-{
-       int limit;
-
-       /*
-        * Arrays were recently switched, all is well
-        */
-       if (!rq->expired_timestamp)
-               return 0;
-
-       limit = STARVATION_LIMIT * rq->nr_running;
-
-       /*
-        * It's time to switch arrays
-        */
-       if (jiffies - rq->expired_timestamp >= limit)
-               return 1;
-
-       /*
-        * There's a better selection in the expired array
-        */
-       if (rq->curr->static_prio > rq->best_expired_prio)
-               return 1;
-
-       /*
-        * All is well
-        */
-       return 0;
-}
-
 /*
  * __activate_task - move a task to the runqueue.
  */
@@ -713,7 +671,7 @@ static void __activate_task(task_t *p, runqueue_t *rq)
 {
        prio_array_t *target = rq->active;
 
-       if (unlikely(batch_task(p) || (expired_starving(rq) && !rt_task(p))))
+       if (batch_task(p))
                target = rq->expired;
        enqueue_task(p, target);
        rq->nr_running++;
@@ -2531,6 +2489,22 @@ unsigned long long current_sched_time(const task_t *tsk)
        return ns;
 }
 
+/*
+ * We place interactive tasks back into the active array, if possible.
+ *
+ * To guarantee that this does not starve expired tasks we ignore the
+ * interactivity of a task if the first expired task had to wait more
+ * than a 'reasonable' amount of time. This deadline timeout is
+ * load-dependent, as the frequency of array switched decreases with
+ * increasing number of running tasks. We also ignore the interactivity
+ * if a better static_prio task has expired:
+ */
+#define EXPIRED_STARVING(rq) \
+       ((STARVATION_LIMIT && ((rq)->expired_timestamp && \
+               (jiffies - (rq)->expired_timestamp >= \
+                       STARVATION_LIMIT * ((rq)->nr_running) + 1))) || \
+                       ((rq)->curr->static_prio > (rq)->best_expired_prio))
+
 /*
  * Account user cpu time to a process.
  * @p: the process that the cpu time gets accounted to
@@ -2666,7 +2640,7 @@ void scheduler_tick(void)
 
                if (!rq->expired_timestamp)
                        rq->expired_timestamp = jiffies;
-               if (!TASK_INTERACTIVE(p) || expired_starving(rq)) {
+               if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
                        enqueue_task(p, rq->expired);
                        if (p->static_prio < rq->best_expired_prio)
                                rq->best_expired_prio = p->static_prio;
index 67eaf0f54096f87162a96daad0b50df11fe5653f..9e49deed468cd8b2e63f2033d2971d961edeb110 100644 (file)
@@ -541,6 +541,22 @@ found:
        }
        spin_unlock(&base->lock);
 
+       /*
+        * It can happen that other CPUs service timer IRQs and increment
+        * jiffies, but we have not yet got a local timer tick to process
+        * the timer wheels.  In that case, the expiry time can be before
+        * jiffies, but since the high-resolution timer here is relative to
+        * jiffies, the default expression when high-resolution timers are
+        * not active,
+        *
+        *   time_before(MAX_JIFFY_OFFSET + jiffies, expires)
+        *
+        * would falsely evaluate to true.  If that is the case, just
+        * return jiffies so that we can immediately fire the local timer
+        */
+       if (time_before(expires, jiffies))
+               return jiffies;
+
        if (time_before(hr_expires, expires))
                return hr_expires;
 
index b46350c278370b3ea799fdd5e220befbb7b83a83..687ab418d292b15084d8a97be48f6003b0d0e315 100644 (file)
@@ -198,14 +198,14 @@ int kobject_add(struct kobject * kobj)
 
                /* be noisy on error issues */
                if (error == -EEXIST)
-                       printk("kobject_add failed for %s with -EEXIST, "
+                       pr_debug("kobject_add failed for %s with -EEXIST, "
                               "don't try to register things with the "
                               "same name in the same directory.\n",
                               kobject_name(kobj));
                else
-                       printk("kobject_add failed for %s (%d)\n",
+                       pr_debug("kobject_add failed for %s (%d)\n",
                               kobject_name(kobj), error);
-               dump_stack();
+               /* dump_stack(); */
        }
 
        return error;
index 1ae2b2cc3a54148a72489416829cf36a26abd81b..70df5c0d957e482f8055fc2ecc596fc173a11a61 100644 (file)
@@ -91,8 +91,8 @@ static void grow_zone_span(struct zone *zone,
        if (start_pfn < zone->zone_start_pfn)
                zone->zone_start_pfn = start_pfn;
 
-       if (end_pfn > old_zone_end_pfn)
-               zone->spanned_pages = end_pfn - zone->zone_start_pfn;
+       zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
+                               zone->zone_start_pfn;
 
        zone_span_writeunlock(zone);
 }
@@ -106,8 +106,8 @@ static void grow_pgdat_span(struct pglist_data *pgdat,
        if (start_pfn < pgdat->node_start_pfn)
                pgdat->node_start_pfn = start_pfn;
 
-       if (end_pfn > old_pgdat_end_pfn)
-               pgdat->node_spanned_pages = end_pfn - pgdat->node_start_pfn;
+       pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
+                                       pgdat->node_start_pfn;
 }
 
 int online_pages(unsigned long pfn, unsigned long nr_pages)
index 813b4ec1298a23ee10e0d091305bd8520ba6fad0..253a450c400df06898de5d864ff2c8863c560043 100644 (file)
@@ -951,7 +951,7 @@ restart:
                goto got_pg;
 
        do {
-               if (cpuset_zone_allowed(*z, gfp_mask))
+               if (cpuset_zone_allowed(*z, gfp_mask|__GFP_HARDWALL))
                        wakeup_kswapd(*z, order);
        } while (*(++z));
 
@@ -970,7 +970,8 @@ restart:
                alloc_flags |= ALLOC_HARDER;
        if (gfp_mask & __GFP_HIGH)
                alloc_flags |= ALLOC_HIGH;
-       alloc_flags |= ALLOC_CPUSET;
+       if (wait)
+               alloc_flags |= ALLOC_CPUSET;
 
        /*
         * Go through the zonelist again. Let __GFP_HIGH and allocations
@@ -2124,14 +2125,22 @@ static void __init alloc_node_mem_map(struct pglist_data *pgdat)
 #ifdef CONFIG_FLAT_NODE_MEM_MAP
        /* ia64 gets its own node_mem_map, before this, without bootmem */
        if (!pgdat->node_mem_map) {
-               unsigned long size;
+               unsigned long size, start, end;
                struct page *map;
 
-               size = (pgdat->node_spanned_pages + 1) * sizeof(struct page);
+               /*
+                * The zone's endpoints aren't required to be MAX_ORDER
+                * aligned but the node_mem_map endpoints must be in order
+                * for the buddy allocator to function correctly.
+                */
+               start = pgdat->node_start_pfn & ~(MAX_ORDER_NR_PAGES - 1);
+               end = pgdat->node_start_pfn + pgdat->node_spanned_pages;
+               end = ALIGN(end, MAX_ORDER_NR_PAGES);
+               size =  (end - start) * sizeof(struct page);
                map = alloc_remap(pgdat->node_id, size);
                if (!map)
                        map = alloc_bootmem_node(pgdat, size);
-               pgdat->node_mem_map = map;
+               pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
        }
 #ifdef CONFIG_FLATMEM
        /*
index d31a06bfbea5c78998e3c68a5a484b98b3e4579f..f1b644eb39d816b3865400caf8d589d458756a17 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -207,11 +207,6 @@ typedef unsigned int kmem_bufctl_t;
 #define        BUFCTL_ACTIVE   (((kmem_bufctl_t)(~0U))-2)
 #define        SLAB_LIMIT      (((kmem_bufctl_t)(~0U))-3)
 
-/* Max number of objs-per-slab for caches which use off-slab slabs.
- * Needed to avoid a possible looping condition in cache_grow().
- */
-static unsigned long offslab_limit;
-
 /*
  * struct slab
  *
@@ -1356,12 +1351,6 @@ void __init kmem_cache_init(void)
                                        NULL, NULL);
                }
 
-               /* Inc off-slab bufctl limit until the ceiling is hit. */
-               if (!(OFF_SLAB(sizes->cs_cachep))) {
-                       offslab_limit = sizes->cs_size - sizeof(struct slab);
-                       offslab_limit /= sizeof(kmem_bufctl_t);
-               }
-
                sizes->cs_dmacachep = kmem_cache_create(names->name_dma,
                                        sizes->cs_size,
                                        ARCH_KMALLOC_MINALIGN,
@@ -1780,6 +1769,7 @@ static void set_up_list3s(struct kmem_cache *cachep, int index)
 static size_t calculate_slab_order(struct kmem_cache *cachep,
                        size_t size, size_t align, unsigned long flags)
 {
+       unsigned long offslab_limit;
        size_t left_over = 0;
        int gfporder;
 
@@ -1791,9 +1781,18 @@ static size_t calculate_slab_order(struct kmem_cache *cachep,
                if (!num)
                        continue;
 
-               /* More than offslab_limit objects will cause problems */
-               if ((flags & CFLGS_OFF_SLAB) && num > offslab_limit)
-                       break;
+               if (flags & CFLGS_OFF_SLAB) {
+                       /*
+                        * Max number of objs-per-slab for caches which
+                        * use off-slab slabs. Needed to avoid a possible
+                        * looping condition in cache_grow().
+                        */
+                       offslab_limit = size - sizeof(struct slab);
+                       offslab_limit /= sizeof(kmem_bufctl_t);
+
+                       if (num > offslab_limit)
+                               break;
+               }
 
                /* Found something acceptable - save it away */
                cachep->num = num;
index c5e89eb9ac8ff10e1e15fced114de41058df4a7e..100040c0dfb6c8e674dada0ed8eb471820e2f75b 100644 (file)
@@ -87,11 +87,8 @@ int __section_nr(struct mem_section* ms)
        unsigned long root_nr;
        struct mem_section* root;
 
-       for (root_nr = 0;
-            root_nr < NR_MEM_SECTIONS;
-            root_nr += SECTIONS_PER_ROOT) {
-               root = __nr_to_section(root_nr);
-
+       for (root_nr = 0; root_nr < NR_SECTION_ROOTS; root_nr++) {
+               root = __nr_to_section(root_nr * SECTIONS_PER_ROOT);
                if (!root)
                        continue;
 
index 22d806cf40caf86d694eb05f2794bc1454c5ee19..12da21afb9ca636bbd438be992cacfa5722b2524 100644 (file)
@@ -55,7 +55,7 @@ static int __init br_init(void)
 
 static void __exit br_deinit(void)
 {
-       llc_sap_close(br_stp_sap);
+       rcu_assign_pointer(br_stp_sap->rcv_func, NULL);
 
 #ifdef CONFIG_BRIDGE_NETFILTER
        br_netfilter_fini();
@@ -67,6 +67,7 @@ static void __exit br_deinit(void)
 
        synchronize_net();
 
+       llc_sap_put(br_stp_sap);
        br_fdb_get_hook = NULL;
        br_fdb_put_hook = NULL;
 
index 2dce673a039b6f4f71888e4780678b35924e7d3e..4fba549caf29911c42f7674310fa35aaa993a36c 100644 (file)
  *             sure which should go first, but I bet it won't make much
  *             difference if we are running VLANs.  The good news is that
  *             this protocol won't be in the list unless compiled in, so
- *             the average user (w/out VLANs) will not be adversly affected.
+ *             the average user (w/out VLANs) will not be adversely affected.
  *             --BLG
  *
  *             0800    IP
@@ -149,7 +149,7 @@ static struct list_head ptype_base[16];     /* 16 way hashed list */
 static struct list_head ptype_all;             /* Taps */
 
 /*
- * The @dev_base list is protected by @dev_base_lock and the rtln
+ * The @dev_base list is protected by @dev_base_lock and the rtnl
  * semaphore.
  *
  * Pure readers hold dev_base_lock for reading.
@@ -641,10 +641,12 @@ int dev_valid_name(const char *name)
  *     @name: name format string
  *
  *     Passed a format string - eg "lt%d" it will try and find a suitable
- *     id. Not efficient for many devices, not called a lot. The caller
- *     must hold the dev_base or rtnl lock while allocating the name and
- *     adding the device in order to avoid duplicates. Returns the number
- *     of the unit assigned or a negative errno code.
+ *     id. It scans list of devices to build up a free map, then chooses
+ *     the first empty slot. The caller must hold the dev_base or rtnl lock
+ *     while allocating the name and adding the device in order to avoid
+ *     duplicates.
+ *     Limited to bits_per_byte * page size devices (ie 32K on most platforms).
+ *     Returns the number of the unit assigned or a negative errno code.
  */
 
 int dev_alloc_name(struct net_device *dev, const char *name)
@@ -744,7 +746,7 @@ int dev_change_name(struct net_device *dev, char *newname)
 }
 
 /**
- *     netdev_features_change - device changes fatures
+ *     netdev_features_change - device changes features
  *     @dev: device to cause notification
  *
  *     Called to indicate a device has changed features.
@@ -2196,7 +2198,7 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
  *     @dev: device
  *     @inc: modifier
  *
- *     Add or remove promsicuity from a device. While the count in the device
+ *     Add or remove promiscuity from a device. While the count in the device
  *     remains above zero the interface remains promiscuous. Once it hits zero
  *     the device reverts back to normal filtering operation. A negative inc
  *     value is used to drop promiscuity on the device.
@@ -3122,7 +3124,7 @@ EXPORT_SYMBOL(alloc_netdev);
 void free_netdev(struct net_device *dev)
 {
 #ifdef CONFIG_SYSFS
-       /*  Compatiablity with error handling in drivers */
+       /*  Compatibility with error handling in drivers */
        if (dev->reg_state == NETREG_UNINITIALIZED) {
                kfree((char *)dev - dev->padded);
                return;
index cd810f41af1a71db684a7787bde2bbc8e5d601f7..95278b22b669ab895903fe039fa3e7d2e1f56a25 100644 (file)
@@ -210,7 +210,7 @@ static void ipcomp4_err(struct sk_buff *skb, u32 info)
            skb->h.icmph->code != ICMP_FRAG_NEEDED)
                return;
 
-       spi = ntohl(ntohs(ipch->cpi));
+       spi = htonl(ntohs(ipch->cpi));
        x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr,
                              spi, IPPROTO_COMP, AF_INET);
        if (!x)
index 3d560dec63ab5dacf2d848191bb62f0069276d7f..d4072533da218e66c8651e9495c50ea9a35a1445 100644 (file)
@@ -170,8 +170,8 @@ config IP_NF_PPTP
          Documentation/modules.txt.  If unsure, say `N'.
 
 config IP_NF_H323
-       tristate  'H.323 protocol support'
-       depends on IP_NF_CONNTRACK
+       tristate  'H.323 protocol support (EXPERIMENTAL)'
+       depends on IP_NF_CONNTRACK && EXPERIMENTAL
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
          important VoIP protocols, it is widely used by voice hardware and
index 979a2eac6f003101438ecd518b1c4d9c2c365bf8..a297da7bbef5dc735d1c68d57fe35b1db901d820 100644 (file)
@@ -1318,6 +1318,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
                        .tuple.dst.u.tcp.port;
                sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
                        .tuple.dst.ip;
+               memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
 
                DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
                       NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
index 355a53a5b6cddf81c5fa42257b3d6a611ab603d7..26dfecadb335681ef8c0b28d778d7ef3001c6a5d 100644 (file)
@@ -528,14 +528,15 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
 
                        /* Decode */
                        if ((err = (Decoders[son->type]) (bs, son, base,
-                                                         level + 1)) >
-                           H323_ERROR_STOP)
+                                                         level + 1)) <
+                           H323_ERROR_NONE)
                                return err;
 
                        bs->cur = beg + len;
                        bs->bit = 0;
                } else if ((err = (Decoders[son->type]) (bs, son, base,
-                                                        level + 1)))
+                                                        level + 1)) <
+                          H323_ERROR_NONE)
                        return err;
        }
 
@@ -554,7 +555,7 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
 
        /* Decode the extension components */
        for (opt = 0; opt < bmp2_len; opt++, i++, son++) {
-               if (son->attr & STOP) {
+               if (i < f->ub && son->attr & STOP) {
                        PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ",
                              son->name);
                        return H323_ERROR_STOP;
@@ -584,8 +585,8 @@ int decode_seq(bitstr_t * bs, field_t * f, char *base, int level)
                beg = bs->cur;
 
                if ((err = (Decoders[son->type]) (bs, son, base,
-                                                 level + 1)) >
-                   H323_ERROR_STOP)
+                                                 level + 1)) <
+                   H323_ERROR_NONE)
                        return err;
 
                bs->cur = beg + len;
@@ -660,18 +661,20 @@ int decode_seqof(bitstr_t * bs, field_t * f, char *base, int level)
                                                          i <
                                                          effective_count ?
                                                          base : NULL,
-                                                         level + 1)) >
-                           H323_ERROR_STOP)
+                                                         level + 1)) <
+                           H323_ERROR_NONE)
                                return err;
 
                        bs->cur = beg + len;
                        bs->bit = 0;
                } else
-                   if ((err = (Decoders[son->type]) (bs, son,
-                                                     i < effective_count ?
-                                                     base : NULL,
-                                                     level + 1)))
-                       return err;
+                       if ((err = (Decoders[son->type]) (bs, son,
+                                                         i <
+                                                         effective_count ?
+                                                         base : NULL,
+                                                         level + 1)) <
+                           H323_ERROR_NONE)
+                               return err;
 
                if (base)
                        base += son->offset;
@@ -735,13 +738,14 @@ int decode_choice(bitstr_t * bs, field_t * f, char *base, int level)
                }
                beg = bs->cur;
 
-               if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) >
-                   H323_ERROR_STOP)
+               if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
+                   H323_ERROR_NONE)
                        return err;
 
                bs->cur = beg + len;
                bs->bit = 0;
-       } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)))
+       } else if ((err = (Decoders[son->type]) (bs, son, base, level + 1)) <
+                  H323_ERROR_NONE)
                return err;
 
        return H323_ERROR_NONE;
index 7d3ba4302e9e3ef0463c79d7e175eed53eb6e4d0..8ccfe17bb253353693bb745c5c9fceff8ffa7de1 100644 (file)
@@ -469,8 +469,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
                        DEBUGP("%s but no session\n", pptp_msg_name[msg]);
                        break;
                }
-               if (info->sstate != PPTP_CALL_IN_REP
-                   && info->sstate != PPTP_CALL_IN_CONF) {
+               if (info->cstate != PPTP_CALL_IN_REP
+                   && info->cstate != PPTP_CALL_IN_CONF) {
                        DEBUGP("%s but never sent IN_CALL_REPLY\n",
                                pptp_msg_name[msg]);
                        break;
index c622538455385d718f66e17e7f5c964d9404f723..c33244263b9035a688c73816487a89c4a5381d62 100644 (file)
@@ -768,6 +768,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
                        len *= sizeof(unsigned long);
                        *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
                        if (*obj == NULL) {
+                               kfree(lp);
                                kfree(id);
                                if (net_ratelimit())
                                        printk("OOM in bsalg (%d)\n", __LINE__);
@@ -1003,12 +1004,12 @@ static unsigned char snmp_trap_decode(struct asn1_ctx *ctx,
                
        return 1;
 
+err_addr_free:
+       kfree((unsigned long *)trap->ip_address);
+
 err_id_free:
        kfree(trap->id);
 
-err_addr_free:
-       kfree((unsigned long *)trap->ip_address);
-       
        return 0;
 }
 
@@ -1126,11 +1127,10 @@ static int snmp_parse_mangle(unsigned char *msg,
                struct snmp_v1_trap trap;
                unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
                
-               /* Discard trap allocations regardless */
-               kfree(trap.id);
-               kfree((unsigned long *)trap.ip_address);
-               
-               if (!ret)
+               if (ret) {
+                       kfree(trap.id);
+                       kfree((unsigned long *)trap.ip_address);
+               } else 
                        return ret;
                
        } else {
index 5bc9f64d7b5b06f9bf1d5a2d8c3923f6fdaccfb9..77d974443c7b6291e54ca4713945a0a53d582167 100644 (file)
@@ -348,6 +348,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
                        .tuple.dst.u.tcp.port;
                sin.sin_addr.s_addr = ct->tuplehash[IP_CT_DIR_ORIGINAL]
                        .tuple.dst.u3.ip;
+               memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
 
                DEBUGP("SO_ORIGINAL_DST: %u.%u.%u.%u %u\n",
                       NIPQUAD(sin.sin_addr.s_addr), ntohs(sin.sin_port));
index b72fa55dfb84d114484bf6f7d1b4751449d9c4e3..ba7c63ca5bb10838f9e81a64b81cf9131be1a3f2 100644 (file)
@@ -135,7 +135,8 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt,
 
                /* Do additive increase */
                if (tp->snd_cwnd < tp->snd_cwnd_clamp) {
-                       tp->snd_cwnd_cnt += ca->ai;
+                       /* cwnd = cwnd + a(w) / cwnd */
+                       tp->snd_cwnd_cnt += ca->ai + 1;
                        if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
                                tp->snd_cwnd_cnt -= tp->snd_cwnd;
                                tp->snd_cwnd++;
index f285bbf296e28d79099887afa2882be75ddf32bc..8604c747bca5fa3d1353159e906ddfcec0da1290 100644 (file)
@@ -221,7 +221,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
                        if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
                                u16 *ipcomp_hdr = (u16 *)xprth;
 
-                               fl->fl_ipsec_spi = ntohl(ntohs(ipcomp_hdr[1]));
+                               fl->fl_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
                        }
                        break;
                default:
index 05eb67def39f17e9c9b84d9270fdbe6fe1ee2a87..48636436028ab2b1ce1b1dfee0bce70b545e0799 100644 (file)
@@ -208,7 +208,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        if (type != ICMPV6_DEST_UNREACH && type != ICMPV6_PKT_TOOBIG)
                return;
 
-       spi = ntohl(ntohs(ipcomph->cpi));
+       spi = htonl(ntohs(ipcomph->cpi));
        x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, IPPROTO_COMP, AF_INET6);
        if (!x)
                return;
index 0190e39096b978692349bd0dbd3e5271a828fab3..8a777932786d7d4c0975fd6941489039abad3d06 100644 (file)
@@ -280,10 +280,13 @@ static int inline rt6_check_neigh(struct rt6_info *rt)
 {
        struct neighbour *neigh = rt->rt6i_nexthop;
        int m = 0;
-       if (neigh) {
+       if (rt->rt6i_flags & RTF_NONEXTHOP ||
+           !(rt->rt6i_flags & RTF_GATEWAY))
+               m = 1;
+       else if (neigh) {
                read_lock_bh(&neigh->lock);
                if (neigh->nud_state & NUD_VALID)
-                       m = 1;
+                       m = 2;
                read_unlock_bh(&neigh->lock);
        }
        return m;
@@ -292,15 +295,18 @@ static int inline rt6_check_neigh(struct rt6_info *rt)
 static int rt6_score_route(struct rt6_info *rt, int oif,
                           int strict)
 {
-       int m = rt6_check_dev(rt, oif);
+       int m, n;
+               
+       m = rt6_check_dev(rt, oif);
        if (!m && (strict & RT6_SELECT_F_IFACE))
                return -1;
 #ifdef CONFIG_IPV6_ROUTER_PREF
        m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
 #endif
-       if (rt6_check_neigh(rt))
+       n = rt6_check_neigh(rt);
+       if (n > 1)
                m |= 16;
-       else if (strict & RT6_SELECT_F_REACHABLE)
+       else if (!n && strict & RT6_SELECT_F_REACHABLE)
                return -1;
        return m;
 }
index 254f9074690011a66e0382fbef5f65892e81b32e..2d2e2b1919f40f70230c1527edbf8bb0c23d5fa4 100644 (file)
@@ -544,7 +544,8 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self,
 {
        struct sk_buff *tx_skb;
        int n;
-       __u32 tmp_be32, tmp_be16;
+       __u32 tmp_be32;
+       __be16 tmp_be16;
        __u8 *fp;
 
        IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
index d117ebc75cf87ce25aa8699f61b4338b12fc1053..1662f9cc869e0a1cd463b7f3575c0c243dfc4ded 100644 (file)
@@ -73,6 +73,8 @@ static struct sctp_association *__sctp_lookup_association(
                                        const union sctp_addr *peer,
                                        struct sctp_transport **pt);
 
+static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
+
 
 /* Calculate the SCTP checksum of an SCTP packet.  */
 static inline int sctp_rcv_checksum(struct sk_buff *skb)
@@ -186,7 +188,6 @@ int sctp_rcv(struct sk_buff *skb)
         */
        if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb)))
        {
-               sock_put(sk);
                if (asoc) {
                        sctp_association_put(asoc);
                        asoc = NULL;
@@ -197,7 +198,6 @@ int sctp_rcv(struct sk_buff *skb)
                sk = sctp_get_ctl_sock();
                ep = sctp_sk(sk)->ep;
                sctp_endpoint_hold(ep);
-               sock_hold(sk);
                rcvr = &ep->base;
        }
 
@@ -253,25 +253,18 @@ int sctp_rcv(struct sk_buff *skb)
         */
        sctp_bh_lock_sock(sk);
 
-       /* It is possible that the association could have moved to a different
-        * socket if it is peeled off. If so, update the sk.
-        */ 
-       if (sk != rcvr->sk) {
-               sctp_bh_lock_sock(rcvr->sk);
-               sctp_bh_unlock_sock(sk);
-               sk = rcvr->sk;
-       }
-
        if (sock_owned_by_user(sk))
-               sk_add_backlog(sk, skb);
+               sctp_add_backlog(sk, skb);
        else
-               sctp_backlog_rcv(sk, skb);
+               sctp_inq_push(&chunk->rcvr->inqueue, chunk);
 
-       /* Release the sock and the sock ref we took in the lookup calls.
-        * The asoc/ep ref will be released in sctp_backlog_rcv.
-        */
        sctp_bh_unlock_sock(sk);
-       sock_put(sk);
+
+       /* Release the asoc/ep ref we took in the lookup calls. */
+       if (asoc)
+               sctp_association_put(asoc);
+       else
+               sctp_endpoint_put(ep);
 
        return 0;
 
@@ -280,8 +273,7 @@ discard_it:
        return 0;
 
 discard_release:
-       /* Release any structures we may be holding. */
-       sock_put(sk);
+       /* Release the asoc/ep ref we took in the lookup calls. */
        if (asoc)
                sctp_association_put(asoc);
        else
@@ -290,56 +282,87 @@ discard_release:
        goto discard_it;
 }
 
-/* Handle second half of inbound skb processing.  If the sock was busy,
- * we may have need to delay processing until later when the sock is
- * released (on the backlog).   If not busy, we call this routine
- * directly from the bottom half.
+/* Process the backlog queue of the socket.  Every skb on
+ * the backlog holds a ref on an association or endpoint.
+ * We hold this ref throughout the state machine to make
+ * sure that the structure we need is still around.
  */
 int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
 {
        struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
-       struct sctp_inq *inqueue = NULL;
+       struct sctp_inq *inqueue = &chunk->rcvr->inqueue;
        struct sctp_ep_common *rcvr = NULL;
+       int backloged = 0;
 
        rcvr = chunk->rcvr;
 
-       BUG_TRAP(rcvr->sk == sk);
-
-       if (rcvr->dead) {
-               sctp_chunk_free(chunk);
-       } else {
-               inqueue = &chunk->rcvr->inqueue;
-               sctp_inq_push(inqueue, chunk);
-       }
-
-       /* Release the asoc/ep ref we took in the lookup calls in sctp_rcv. */ 
-       if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
-               sctp_association_put(sctp_assoc(rcvr));
-       else
-               sctp_endpoint_put(sctp_ep(rcvr));
-  
+       /* If the rcvr is dead then the association or endpoint
+        * has been deleted and we can safely drop the chunk
+        * and refs that we are holding.
+        */
+       if (rcvr->dead) {
+               sctp_chunk_free(chunk);
+               goto done;
+       }
+
+       if (unlikely(rcvr->sk != sk)) {
+               /* In this case, the association moved from one socket to
+                * another.  We are currently sitting on the backlog of the
+                * old socket, so we need to move.
+                * However, since we are here in the process context we
+                * need to take make sure that the user doesn't own
+                * the new socket when we process the packet.
+                * If the new socket is user-owned, queue the chunk to the
+                * backlog of the new socket without dropping any refs.
+                * Otherwise, we can safely push the chunk on the inqueue.
+                */
+
+               sk = rcvr->sk;
+               sctp_bh_lock_sock(sk);
+
+               if (sock_owned_by_user(sk)) {
+                       sk_add_backlog(sk, skb);
+                       backloged = 1;
+               } else
+                       sctp_inq_push(inqueue, chunk);
+
+               sctp_bh_unlock_sock(sk);
+
+               /* If the chunk was backloged again, don't drop refs */
+               if (backloged)
+                       return 0;
+       } else {
+               sctp_inq_push(inqueue, chunk);
+       }
+
+done:
+       /* Release the refs we took in sctp_add_backlog */
+       if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
+               sctp_association_put(sctp_assoc(rcvr));
+       else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
+               sctp_endpoint_put(sctp_ep(rcvr));
+       else
+               BUG();
+
         return 0;
 }
 
-void sctp_backlog_migrate(struct sctp_association *assoc, 
-                         struct sock *oldsk, struct sock *newsk)
+static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
 {
-       struct sk_buff *skb;
-       struct sctp_chunk *chunk;
+       struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
+       struct sctp_ep_common *rcvr = chunk->rcvr;
 
-       skb = oldsk->sk_backlog.head;
-       oldsk->sk_backlog.head = oldsk->sk_backlog.tail = NULL;
-       while (skb != NULL) {
-               struct sk_buff *next = skb->next;
-
-               chunk = SCTP_INPUT_CB(skb)->chunk;
-               skb->next = NULL;
-               if (&assoc->base == chunk->rcvr)
-                       sk_add_backlog(newsk, skb);
-               else
-                       sk_add_backlog(oldsk, skb);
-               skb = next;
-       }
+       /* Hold the assoc/ep while hanging on the backlog queue.
+        * This way, we know structures we need will not disappear from us
+        */
+       if (SCTP_EP_TYPE_ASSOCIATION == rcvr->type)
+               sctp_association_hold(sctp_assoc(rcvr));
+       else if (SCTP_EP_TYPE_SOCKET == rcvr->type)
+               sctp_endpoint_hold(sctp_ep(rcvr));
+       else
+               BUG();
+
+       sk_add_backlog(sk, skb);
 }
 
 /* Handle icmp frag needed error. */
@@ -412,7 +435,7 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
        union sctp_addr daddr;
        struct sctp_af *af;
        struct sock *sk = NULL;
-       struct sctp_association *asoc = NULL;
+       struct sctp_association *asoc;
        struct sctp_transport *transport = NULL;
 
        *app = NULL; *tpp = NULL;
@@ -453,7 +476,6 @@ struct sock *sctp_err_lookup(int family, struct sk_buff *skb,
        return sk;
 
 out:
-       sock_put(sk);
        if (asoc)
                sctp_association_put(asoc);
        return NULL;
@@ -463,7 +485,6 @@ out:
 void sctp_err_finish(struct sock *sk, struct sctp_association *asoc)
 {
        sctp_bh_unlock_sock(sk);
-       sock_put(sk);
        if (asoc)
                sctp_association_put(asoc);
 }
@@ -490,7 +511,7 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
        int type = skb->h.icmph->type;
        int code = skb->h.icmph->code;
        struct sock *sk;
-       struct sctp_association *asoc;
+       struct sctp_association *asoc = NULL;
        struct sctp_transport *transport;
        struct inet_sock *inet;
        char *saveip, *savesctp;
@@ -716,7 +737,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
 
 hit:
        sctp_endpoint_hold(ep);
-       sock_hold(epb->sk);
        read_unlock(&head->lock);
        return ep;
 }
@@ -818,7 +838,6 @@ static struct sctp_association *__sctp_lookup_association(
 hit:
        *pt = transport;
        sctp_association_hold(asoc);
-       sock_hold(epb->sk);
        read_unlock(&head->lock);
        return asoc;
 }
@@ -846,7 +865,6 @@ int sctp_has_association(const union sctp_addr *laddr,
        struct sctp_transport *transport;
 
        if ((asoc = sctp_lookup_association(laddr, paddr, &transport))) {
-               sock_put(asoc->base.sk);
                sctp_association_put(asoc);
                return 1;
        }
index 8d1dc24bab4c1f1da541c760e13955ca54b77d29..c5beb2ad7ef7a442798a669faea2c393d5f422f8 100644 (file)
@@ -498,10 +498,6 @@ static void sctp_cmd_assoc_failed(sctp_cmd_seq_t *commands,
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_CLOSED));
 
-       /* Set sk_err to ECONNRESET on a 1-1 style socket. */
-       if (!sctp_style(asoc->base.sk, UDP))
-               asoc->base.sk->sk_err = ECONNRESET; 
-
        /* SEND_FAILED sent later when cleaning up the association. */
        asoc->outqueue.error = error;
        sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
@@ -838,6 +834,15 @@ static void sctp_cmd_del_non_primary(struct sctp_association *asoc)
        return;
 }
 
+/* Helper function to set sk_err on a 1-1 style socket. */
+static void sctp_cmd_set_sk_err(struct sctp_association *asoc, int error)
+{
+       struct sock *sk = asoc->base.sk;
+
+       if (!sctp_style(sk, UDP))
+               sk->sk_err = error;
+}
+
 /* These three macros allow us to pull the debugging code out of the
  * main flow of sctp_do_sm() to keep attention focused on the real
  * functionality there.
@@ -1458,6 +1463,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        local_cork = 0;
                        asoc->peer.retran_path = t;
                        break;
+               case SCTP_CMD_SET_SK_ERR:
+                       sctp_cmd_set_sk_err(asoc, cmd->obj.error);
+                       break;
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
                               cmd->verb, cmd->obj.ptr);
index 8cdba51ec0766a4d333ddc30e7ba4b756fe7802f..8bc279219a72ca3b8e4e107eaeba562e87a79e4a 100644 (file)
@@ -93,7 +93,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
 static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
 
 static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
-                                          __u16 error,
+                                          __u16 error, int sk_err,
                                           const struct sctp_association *asoc,
                                           struct sctp_transport *transport);
 
@@ -448,7 +448,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
        __u32 init_tag;
        struct sctp_chunk *err_chunk;
        struct sctp_packet *packet;
-       sctp_disposition_t ret;
+       __u16 error;
 
        if (!sctp_vtag_verify(chunk, asoc))
                return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -480,11 +480,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
                        goto nomem;
 
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
-               sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-                               SCTP_STATE(SCTP_STATE_CLOSED));
-               SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
-               sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB, SCTP_NULL());
-               return SCTP_DISPOSITION_DELETE_TCB;
+               return sctp_stop_t1_and_abort(commands, SCTP_ERROR_INV_PARAM,
+                                             ECONNREFUSED, asoc,
+                                             chunk->transport);
        }
 
        /* Verify the INIT chunk before processing it. */
@@ -511,27 +509,16 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
                                sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
                                                SCTP_PACKET(packet));
                                SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
-                               sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-                                               SCTP_STATE(SCTP_STATE_CLOSED));
-                               sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
-                                               SCTP_NULL());
-                               return SCTP_DISPOSITION_CONSUME;
+                               error = SCTP_ERROR_INV_PARAM;
                        } else {
-                               sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-                                               SCTP_STATE(SCTP_STATE_CLOSED));
-                               sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
-                                               SCTP_NULL());
-                               return SCTP_DISPOSITION_NOMEM;
+                               error = SCTP_ERROR_NO_RESOURCE;
                        }
                } else {
-                       ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
-                                                  commands);
-                       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
-                                       SCTP_STATE(SCTP_STATE_CLOSED));
-                       sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
-                                       SCTP_NULL());
-                       return ret;
+                       sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+                       error = SCTP_ERROR_INV_PARAM;
                }
+               return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED,
+                                               asoc, chunk->transport);
        }
 
        /* Tag the variable length parameters.  Note that we never
@@ -886,6 +873,8 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
        struct sctp_transport *transport = (struct sctp_transport *) arg;
 
        if (asoc->overall_error_count >= asoc->max_retrans) {
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ETIMEDOUT));
                /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -1030,6 +1019,12 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
                                                  commands);
 
        hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
+       /* Make sure that the length of the parameter is what we expect */
+       if (ntohs(hbinfo->param_hdr.length) !=
+                                   sizeof(sctp_sender_hb_info_t)) {
+               return SCTP_DISPOSITION_DISCARD;
+       }
+
        from_addr = hbinfo->daddr;
        link = sctp_assoc_lookup_paddr(asoc, &from_addr);
 
@@ -2126,6 +2121,8 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
        int attempts = asoc->init_err_counter + 1;
 
        if (attempts > asoc->max_init_attempts) {
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_STALE_COOKIE));
                return SCTP_DISPOSITION_DELETE_TCB;
@@ -2262,6 +2259,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
        if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
                error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
        /* ASSOC_FAILED will DELETE_TCB. */
        sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error));
        SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2306,7 +2304,8 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
        if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
                error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
 
-       return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport);
+       return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, asoc,
+                                     chunk->transport);
 }
 
 /*
@@ -2318,7 +2317,8 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep
                                        void *arg,
                                        sctp_cmd_seq_t *commands)
 {
-       return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc,
+       return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR,
+                                     ENOPROTOOPT, asoc,
                                      (struct sctp_transport *)arg);
 }
 
@@ -2343,7 +2343,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
  * This is common code called by several sctp_sf_*_abort() functions above.
  */
 static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
-                                          __u16 error,
+                                          __u16 error, int sk_err,
                                           const struct sctp_association *asoc,
                                           struct sctp_transport *transport)
 {
@@ -2353,6 +2353,7 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
        SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err));
        /* CMD_INIT_FAILED will DELETE_TCB. */
        sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                        SCTP_U32(error));
@@ -3336,6 +3337,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
                sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_ASCONF_ACK));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -3362,6 +3365,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
                 * processing the rest of the chunks in the packet.
                 */
                sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_ASCONF_ACK));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -3714,9 +3719,13 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
        if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ECONNREFUSED));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
        } else {
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_PROTO_VIOLATION));
                SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
@@ -4034,6 +4043,8 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
         * TCB.  This is a departure from our typical NOMEM handling.
         */
 
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                       SCTP_ERROR(ECONNABORTED));
        /* Delete the established association. */
        sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                        SCTP_U32(SCTP_ERROR_USER_ABORT));
@@ -4175,6 +4186,8 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
         * TCB.  This is a departure from our typical NOMEM handling.
         */
 
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                       SCTP_ERROR(ECONNREFUSED));
        /* Delete the established association. */
        sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                        SCTP_U32(SCTP_ERROR_USER_ABORT));
@@ -4543,6 +4556,8 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
        struct sctp_transport *transport = arg;
 
        if (asoc->overall_error_count >= asoc->max_retrans) {
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ETIMEDOUT));
                /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4662,6 +4677,8 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
                SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d"
                                  " max_init_attempts: %d\n",
                                  attempts, asoc->max_init_attempts);
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
                return SCTP_DISPOSITION_DELETE_TCB;
@@ -4711,6 +4728,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
 
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
        } else {
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
                return SCTP_DISPOSITION_DELETE_TCB;
@@ -4742,6 +4761,8 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
 
        SCTP_DEBUG_PRINTK("Timer T2 expired.\n");
        if (asoc->overall_error_count >= asoc->max_retrans) {
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ETIMEDOUT));
                /* Note:  CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
@@ -4817,6 +4838,8 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
        if (asoc->overall_error_count >= asoc->max_retrans) {
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO));
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ETIMEDOUT));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_ERROR));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -4870,6 +4893,8 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
                goto nomem;
 
        sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                       SCTP_ERROR(ETIMEDOUT));
        sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                        SCTP_U32(SCTP_ERROR_NO_ERROR));
 
@@ -5309,6 +5334,8 @@ static int sctp_eat_data(const struct sctp_association *asoc,
                 * processing the rest of the chunks in the packet.
                 */
                sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET,SCTP_NULL());
+               sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                               SCTP_ERROR(ECONNABORTED));
                sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
                                SCTP_U32(SCTP_ERROR_NO_DATA));
                SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
index b6e4b89539b3178216037c53350f5591dde8a1b6..174d4d35e951590d7bef5d10df113afe36f88ae6 100644 (file)
@@ -1057,6 +1057,7 @@ static int __sctp_connect(struct sock* sk,
        inet_sk(sk)->dport = htons(asoc->peer.port);
        af = sctp_get_af_specific(to.sa.sa_family);
        af->to_sk_daddr(&to, sk);
+       sk->sk_err = 0;
 
        timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
        err = sctp_wait_for_connect(asoc, &timeo);
@@ -1228,7 +1229,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
 
        ep = sctp_sk(sk)->ep;
 
-       /* Walk all associations on a socket, not on an endpoint.  */
+       /* Walk all associations on an endpoint.  */
        list_for_each_safe(pos, temp, &ep->asocs) {
                asoc = list_entry(pos, struct sctp_association, asocs);
 
@@ -1241,13 +1242,13 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
                        if (sctp_state(asoc, CLOSED)) {
                                sctp_unhash_established(asoc);
                                sctp_association_free(asoc);
+                               continue;
+                       }
+               }
 
-                       } else if (sock_flag(sk, SOCK_LINGER) &&
-                                  !sk->sk_lingertime)
-                               sctp_primitive_ABORT(asoc, NULL);
-                       else
-                               sctp_primitive_SHUTDOWN(asoc, NULL);
-               } else
+               if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)
+                       sctp_primitive_ABORT(asoc, NULL);
+               else
                        sctp_primitive_SHUTDOWN(asoc, NULL);
        }
 
@@ -5317,6 +5318,7 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
                 */
                sctp_release_sock(sk);
                current_timeo = schedule_timeout(current_timeo);
+               BUG_ON(sk != asoc->base.sk);
                sctp_lock_sock(sk);
 
                *timeo_p = current_timeo;
@@ -5604,12 +5606,14 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
         */
        newsp->type = type;
 
-       spin_lock_bh(&oldsk->sk_lock.slock);
-       /* Migrate the backlog from oldsk to newsk. */
-       sctp_backlog_migrate(assoc, oldsk, newsk);
-       /* Migrate the association to the new socket. */
+       /* Mark the new socket "in-use" by the user so that any packets
+        * that may arrive on the association after we've moved it are
+        * queued to the backlog.  This prevents a potential race between
+        * backlog processing on the old socket and new-packet processing
+        * on the new socket.
+        */
+       sctp_lock_sock(newsk);
        sctp_assoc_migrate(assoc, newsk);
-       spin_unlock_bh(&oldsk->sk_lock.slock);
 
        /* If the association on the newsk is already closed before accept()
         * is called, set RCV_SHUTDOWN flag.
@@ -5618,6 +5622,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
                newsk->sk_shutdown |= RCV_SHUTDOWN;
 
        newsk->sk_state = SCTP_SS_ESTABLISHED;
+       sctp_release_sock(newsk);
 }
 
 /* This proto struct describes the ULP interface for SCTP.  */
index 3ac4193a78edf2c0fcff4ae5257b50163c2a937f..7026b0866b7b0d50b0003b15bb14fde24a569a65 100644 (file)
@@ -159,6 +159,7 @@ struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
                detail->update(tmp, new);
        tmp->next = *head;
        *head = tmp;
+       detail->entries++;
        cache_get(tmp);
        is_new = cache_fresh_locked(tmp, new->expiry_time);
        cache_fresh_locked(old, 0);
index b54971059f164136be5db7dbaea938548a4e4e15..891a6090cc099d2f88e15aa33ff68db982132d6e 100644 (file)
@@ -62,7 +62,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq)
        case IPPROTO_COMP:
                if (!pskb_may_pull(skb, sizeof(struct ip_comp_hdr)))
                        return -EINVAL;
-               *spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2)));
+               *spi = htonl(ntohs(*(u16*)(skb->h.raw + 2)));
                *seq = 0;
                return 0;
        default:
index 6d04504b2fc111a0bbd7ac8745fa9f96e008e72a..d0f86ed43f7a17156953d889df8cfa00f6013b04 100644 (file)
@@ -697,29 +697,79 @@ static void check_sec_ref(struct module *mod, const char *modname,
 
        /* Walk through all sections */
        for (i = 0; i < hdr->e_shnum; i++) {
-               Elf_Rela *rela;
-               Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
-               Elf_Rela *stop  = (void*)start + sechdrs[i].sh_size;
-               const char *name = secstrings + sechdrs[i].sh_name +
-                                               strlen(".rela");
+               const char *name = secstrings + sechdrs[i].sh_name;
+               const char *secname;
+               Elf_Rela r;
+               unsigned int r_sym;
                /* We want to process only relocation sections and not .init */
-               if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA))
-                       continue;
+               if (sechdrs[i].sh_type == SHT_RELA) {
+                       Elf_Rela *rela;
+                       Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
+                       Elf_Rela *stop  = (void*)start + sechdrs[i].sh_size;
+                       name += strlen(".rela");
+                       if (section_ref_ok(name))
+                               continue;
 
-               for (rela = start; rela < stop; rela++) {
-                       Elf_Rela r;
-                       const char *secname;
-                       r.r_offset = TO_NATIVE(rela->r_offset);
-                       r.r_info   = TO_NATIVE(rela->r_info);
-                       r.r_addend = TO_NATIVE(rela->r_addend);
-                       sym = elf->symtab_start + ELF_R_SYM(r.r_info);
-                       /* Skip special sections */
-                       if (sym->st_shndx >= SHN_LORESERVE)
+                       for (rela = start; rela < stop; rela++) {
+                               r.r_offset = TO_NATIVE(rela->r_offset);
+#if KERNEL_ELFCLASS == ELFCLASS64
+                               if (hdr->e_machine == EM_MIPS) {
+                                       r_sym = ELF64_MIPS_R_SYM(rela->r_info);
+                                       r_sym = TO_NATIVE(r_sym);
+                               } else {
+                                       r.r_info = TO_NATIVE(rela->r_info);
+                                       r_sym = ELF_R_SYM(r.r_info);
+                               }
+#else
+                               r.r_info = TO_NATIVE(rela->r_info);
+                               r_sym = ELF_R_SYM(r.r_info);
+#endif
+                               r.r_addend = TO_NATIVE(rela->r_addend);
+                               sym = elf->symtab_start + r_sym;
+                               /* Skip special sections */
+                               if (sym->st_shndx >= SHN_LORESERVE)
+                                       continue;
+
+                               secname = secstrings +
+                                       sechdrs[sym->st_shndx].sh_name;
+                               if (section(secname))
+                                       warn_sec_mismatch(modname, name,
+                                                         elf, sym, r);
+                       }
+               } else if (sechdrs[i].sh_type == SHT_REL) {
+                       Elf_Rel *rel;
+                       Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset;
+                       Elf_Rel *stop  = (void*)start + sechdrs[i].sh_size;
+                       name += strlen(".rel");
+                       if (section_ref_ok(name))
                                continue;
 
-                       secname = secstrings + sechdrs[sym->st_shndx].sh_name;
-                       if (section(secname))
-                               warn_sec_mismatch(modname, name, elf, sym, r);
+                       for (rel = start; rel < stop; rel++) {
+                               r.r_offset = TO_NATIVE(rel->r_offset);
+#if KERNEL_ELFCLASS == ELFCLASS64
+                               if (hdr->e_machine == EM_MIPS) {
+                                       r_sym = ELF64_MIPS_R_SYM(rel->r_info);
+                                       r_sym = TO_NATIVE(r_sym);
+                               } else {
+                                       r.r_info = TO_NATIVE(rel->r_info);
+                                       r_sym = ELF_R_SYM(r.r_info);
+                               }
+#else
+                               r.r_info = TO_NATIVE(rel->r_info);
+                               r_sym = ELF_R_SYM(r.r_info);
+#endif
+                               r.r_addend = 0;
+                               sym = elf->symtab_start + r_sym;
+                               /* Skip special sections */
+                               if (sym->st_shndx >= SHN_LORESERVE)
+                                       continue;
+
+                               secname = secstrings +
+                                       sechdrs[sym->st_shndx].sh_name;
+                               if (section(secname))
+                                       warn_sec_mismatch(modname, name,
+                                                         elf, sym, r);
+                       }
                }
        }
 }
index b14255c72a375edcfe6da9f61589ba2e433deb94..861d866fcd8394bf2fdcec228fe8b7c81f145804 100644 (file)
@@ -21,6 +21,7 @@
 #define ELF_ST_BIND ELF32_ST_BIND
 #define ELF_ST_TYPE ELF32_ST_TYPE
 
+#define Elf_Rel     Elf32_Rel
 #define Elf_Rela    Elf32_Rela
 #define ELF_R_SYM   ELF32_R_SYM
 #define ELF_R_TYPE  ELF32_R_TYPE
 #define ELF_ST_BIND ELF64_ST_BIND
 #define ELF_ST_TYPE ELF64_ST_TYPE
 
+#define Elf_Rel     Elf64_Rel
 #define Elf_Rela    Elf64_Rela
 #define ELF_R_SYM   ELF64_R_SYM
 #define ELF_R_TYPE  ELF64_R_TYPE
 #endif
 
+/* The 64-bit MIPS ELF ABI uses an unusual reloc format. */
+typedef struct
+{
+       Elf32_Word    r_sym;    /* Symbol index */
+       unsigned char r_ssym;   /* Special symbol for 2nd relocation */
+       unsigned char r_type3;  /* 3rd relocation type */
+       unsigned char r_type2;  /* 2nd relocation type */
+       unsigned char r_type1;  /* 1st relocation type */
+} _Elf64_Mips_R_Info;
+
+typedef union
+{
+       Elf64_Xword             r_info_number;
+       _Elf64_Mips_R_Info      r_info_fields;
+} _Elf64_Mips_R_Info_union;
+
+#define ELF64_MIPS_R_SYM(i) \
+  ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
+
 #if KERNEL_ELFDATA != HOST_ELFDATA
 
 static inline void __endian(const void *src, void *dest, unsigned int size)
@@ -48,8 +69,6 @@ static inline void __endian(const void *src, void *dest, unsigned int size)
                ((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
 }
 
-
-
 #define TO_NATIVE(x)                                           \
 ({                                                             \
        typeof(x) __x;                                          \
index d987048d3f330526b31185d5023ea8fd4c891027..21dad415b8960d7e389a7e4d8376a9972b0e7abe 100644 (file)
@@ -3231,7 +3231,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
                goto out;
 
        /* Handle mapped IPv4 packets arriving via IPv6 sockets */
-       if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
+       if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
                family = PF_INET;
 
        read_lock_bh(&sk->sk_callback_lock);
index da7ef26995c3d9ae3ea73e254d9bc8ef16666954..77b06009735df818253aa6a70b39392e476bfc80 100644 (file)
@@ -151,7 +151,7 @@ static struct pnp_device_id snd_mpu401_pnpids[] = {
 
 MODULE_DEVICE_TABLE(pnp, snd_mpu401_pnpids);
 
-static int __init snd_mpu401_pnp(int dev, struct pnp_dev *device,
+static int __devinit snd_mpu401_pnp(int dev, struct pnp_dev *device,
                                 const struct pnp_device_id *id)
 {
        if (!pnp_port_valid(device, 0) ||
index a36ec1daa5cb9e24dcb5e3d887d5d56936c13f2b..e6945db8ed1b8a2fcd4b877712b96db8ff791c98 100644 (file)
@@ -85,6 +85,8 @@
 #include <linux/pnp.h>
 #include <linux/isapnp.h>
 #include <linux/moduleparam.h>
+#include <linux/delay.h>
+
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <sound/core.h>
index 49796be955f32c69cb933f9657761ca3f32a1e28..e04fa49b0dc8e5509963e82ef6d4bc34692324d4 100644 (file)
@@ -2026,7 +2026,8 @@ int ad1848_init (char *name, struct resource *ports, int irq, int dma_playback,
        if (irq > 0)
        {
                devc->dev_no = my_dev;
-               if (request_irq(devc->irq, adintr, 0, devc->name, (void *)my_dev) < 0)
+               if (request_irq(devc->irq, adintr, 0, devc->name,
+                               (void *)(long)my_dev) < 0)
                {
                        printk(KERN_WARNING "ad1848: Unable to allocate IRQ\n");
                        /* Don't free it either then.. */
@@ -2175,7 +2176,7 @@ void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int
                if (!share_dma)
                {
                        if (devc->irq > 0) /* There is no point in freeing irq, if it wasn't allocated */
-                               free_irq(devc->irq, (void *)devc->dev_no);
+                               free_irq(devc->irq, (void *)(long)devc->dev_no);
 
                        sound_free_dma(dma_playback);
 
@@ -2204,7 +2205,7 @@ irqreturn_t adintr(int irq, void *dev_id, struct pt_regs *dummy)
        unsigned char c930_stat = 0;
        int cnt = 0;
 
-       dev = (int)dev_id;
+       dev = (long)dev_id;
        devc = (ad1848_info *) audio_devs[dev]->devc;
 
 interrupt_again:               /* Jump back here if int status doesn't reset */
@@ -2900,7 +2901,8 @@ static struct pnp_dev *activate_dev(char *devname, char *resname, struct pnp_dev
        return(dev);
 }
 
-static struct pnp_dev *ad1848_init_generic(struct pnp_card *bus, struct address_info *hw_config, int slot)
+static struct pnp_dev __init *ad1848_init_generic(struct pnp_card *bus,
+                               struct address_info *hw_config, int slot)
 {
 
        /* Configure Audio device */
index 7de079b202f214bd9dc9baf608a4131ba89d71c5..6e662ac009ae5f2ff04a08c8b86235be17da12ff 100644 (file)
@@ -960,7 +960,7 @@ static struct ac97_mixer_value_list mixer_defaults[] = {
 
 
 /* Installs the AC97 mixer into CARD.  */
-static int __init
+static int __devinit
 nm256_install_mixer (struct nm256_info *card)
 {
     int mixer;
@@ -995,7 +995,7 @@ nm256_install_mixer (struct nm256_info *card)
  * RAM.
  */
 
-static void __init
+static void __devinit
 nm256_peek_for_sig (struct nm256_info *card)
 {
     u32 port1offset 
@@ -1056,7 +1056,7 @@ nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr)
     card->playing  = 0;
     card->recording = 0;
     card->rev = rev;
-       spin_lock_init(&card->lock);
+    spin_lock_init(&card->lock);
 
     /* Init the memory port info.  */
     for (x = 0; x < 2; x++) {