]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
authorJody McIntyre <scjody@modernduck.com>
Tue, 22 Nov 2005 17:38:34 +0000 (12:38 -0500)
committerJody McIntyre <scjody@modernduck.com>
Tue, 22 Nov 2005 17:38:34 +0000 (12:38 -0500)
186 files changed:
CREDITS
Documentation/DocBook/kernel-api.tmpl
Documentation/arm/memory.txt
MAINTAINERS
Makefile
arch/arm/kernel/armksyms.c
arch/arm/kernel/entry-common.S
arch/arm/kernel/signal.c
arch/arm/kernel/vmlinux.lds.S
arch/arm/lib/getuser.S
arch/arm/mach-clps7500/core.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-sa1100/assabet.c
arch/arm/mm/Makefile
arch/arm/mm/blockops.c [deleted file]
arch/arm/mm/init.c
arch/arm/mm/ioremap.c
arch/i386/kernel/acpi/boot.c
arch/i386/kernel/mpparse.c
arch/ia64/sn/kernel/bte.c
arch/ia64/sn/kernel/sn2/sn2_smp.c
arch/ia64/sn/kernel/sn2/sn_hwperf.c
arch/parisc/kernel/drivers.c
arch/parisc/kernel/entry.S
arch/parisc/kernel/inventory.c
arch/parisc/kernel/ioctl32.c
arch/parisc/kernel/irq.c
arch/parisc/kernel/perf.c
arch/parisc/kernel/ptrace.c
arch/parisc/kernel/signal.c
arch/parisc/kernel/smp.c
arch/parisc/kernel/syscall.S
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/ptrace-common.h [moved from include/asm-ppc64/ptrace-common.h with 100% similarity]
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/ptrace32.c
arch/powerpc/mm/imalloc.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mmu_decl.h
arch/powerpc/mm/pgtable_64.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/sysdev/mpic.c
block/as-iosched.c
block/cfq-iosched.c
block/deadline-iosched.c
block/elevator.c
block/ll_rw_blk.c
drivers/block/cciss.c
drivers/char/agp/amd64-agp.c
drivers/char/agp/backend.c
drivers/char/agp/via-agp.c
drivers/i2c/busses/i2c-ixp2000.c
drivers/i2c/busses/i2c-ixp4xx.c
drivers/ide/Kconfig
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-floppy.c
drivers/ide/ide-io.c
drivers/ide/ide-lib.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/pci/aec62xx.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/cs5520.c
drivers/ide/pci/siimage.c
drivers/ide/pci/sis5513.c
drivers/ide/pci/via82cxxx.c
drivers/ide/ppc/pmac.c
drivers/ide/setup-pci.c
drivers/infiniband/core/user_mad.c
drivers/infiniband/hw/mthca/mthca_qp.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/infiniband/ulp/srp/ib_srp.h
drivers/input/gameport/gameport.c
drivers/input/input.c
drivers/input/keyboard/atkbd.c
drivers/input/misc/Kconfig
drivers/input/misc/Makefile
drivers/input/misc/uinput.c
drivers/input/misc/wistron_btns.c [new file with mode: 0644]
drivers/input/serio/serio.c
drivers/isdn/hisax/Kconfig
drivers/isdn/pcbit/Kconfig
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/video/ir-kbd-gpio.c
drivers/media/video/saa7134/saa7134-input.c
drivers/mtd/maps/ipaq-flash.c
drivers/mtd/maps/ixp2000.c
drivers/mtd/nand/h1910.c
drivers/net/au1000_eth.c
drivers/net/e100.c
drivers/net/fec_8xx/Kconfig
drivers/net/ioc3-eth.c
drivers/net/r8169.c
drivers/net/saa9730.h
drivers/net/smc91x.c
drivers/net/wan/hdlc_cisco.c
drivers/net/wan/hdlc_fr.c
drivers/net/wan/hdlc_generic.c
drivers/net/wireless/hermes.c
drivers/net/wireless/hermes.h
drivers/net/wireless/i82593.h
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2100.h
drivers/net/wireless/prism54/isl_38xx.c
drivers/parisc/iosapic.c
drivers/parisc/superio.c
drivers/scsi/ide-scsi.c
drivers/scsi/sata_mv.c
drivers/scsi/sata_sil24.c
drivers/serial/Kconfig
drivers/serial/amba-pl011.c
drivers/serial/imx.c
drivers/serial/mux.c
drivers/serial/sa1100.c
fs/cifs/CHANGES
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.h
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifspdu.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/readdir.c
fs/cifs/transport.c
fs/compat.c
fs/compat_ioctl.c
include/asm-arm/arch-ebsa110/io.h
include/asm-arm/arch-ixp4xx/io.h
include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
include/asm-arm/hardware/amba_serial.h
include/asm-arm/io.h
include/asm-arm/numnodes.h
include/asm-arm/uaccess.h
include/asm-ia64/sn/sn_sal.h
include/asm-ia64/sn/tioce.h
include/asm-ia64/sn/tioce_provider.h
include/asm-parisc/irq.h
include/asm-parisc/smp.h
include/asm-parisc/spinlock.h
include/asm-parisc/tlbflush.h
include/asm-powerpc/dma-mapping.h [moved from include/asm-ppc/dma-mapping.h with 56% similarity]
include/asm-powerpc/io.h [moved from include/asm-ppc64/io.h with 98% similarity]
include/asm-powerpc/mmu.h [moved from include/asm-ppc64/mmu.h with 98% similarity]
include/asm-powerpc/mmu_context.h [moved from include/asm-ppc64/mmu_context.h with 91% similarity]
include/asm-powerpc/mmzone.h [moved from include/asm-ppc64/mmzone.h with 100% similarity]
include/asm-powerpc/pci-bridge.h [moved from include/asm-ppc64/pci-bridge.h with 96% similarity]
include/asm-powerpc/pci.h [moved from include/asm-ppc64/pci.h with 63% similarity]
include/asm-powerpc/pgalloc.h [moved from include/asm-ppc64/pgalloc.h with 95% similarity]
include/asm-powerpc/pgtable-4k.h [moved from include/asm-ppc64/pgtable-4k.h with 100% similarity]
include/asm-powerpc/pgtable-64k.h [moved from include/asm-ppc64/pgtable-64k.h with 100% similarity]
include/asm-powerpc/pgtable.h [moved from include/asm-ppc64/pgtable.h with 97% similarity]
include/asm-powerpc/ppc-pci.h
include/asm-powerpc/spinlock.h [moved from include/asm-ppc64/spinlock.h with 80% similarity]
include/asm-ppc/io.h
include/asm-ppc64/dma-mapping.h [deleted file]
include/asm-ppc64/imalloc.h [deleted file]
include/asm-x86_64/msr.h
include/linux/cciss_ioctl.h
include/linux/hdreg.h
include/linux/ide.h
include/linux/mm.h
include/linux/netfilter_ipv4/ipt_sctp.h
include/linux/pci_ids.h
include/linux/skbuff.h
include/linux/uinput.h
include/net/ieee80211.h
include/net/ipv6.h
mm/mmap.c
net/core/filter.c
net/dccp/proto.c
net/ipv4/fib_trie.c
net/ipv4/netfilter/Kconfig
net/ipv6/addrconf.c
net/ipv6/datagram.c
net/ipv6/exthdrs.c
net/ipv6/ip6_flowlabel.c
net/ipv6/raw.c
net/ipv6/udp.c
net/sched/sch_netem.c

diff --git a/CREDITS b/CREDITS
index 192f749eba25b38007b7a32e362e06896f7a368c..1b4f8694fa48ff0832b1f87b3a99c5233c313fda 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -611,8 +611,7 @@ S: USA
 N: Randolph Chung
 E: tausq@debian.org
 D: Linux/PA-RISC hacker
-S: Los Altos, CA 94022
-S: USA
+S: Hong Kong
 
 N: Juan Jose Ciarlante
 W: http://juanjox.kernelnotes.org/
@@ -3405,6 +3404,15 @@ S: Chudenicka 8
 S: 10200 Prague 10, Hostivar
 S: Czech Republic
 
+N: Thibaut Varene
+E: T-Bone@parisc-linux.org
+W: http://www.parisc-linux.org/
+P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C  FA2F 1E32 C3DA B7D2 F063
+D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
+D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there
+D: AD1889 sound driver
+S: Paris, France
+
 N: Heikki Vatiainen
 E: hessu@cs.tut.fi
 D: Co-author of Multi-Protocol Over ATM (MPOA), some LANE hacks
index 096aed62c326821cb7c6ab586167344ef3401ac0..767433bdbc4099ce3a2f4403f91d0e35a0a1f6f6 100644 (file)
@@ -237,8 +237,10 @@ X!Ilib/string.c
      <sect1><title>Driver Support</title>
 !Enet/core/dev.c
 !Enet/ethernet/eth.c
-!Einclude/linux/etherdevice.h
-!Enet/core/wireless.c
+!Iinclude/linux/etherdevice.h
+<!-- FIXME: Removed for now since no structured comments in source
+X!Enet/core/wireless.c
+-->
      </sect1>
      <sect1><title>Synchronous PPP</title>
 !Edrivers/net/wan/syncppp.c
index 4b1c93a8177b9d6fbf447b86119e596c71e7f7cf..dc6045577a8bdcebe21980453beecbe82126f41f 100644 (file)
@@ -1,7 +1,7 @@
                Kernel Memory Layout on ARM Linux
 
                Russell King <rmk@arm.linux.org.uk>
-                       May 21, 2004 (2.6.6)
+                    November 17, 2005 (2.6.15)
 
 This document describes the virtual memory layout which the Linux
 kernel uses for ARM processors.  It indicates which regions are
@@ -37,6 +37,8 @@ ff000000      ffbfffff        Reserved for future expansion of DMA
                                mapping region.
 
 VMALLOC_END    feffffff        Free for platform use, recommended.
+                               VMALLOC_END must be aligned to a 2MB
+                               boundary.
 
 VMALLOC_START  VMALLOC_END-1   vmalloc() / ioremap() space.
                                Memory returned by vmalloc/ioremap will
index f239ac4762ddb4565954c49135dff2adb1a364b5..c5cf7d7e58b24116c30864414b7496ed50e1f0e6 100644 (file)
@@ -2907,6 +2907,11 @@ M:       zaga@fly.cc.fer.hr
 L:     linux-scsi@vger.kernel.org
 S:     Maintained
 
+WISTRON LAPTOP BUTTON DRIVER
+P:     Miloslav Trmac
+M:     mitr@volny.cz
+S:     Maintained
+
 WL3501 WIRELESS PCMCIA CARD DRIVER
 P:     Arnaldo Carvalho de Melo
 M:     acme@conectiva.com.br
index c31914400953b05438b6cda4e793d166094b2ee4..e7a0443c867c4c750f829bbceb6bb99889dda78b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 15
-EXTRAVERSION =-rc1
+EXTRAVERSION =-rc2
 NAME=Affluent Albatross
 
 # *DOCUMENTATION*
index 7a3261f0bf79012e158e81eab69e7f633d56b4c6..9997098009a9941ff63c025c23be09aa56b6ccbf 100644 (file)
@@ -120,7 +120,6 @@ EXPORT_SYMBOL(__arch_strncpy_from_user);
 EXPORT_SYMBOL(__get_user_1);
 EXPORT_SYMBOL(__get_user_2);
 EXPORT_SYMBOL(__get_user_4);
-EXPORT_SYMBOL(__get_user_8);
 
 EXPORT_SYMBOL(__put_user_1);
 EXPORT_SYMBOL(__put_user_2);
index 066597f4345a6716bf0284200076303f6a85602b..f7f18307523754ba6fda73990ac5033e08cf1f70 100644 (file)
@@ -48,8 +48,7 @@ work_pending:
        mov     r0, sp                          @ 'regs'
        mov     r2, why                         @ 'syscall'
        bl      do_notify_resume
-       disable_irq                             @ disable interrupts
-       b       no_work_pending
+       b       ret_slow_syscall                @ Check work again
 
 work_resched:
        bl      schedule
index a917e3dd366611b2bb7d017f3b74c31d7a95fd64..765922bcf9e7c2f37b0bf606ad57a6ac3cd8d7dd 100644 (file)
@@ -595,23 +595,22 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
         */
        ret |= !valid_user_regs(regs);
 
-       /*
-        * Block the signal if we were unsuccessful.
-        */
        if (ret != 0) {
-               spin_lock_irq(&tsk->sighand->siglock);
-               sigorsets(&tsk->blocked, &tsk->blocked,
-                         &ka->sa.sa_mask);
-               if (!(ka->sa.sa_flags & SA_NODEFER))
-                       sigaddset(&tsk->blocked, sig);
-               recalc_sigpending();
-               spin_unlock_irq(&tsk->sighand->siglock);
+               force_sigsegv(sig, tsk);
+               return;
        }
 
-       if (ret == 0)
-               return;
+       /*
+        * Block the signal if we were successful.
+        */
+       spin_lock_irq(&tsk->sighand->siglock);
+       sigorsets(&tsk->blocked, &tsk->blocked,
+                 &ka->sa.sa_mask);
+       if (!(ka->sa.sa_flags & SA_NODEFER))
+               sigaddset(&tsk->blocked, sig);
+       recalc_sigpending();
+       spin_unlock_irq(&tsk->sighand->siglock);
 
-       force_sigsegv(sig, tsk);
 }
 
 /*
index 80c8e4c8cefa078650b7180f7581eeac93296ebf..9a47770114d49db0663b6f611ab7872cd0ab2755 100644 (file)
@@ -172,6 +172,10 @@ SECTIONS
        .comment 0 : { *(.comment) }
 }
 
-/* those must never be empty */
+/*
+ * These must never be empty
+ * If you have to comment these two assert statements out, your
+ * binutils is too old (for other reasons as well)
+ */
 ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")
 ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")
index d204018070a49bde08c2c32b610c8b9edef37b5b..c03ea8e666ba1906544fba96a62d58ce3e526ecf 100644 (file)
@@ -54,15 +54,6 @@ __get_user_4:
        mov     r0, #0
        mov     pc, lr
 
-       .global __get_user_8
-__get_user_8:
-5:     ldrt    r2, [r0], #4
-6:     ldrt    r3, [r0]
-       mov     r0, #0
-       mov     pc, lr
-
-__get_user_bad_8:
-       mov     r3, #0
 __get_user_bad:
        mov     r2, #0
        mov     r0, #-EFAULT
@@ -73,6 +64,4 @@ __get_user_bad:
        .long   2b, __get_user_bad
        .long   3b, __get_user_bad
        .long   4b, __get_user_bad
-       .long   5b, __get_user_bad_8
-       .long   6b, __get_user_bad_8
 .previous
index 0364ba4b539e075e5ecf893a6a141948fd4fa998..d869af0023f8e906da3312cf6576aa8507a41092 100644 (file)
@@ -260,7 +260,7 @@ static void __init clps7500_init_irq(void)
 
 static struct map_desc cl7500_io_desc[] __initdata = {
        {       /* IO space     */
-               .virtual        = IO_BASE,
+               .virtual        = (unsigned long)IO_BASE,
                .pfn            = __phys_to_pfn(IO_START),
                .length         = IO_SIZE,
                .type           = MT_DEVICE
index c312054dfb8872b3e2af9a1065fdd227488af969..e4f92efc616e58e038b4c649ef911163692b1169 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
index 75efb5da5b6d2874867cd83c58fd37b82e456bde..a66ac61233a2f088e2e666ded4b59afaab03ab52 100644 (file)
@@ -293,7 +293,8 @@ static void __init get_assabet_scr(void)
        GPDR |= 0x3fc;                  /* Configure GPIO 9:2 as outputs */
        GPSR = 0x3fc;                   /* Write 0xFF to GPIO 9:2 */
        GPDR &= ~(0x3fc);               /* Configure GPIO 9:2 as inputs */
-       for(i = 100; i--; scr = GPLR);  /* Read GPIO 9:2 */
+       for(i = 100; i--; )             /* Read GPIO 9:2 */
+               scr = GPLR;
        GPDR |= 0x3fc;                  /*  restore correct pin direction */
        scr &= 0x3fc;                   /* save as system configuration byte. */
        SCR_value = scr;
index 59f47d4c2dfe6edf22560b861d6a3d554104dbf1..ffe73ba2bf174d857738d986d1c30240d49bcf50 100644 (file)
@@ -51,4 +51,4 @@ obj-$(CONFIG_CPU_ARM1026)     += proc-arm1026.o
 obj-$(CONFIG_CPU_SA110)                += proc-sa110.o
 obj-$(CONFIG_CPU_SA1100)       += proc-sa1100.o
 obj-$(CONFIG_CPU_XSCALE)       += proc-xscale.o
-obj-$(CONFIG_CPU_V6)           += proc-v6.o blockops.o
+obj-$(CONFIG_CPU_V6)           += proc-v6.o
diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c
deleted file mode 100644 (file)
index 4f5ee2d..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-
-#include <asm/memory.h>
-#include <asm/ptrace.h>
-#include <asm/cacheflush.h>
-#include <asm/traps.h>
-
-extern struct cpu_cache_fns blk_cache_fns;
-
-#define HARVARD_CACHE
-
-/*
- *     blk_flush_kern_dcache_page(kaddr)
- *
- *     Ensure that the data held in the page kaddr is written back
- *     to the page in question.
- *
- *     - kaddr   - kernel address (guaranteed to be page aligned)
- */
-static void __attribute__((naked))
-blk_flush_kern_dcache_page(void *kaddr)
-{
-       asm(
-       "add    r1, r0, %0                                                      \n\
-       sub     r1, r1, %1                                                      \n\
-1:     .word   0xec401f0e      @ mcrr  p15, 0, r0, r1, c14, 0  @ blocking      \n\
-       mov     r0, #0                                                          \n\
-       mcr     p15, 0, r0, c7, c5, 0                                           \n\
-       mcr     p15, 0, r0, c7, c10, 4                                          \n\
-       mov     pc, lr"
-       :
-       : "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES));
-}
-
-/*
- *     blk_dma_inv_range(start,end)
- *
- *     Invalidate the data cache within the specified region; we will
- *     be performing a DMA operation in this region and we want to
- *     purge old data in the cache.
- *
- *     - start   - virtual start address of region
- *     - end     - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_inv_range_unified(unsigned long start, unsigned long end)
-{
-       asm(
-       "tst    r0, %0                                                          \n\
-       mcrne   p15, 0, r0, c7, c11, 1          @ clean unified line            \n\
-       tst     r1, %0                                                          \n\
-       mcrne   p15, 0, r1, c7, c15, 1          @ clean & invalidate unified line\n\
-       .word   0xec401f06      @ mcrr  p15, 0, r1, r0, c6, 0   @ blocking      \n\
-       mov     r0, #0                                                          \n\
-       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer            \n\
-       mov     pc, lr"
-       :
-       : "I" (L1_CACHE_BYTES - 1));
-}
-
-static void __attribute__((naked))
-blk_dma_inv_range_harvard(unsigned long start, unsigned long end)
-{
-       asm(
-       "tst    r0, %0                                                          \n\
-       mcrne   p15, 0, r0, c7, c10, 1          @ clean D line                  \n\
-       tst     r1, %0                                                          \n\
-       mcrne   p15, 0, r1, c7, c14, 1          @ clean & invalidate D line     \n\
-       .word   0xec401f06      @ mcrr  p15, 0, r1, r0, c6, 0   @ blocking      \n\
-       mov     r0, #0                                                          \n\
-       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer            \n\
-       mov     pc, lr"
-       :
-       : "I" (L1_CACHE_BYTES - 1));
-}
-
-/*
- *     blk_dma_clean_range(start,end)
- *     - start   - virtual start address of region
- *     - end     - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_clean_range(unsigned long start, unsigned long end)
-{
-       asm(
-       ".word  0xec401f0c      @ mcrr  p15, 0, r1, r0, c12, 0  @ blocking      \n\
-       mov     r0, #0                                                          \n\
-       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer            \n\
-       mov     pc, lr");
-}
-
-/*
- *     blk_dma_flush_range(start,end)
- *     - start   - virtual start address of region
- *     - end     - virtual end address of region
- */
-static void __attribute__((naked))
-blk_dma_flush_range(unsigned long start, unsigned long end)
-{
-       asm(
-       ".word  0xec401f0e      @ mcrr  p15, 0, r1, r0, c14, 0  @ blocking      \n\
-       mov     pc, lr");
-}
-
-static int blockops_trap(struct pt_regs *regs, unsigned int instr)
-{
-       regs->ARM_r4 |= regs->ARM_r2;
-       regs->ARM_pc += 4;
-       return 0;
-}
-
-static char *func[] = {
-       "Prefetch data range",
-       "Clean+Invalidate data range",
-       "Clean data range",
-       "Invalidate data range",
-       "Invalidate instr range"
-};
-
-static struct undef_hook blockops_hook __initdata = {
-       .instr_mask     = 0x0fffffd0,
-       .instr_val      = 0x0c401f00,
-       .cpsr_mask      = PSR_T_BIT,
-       .cpsr_val       = 0,
-       .fn             = blockops_trap,
-};
-
-static int __init blockops_check(void)
-{
-       register unsigned int err asm("r4") = 0;
-       unsigned int err_pos = 1;
-       unsigned int cache_type;
-       int i;
-
-       asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_type));
-
-       printk("Checking V6 block cache operations:\n");
-       register_undef_hook(&blockops_hook);
-
-       __asm__ ("mov   r0, %0\n\t"
-               "mov    r1, %1\n\t"
-               "mov    r2, #1\n\t"
-               ".word  0xec401f2c @ mcrr p15, 0, r1, r0, c12, 2\n\t"
-               "mov    r2, #2\n\t"
-               ".word  0xec401f0e @ mcrr p15, 0, r1, r0, c14, 0\n\t"
-               "mov    r2, #4\n\t"
-               ".word  0xec401f0c @ mcrr p15, 0, r1, r0, c12, 0\n\t"
-               "mov    r2, #8\n\t"
-               ".word  0xec401f06 @ mcrr p15, 0, r1, r0, c6, 0\n\t"
-               "mov    r2, #16\n\t"
-               ".word  0xec401f05 @ mcrr p15, 0, r1, r0, c5, 0\n\t"
-               :
-               : "r" (PAGE_OFFSET), "r" (PAGE_OFFSET + 128)
-               : "r0", "r1", "r2");
-
-       unregister_undef_hook(&blockops_hook);
-
-       for (i = 0; i < ARRAY_SIZE(func); i++, err_pos <<= 1)
-               printk("%30s: %ssupported\n", func[i], err & err_pos ? "not " : "");
-
-       if ((err & 8) == 0) {
-               printk(" --> Using %s block cache invalidate\n",
-                       cache_type & (1 << 24) ? "harvard" : "unified");
-               if (cache_type & (1 << 24))
-                       cpu_cache.dma_inv_range = blk_dma_inv_range_harvard;
-               else
-                       cpu_cache.dma_inv_range = blk_dma_inv_range_unified;
-       }
-       if ((err & 4) == 0) {
-               printk(" --> Using block cache clean\n");
-               cpu_cache.dma_clean_range        = blk_dma_clean_range;
-       }
-       if ((err & 2) == 0) {
-               printk(" --> Using block cache clean+invalidate\n");
-               cpu_cache.dma_flush_range        = blk_dma_flush_range;
-               cpu_cache.flush_kern_dcache_page = blk_flush_kern_dcache_page;
-       }
-
-       return 0;
-}
-
-__initcall(blockops_check);
index c168f322ef8c80d91fcdbded23a56d76856162c3..8b276ee38acfabdb65b35e6b07903716b9db100d 100644 (file)
@@ -420,7 +420,8 @@ static void __init bootmem_init(struct meminfo *mi)
  * Set up device the mappings.  Since we clear out the page tables for all
  * mappings above VMALLOC_END, we will remove any debug device mappings.
  * This means you have to be careful how you debug this function, or any
- * called function.  (Do it by code inspection!)
+ * called function.  This means you can't use any function or debugging
+ * method which may touch any device, otherwise the kernel _will_ crash.
  */
 static void __init devicemaps_init(struct machine_desc *mdesc)
 {
@@ -428,6 +429,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
        unsigned long addr;
        void *vectors;
 
+       /*
+        * Allocate the vector page early.
+        */
+       vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+       BUG_ON(!vectors);
+
        for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
                pmd_clear(pmd_off_k(addr));
 
@@ -461,12 +468,6 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
        create_mapping(&map);
 #endif
 
-       flush_cache_all();
-       local_flush_tlb_all();
-
-       vectors = alloc_bootmem_low_pages(PAGE_SIZE);
-       BUG_ON(!vectors);
-
        /*
         * Create a mapping for the machine vectors at the high-vectors
         * location (0xffff0000).  If we aren't using high-vectors, also
@@ -491,12 +492,13 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
                mdesc->map_io();
 
        /*
-        * Finally flush the tlb again - this ensures that we're in a
-        * consistent state wrt the writebuffer if the writebuffer needs
-        * draining.  After this point, we can start to touch devices
-        * again.
+        * Finally flush the caches and tlb to ensure that we're in a
+        * consistent state wrt the writebuffer.  This also ensures that
+        * any write-allocated cache lines in the vector page are written
+        * back.  After this point, we can start to touch devices again.
         */
        local_flush_tlb_all();
+       flush_cache_all();
 }
 
 /*
index 0f128c28fee43d620dd788a726f4af17e2a4967a..10901398e4a28787abd2392f19a1b109ab070706 100644 (file)
@@ -130,8 +130,7 @@ remap_area_pages(unsigned long start, unsigned long phys_addr,
  * mapping.  See include/asm-arm/proc-armv/pgtable.h for more information.
  */
 void __iomem *
-__ioremap(unsigned long phys_addr, size_t size, unsigned long flags,
-         unsigned long align)
+__ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
 {
        void * addr;
        struct vm_struct * area;
index f36677241ecd528527528cc779ee6fb067de7926..76b1135d401a6eb3b4851fe344fe6f052f70300f 100644 (file)
@@ -248,9 +248,7 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
 
        acpi_table_print_madt_entry(header);
 
-       /* no utility in registering a disabled processor */
-       if (processor->flags.enabled == 0)
-               return 0;
+       /* Register even disabled CPUs for cpu hotplug */
 
        x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
 
index 8f767d9aa45d73286af9f8a8a92b2fe901b33608..1ca5269b1e863c8d9b7d9792e1b796a6cb7d8b4e 100644 (file)
@@ -220,8 +220,9 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
        num_processors++;
 
        if ((num_processors > 8) &&
-           APIC_XAPIC(ver) &&
-           (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+           ((APIC_XAPIC(ver) &&
+            (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ||
+            (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)))
                def_to_bigsmp = 1;
        else
                def_to_bigsmp = 0;
index d71f4de44f79a1074ee3c614735576cf3b9a8369..dd73c0cb754b4051214f113bf0bad237b684148a 100644 (file)
@@ -137,6 +137,7 @@ retry_bteop:
                        bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
 
                        if (bte == NULL) {
+                               nasid_index++;
                                continue;
                        }
 
index 49b530c39a423d99ff59cf55d2ccdac4650705c6..5d54f5f4e92672b3b1b8f33b8f880154bdd83a43 100644 (file)
@@ -492,6 +492,9 @@ static struct proc_dir_entry *proc_sn2_ptc;
 
 static int __init sn2_ptc_init(void)
 {
+       if (!ia64_platform_is("sn2"))
+               return -ENOSYS;
+
        if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) {
                printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
                return -EINVAL;
index 6c6fbca3229c9625964c1801c8ba480d7ab5c492..19b54fbcd7eaf790c7136571b81f79e2ae1dc1a0 100644 (file)
@@ -743,13 +743,14 @@ sn_hwperf_ioctl(struct inode *in, struct file *fp, u32 op, u64 arg)
                if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
                        memset(p, 0, a.sz);
                        for (i = 0; i < nobj; i++) {
+                               int cpuobj_index = 0;
                                if (!SN_HWPERF_IS_NODE(objs + i))
                                        continue;
                                node = sn_hwperf_obj_to_cnode(objs + i);
                                for_each_online_cpu(j) {
                                        if (node != cpu_to_node(j))
                                                continue;
-                                       cpuobj = (struct sn_hwperf_object_info *) p + j;
+                                       cpuobj = (struct sn_hwperf_object_info *) p + cpuobj_index++;
                                        slice = 'a' + cpuid_to_slice(j);
                                        cdata = cpu_data(j);
                                        cpuobj->id = j;
index 988844a169e615a764fe7e43460738c8b628f89b..d016d672ec2b2515ff5c9af789a5e457f860ca06 100644 (file)
@@ -499,8 +499,12 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
 
        dev = create_parisc_device(mod_path);
        if (dev->id.hw_type != HPHW_FAULTY) {
-               printk("Two devices have hardware path %s.  Please file a bug with HP.\n"
-                       "In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
+               printk(KERN_ERR "Two devices have hardware path [%s].  "
+                               "IODC data for second device: "
+                               "%02x%02x%02x%02x%02x%02x\n"
+                               "Rearranging GSC cards sometimes helps\n",
+                       parisc_pathname(dev), iodc_data[0], iodc_data[1],
+                       iodc_data[3], iodc_data[4], iodc_data[5], iodc_data[6]);
                return NULL;
        }
 
index c7e66ee5b083729ff4a7305ef066d0c7d9c91a65..9af4b22a6d77e793a2600eec96529fd2e2183641 100644 (file)
@@ -1846,6 +1846,7 @@ sys_clone_wrapper:
        ldo     -16(%r30),%r29          /* Reference param save area */
 #endif
 
+       /* WARNING - Clobbers r19 and r21, userspace must save these! */
        STREG   %r2,PT_GR19(%r1)        /* save for child */
        STREG   %r30,PT_GR21(%r1)
        BL      sys_clone,%r2
index 1a1c66422736e331710780ff929c00c29ec09ff7..8f563871e83c599e068872215b1b0d4fc0a80bdf 100644 (file)
@@ -188,7 +188,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index)
        temp = pa_pdc_cell.cba;
        dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path);
        if (!dev) {
-               return PDC_NE_MOD;
+               return PDC_OK;
        }
 
        /* alloc_pa_dev sets dev->hpa */
index 0a331104ad5675a0c8f9440e44d8bb63977996ad..4eada1bb27f0f47afd27602d130ccfaa074e4982 100644 (file)
 #define CODE
 #include "compat_ioctl.c"
 
-/* Use this to get at 32-bit user passed pointers. 
-   See sys_sparc32.c for description about these. */
-#define A(__x) ((unsigned long)(__x))
-/* The same for use with copy_from_user() and copy_to_user(). */
-#define B(__x) ((void *)(unsigned long)(__x))
-
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-/* This really belongs in include/linux/drm.h -DaveM */
-#include "../../../drivers/char/drm/drm.h"
-
-typedef struct drm32_version {
-       int    version_major;     /* Major version                          */
-       int    version_minor;     /* Minor version                          */
-       int    version_patchlevel;/* Patch level                            */
-       int    name_len;          /* Length of name buffer                  */
-       u32    name;              /* Name of driver                         */
-       int    date_len;          /* Length of date buffer                  */
-       u32    date;              /* User-space buffer to hold date         */
-       int    desc_len;          /* Length of desc buffer                  */
-       u32    desc;              /* User-space buffer to hold desc         */
-} drm32_version_t;
-#define DRM32_IOCTL_VERSION    DRM_IOWR(0x00, drm32_version_t)
-
-static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_version_t *uversion = (drm32_version_t *)arg;
-       char *name_ptr, *date_ptr, *desc_ptr;
-       u32 tmp1, tmp2, tmp3;
-       drm_version_t kversion;
-       mm_segment_t old_fs;
-       int ret;
-
-       memset(&kversion, 0, sizeof(kversion));
-       if (get_user(kversion.name_len, &uversion->name_len) ||
-           get_user(kversion.date_len, &uversion->date_len) ||
-           get_user(kversion.desc_len, &uversion->desc_len) ||
-           get_user(tmp1, &uversion->name) ||
-           get_user(tmp2, &uversion->date) ||
-           get_user(tmp3, &uversion->desc))
-               return -EFAULT;
-
-       name_ptr = (char *) A(tmp1);
-       date_ptr = (char *) A(tmp2);
-       desc_ptr = (char *) A(tmp3);
-
-       ret = -ENOMEM;
-       if (kversion.name_len && name_ptr) {
-               kversion.name = kmalloc(kversion.name_len, GFP_KERNEL);
-               if (!kversion.name)
-                       goto out;
-       }
-       if (kversion.date_len && date_ptr) {
-               kversion.date = kmalloc(kversion.date_len, GFP_KERNEL);
-               if (!kversion.date)
-                       goto out;
-       }
-       if (kversion.desc_len && desc_ptr) {
-               kversion.desc = kmalloc(kversion.desc_len, GFP_KERNEL);
-               if (!kversion.desc)
-                       goto out;
-       }
-
-        old_fs = get_fs();
-       set_fs(KERNEL_DS);
-        ret = sys_ioctl (fd, DRM_IOCTL_VERSION, (unsigned long)&kversion);
-        set_fs(old_fs);
-
-       if (!ret) {
-               if ((kversion.name &&
-                    copy_to_user(name_ptr, kversion.name, kversion.name_len)) ||
-                   (kversion.date &&
-                    copy_to_user(date_ptr, kversion.date, kversion.date_len)) ||
-                   (kversion.desc &&
-                    copy_to_user(desc_ptr, kversion.desc, kversion.desc_len)))
-                       ret = -EFAULT;
-               if (put_user(kversion.version_major, &uversion->version_major) ||
-                   put_user(kversion.version_minor, &uversion->version_minor) ||
-                   put_user(kversion.version_patchlevel, &uversion->version_patchlevel) ||
-                   put_user(kversion.name_len, &uversion->name_len) ||
-                   put_user(kversion.date_len, &uversion->date_len) ||
-                   put_user(kversion.desc_len, &uversion->desc_len))
-                       ret = -EFAULT;
-       }
-
-out:
-       kfree(kversion.name);
-       kfree(kversion.date);
-       kfree(kversion.desc);
-       return ret;
-}
-
-typedef struct drm32_unique {
-       int     unique_len;       /* Length of unique                       */
-       u32     unique;           /* Unique name for driver instantiation   */
-} drm32_unique_t;
-#define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t)
-#define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t)
-
-static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_unique_t *uarg = (drm32_unique_t *)arg;
-       drm_unique_t karg;
-       mm_segment_t old_fs;
-       char *uptr;
-       u32 tmp;
-       int ret;
-
-       if (get_user(karg.unique_len, &uarg->unique_len))
-               return -EFAULT;
-       karg.unique = NULL;
-
-       if (get_user(tmp, &uarg->unique))
-               return -EFAULT;
-
-       uptr = (char *) A(tmp);
-
-       if (uptr) {
-               karg.unique = kmalloc(karg.unique_len, GFP_KERNEL);
-               if (!karg.unique)
-                       return -ENOMEM;
-               if (cmd == DRM32_IOCTL_SET_UNIQUE &&
-                   copy_from_user(karg.unique, uptr, karg.unique_len)) {
-                       kfree(karg.unique);
-                       return -EFAULT;
-               }
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       if (cmd == DRM32_IOCTL_GET_UNIQUE)
-               ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)&karg);
-       else
-               ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)&karg);
-        set_fs(old_fs);
-
-       if (!ret) {
-               if (cmd == DRM32_IOCTL_GET_UNIQUE &&
-                   uptr != NULL &&
-                   copy_to_user(uptr, karg.unique, karg.unique_len))
-                       ret = -EFAULT;
-               if (put_user(karg.unique_len, &uarg->unique_len))
-                       ret = -EFAULT;
-       }
-
-       kfree(karg.unique);
-       return ret;
-}
-
-typedef struct drm32_map {
-       u32             offset;  /* Requested physical address (0 for SAREA)*/
-       u32             size;    /* Requested physical size (bytes)         */
-       drm_map_type_t  type;    /* Type of memory to map                   */
-       drm_map_flags_t flags;   /* Flags                                   */
-       u32             handle;  /* User-space: "Handle" to pass to mmap    */
-                                /* Kernel-space: kernel-virtual address    */
-       int             mtrr;    /* MTRR slot used                          */
-                                /* Private data                            */
-} drm32_map_t;
-#define DRM32_IOCTL_ADD_MAP    DRM_IOWR(0x15, drm32_map_t)
-
-static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_map_t *uarg = (drm32_map_t *) arg;
-       drm_map_t karg;
-       mm_segment_t old_fs;
-       u32 tmp;
-       int ret;
-
-       ret  = get_user(karg.offset, &uarg->offset);
-       ret |= get_user(karg.size, &uarg->size);
-       ret |= get_user(karg.type, &uarg->type);
-       ret |= get_user(karg.flags, &uarg->flags);
-       ret |= get_user(tmp, &uarg->handle);
-       ret |= get_user(karg.mtrr, &uarg->mtrr);
-       if (ret)
-               return -EFAULT;
-
-       karg.handle = (void *) A(tmp);
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               ret  = put_user(karg.offset, &uarg->offset);
-               ret |= put_user(karg.size, &uarg->size);
-               ret |= put_user(karg.type, &uarg->type);
-               ret |= put_user(karg.flags, &uarg->flags);
-               tmp = (u32) (long)karg.handle;
-               ret |= put_user(tmp, &uarg->handle);
-               ret |= put_user(karg.mtrr, &uarg->mtrr);
-               if (ret)
-                       ret = -EFAULT;
-       }
-
-       return ret;
-}
-
-typedef struct drm32_buf_info {
-       int            count;   /* Entries in list                           */
-       u32            list;    /* (drm_buf_desc_t *) */ 
-} drm32_buf_info_t;
-#define DRM32_IOCTL_INFO_BUFS  DRM_IOWR(0x18, drm32_buf_info_t)
-
-static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_buf_info_t *uarg = (drm32_buf_info_t *)arg;
-       drm_buf_desc_t *ulist;
-       drm_buf_info_t karg;
-       mm_segment_t old_fs;
-       int orig_count, ret;
-       u32 tmp;
-
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp, &uarg->list))
-               return -EFAULT;
-
-       ulist = (drm_buf_desc_t *) A(tmp);
-
-       orig_count = karg.count;
-
-       karg.list = kmalloc(karg.count * sizeof(drm_buf_desc_t), GFP_KERNEL);
-       if (!karg.list)
-               return -EFAULT;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               if (karg.count <= orig_count &&
-                   (copy_to_user(ulist, karg.list,
-                                 karg.count * sizeof(drm_buf_desc_t))))
-                       ret = -EFAULT;
-               if (put_user(karg.count, &uarg->count))
-                       ret = -EFAULT;
-       }
-
-       kfree(karg.list);
-       return ret;
-}
-
-typedef struct drm32_buf_free {
-       int            count;
-       u32            list;    /* (int *) */
-} drm32_buf_free_t;
-#define DRM32_IOCTL_FREE_BUFS  DRM_IOW( 0x1a, drm32_buf_free_t)
-
-static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_buf_free_t *uarg = (drm32_buf_free_t *)arg;
-       drm_buf_free_t karg;
-       mm_segment_t old_fs;
-       int *ulist;
-       int ret;
-       u32 tmp;
-
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp, &uarg->list))
-               return -EFAULT;
-
-       ulist = (int *) A(tmp);
-
-       karg.list = kmalloc(karg.count * sizeof(int), GFP_KERNEL);
-       if (!karg.list)
-               return -ENOMEM;
-
-       ret = -EFAULT;
-       if (copy_from_user(karg.list, ulist, (karg.count * sizeof(int))))
-               goto out;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long) &karg);
-       set_fs(old_fs);
-
-out:
-       kfree(karg.list);
-       return ret;
-}
-
-typedef struct drm32_buf_pub {
-       int               idx;         /* Index into master buflist          */
-       int               total;       /* Buffer size                        */
-       int               used;        /* Amount of buffer in use (for DMA)  */
-       u32               address;     /* Address of buffer (void *)         */
-} drm32_buf_pub_t;
-
-typedef struct drm32_buf_map {
-       int           count;    /* Length of buflist                        */
-       u32           virtual;  /* Mmaped area in user-virtual (void *)     */
-       u32           list;     /* Buffer information (drm_buf_pub_t *)     */
-} drm32_buf_map_t;
-#define DRM32_IOCTL_MAP_BUFS   DRM_IOWR(0x19, drm32_buf_map_t)
-
-static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_buf_map_t *uarg = (drm32_buf_map_t *)arg;
-       drm32_buf_pub_t *ulist;
-       drm_buf_map_t karg;
-       mm_segment_t old_fs;
-       int orig_count, ret, i;
-       u32 tmp1, tmp2;
-
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp1, &uarg->virtual) ||
-           get_user(tmp2, &uarg->list))
-               return -EFAULT;
-
-       karg.virtual = (void *) A(tmp1);
-       ulist = (drm32_buf_pub_t *) A(tmp2);
-
-       orig_count = karg.count;
-
-       karg.list = kmalloc(karg.count * sizeof(drm_buf_pub_t), GFP_KERNEL);
-       if (!karg.list)
-               return -ENOMEM;
-
-       ret = -EFAULT;
-       for (i = 0; i < karg.count; i++) {
-               if (get_user(karg.list[i].idx, &ulist[i].idx) ||
-                   get_user(karg.list[i].total, &ulist[i].total) ||
-                   get_user(karg.list[i].used, &ulist[i].used) ||
-                   get_user(tmp1, &ulist[i].address))
-                       goto out;
-
-               karg.list[i].address = (void *) A(tmp1);
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               for (i = 0; i < orig_count; i++) {
-                       tmp1 = (u32) (long) karg.list[i].address;
-                       if (put_user(karg.list[i].idx, &ulist[i].idx) ||
-                           put_user(karg.list[i].total, &ulist[i].total) ||
-                           put_user(karg.list[i].used, &ulist[i].used) ||
-                           put_user(tmp1, &ulist[i].address)) {
-                               ret = -EFAULT;
-                               goto out;
-                       }
-               }
-               if (put_user(karg.count, &uarg->count))
-                       ret = -EFAULT;
-       }
-
-out:
-       kfree(karg.list);
-       return ret;
-}
-
-typedef struct drm32_dma {
-                               /* Indices here refer to the offset into
-                                  buflist in drm_buf_get_t.  */
-       int             context;          /* Context handle                 */
-       int             send_count;       /* Number of buffers to send      */
-       u32             send_indices;     /* List of handles to buffers (int *) */
-       u32             send_sizes;       /* Lengths of data to send (int *) */
-       drm_dma_flags_t flags;            /* Flags                          */
-       int             request_count;    /* Number of buffers requested    */
-       int             request_size;     /* Desired size for buffers       */
-       u32             request_indices;  /* Buffer information (int *)     */
-       u32             request_sizes;    /* (int *) */
-       int             granted_count;    /* Number of buffers granted      */
-} drm32_dma_t;
-#define DRM32_IOCTL_DMA             DRM_IOWR(0x29, drm32_dma_t)
-
-/* RED PEN     The DRM layer blindly dereferences the send/request
- *             indice/size arrays even though they are userland
- *             pointers.  -DaveM
- */
-static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_dma_t *uarg = (drm32_dma_t *) arg;
-       int *u_si, *u_ss, *u_ri, *u_rs;
-       drm_dma_t karg;
-       mm_segment_t old_fs;
-       int ret;
-       u32 tmp1, tmp2, tmp3, tmp4;
-
-       karg.send_indices = karg.send_sizes = NULL;
-       karg.request_indices = karg.request_sizes = NULL;
-
-       if (get_user(karg.context, &uarg->context) ||
-           get_user(karg.send_count, &uarg->send_count) ||
-           get_user(tmp1, &uarg->send_indices) ||
-           get_user(tmp2, &uarg->send_sizes) ||
-           get_user(karg.flags, &uarg->flags) ||
-           get_user(karg.request_count, &uarg->request_count) ||
-           get_user(karg.request_size, &uarg->request_size) ||
-           get_user(tmp3, &uarg->request_indices) ||
-           get_user(tmp4, &uarg->request_sizes) ||
-           get_user(karg.granted_count, &uarg->granted_count))
-               return -EFAULT;
-
-       u_si = (int *) A(tmp1);
-       u_ss = (int *) A(tmp2);
-       u_ri = (int *) A(tmp3);
-       u_rs = (int *) A(tmp4);
-
-       if (karg.send_count) {
-               karg.send_indices = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-               karg.send_sizes = kmalloc(karg.send_count * sizeof(int), GFP_KERNEL);
-
-               ret = -ENOMEM;
-               if (!karg.send_indices || !karg.send_sizes)
-                       goto out;
-
-               ret = -EFAULT;
-               if (copy_from_user(karg.send_indices, u_si,
-                                  (karg.send_count * sizeof(int))) ||
-                   copy_from_user(karg.send_sizes, u_ss,
-                                  (karg.send_count * sizeof(int))))
-                       goto out;
-       }
-
-       if (karg.request_count) {
-               karg.request_indices = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-               karg.request_sizes = kmalloc(karg.request_count * sizeof(int), GFP_KERNEL);
-
-               ret = -ENOMEM;
-               if (!karg.request_indices || !karg.request_sizes)
-                       goto out;
-
-               ret = -EFAULT;
-               if (copy_from_user(karg.request_indices, u_ri,
-                                  (karg.request_count * sizeof(int))) ||
-                   copy_from_user(karg.request_sizes, u_rs,
-                                  (karg.request_count * sizeof(int))))
-                       goto out;
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               if (put_user(karg.context, &uarg->context) ||
-                   put_user(karg.send_count, &uarg->send_count) ||
-                   put_user(karg.flags, &uarg->flags) ||
-                   put_user(karg.request_count, &uarg->request_count) ||
-                   put_user(karg.request_size, &uarg->request_size) ||
-                   put_user(karg.granted_count, &uarg->granted_count))
-                       ret = -EFAULT;
-
-               if (karg.send_count) {
-                       if (copy_to_user(u_si, karg.send_indices,
-                                        (karg.send_count * sizeof(int))) ||
-                           copy_to_user(u_ss, karg.send_sizes,
-                                        (karg.send_count * sizeof(int))))
-                               ret = -EFAULT;
-               }
-               if (karg.request_count) {
-                       if (copy_to_user(u_ri, karg.request_indices,
-                                        (karg.request_count * sizeof(int))) ||
-                           copy_to_user(u_rs, karg.request_sizes,
-                                        (karg.request_count * sizeof(int))))
-                               ret = -EFAULT;
-               }
-       }
-
-out:
-       kfree(karg.send_indices);
-       kfree(karg.send_sizes);
-       kfree(karg.request_indices);
-       kfree(karg.request_sizes);
-       return ret;
-}
-
-typedef struct drm32_ctx_res {
-       int             count;
-       u32             contexts; /* (drm_ctx_t *) */
-} drm32_ctx_res_t;
-#define DRM32_IOCTL_RES_CTX    DRM_IOWR(0x26, drm32_ctx_res_t)
-
-static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg)
-{
-       drm32_ctx_res_t *uarg = (drm32_ctx_res_t *) arg;
-       drm_ctx_t *ulist;
-       drm_ctx_res_t karg;
-       mm_segment_t old_fs;
-       int orig_count, ret;
-       u32 tmp;
-
-       karg.contexts = NULL;
-       if (get_user(karg.count, &uarg->count) ||
-           get_user(tmp, &uarg->contexts))
-               return -EFAULT;
-
-       ulist = (drm_ctx_t *) A(tmp);
-
-       orig_count = karg.count;
-       if (karg.count && ulist) {
-               karg.contexts = kmalloc((karg.count * sizeof(drm_ctx_t)), GFP_KERNEL);
-               if (!karg.contexts)
-                       return -ENOMEM;
-               if (copy_from_user(karg.contexts, ulist,
-                                  (karg.count * sizeof(drm_ctx_t)))) {
-                       kfree(karg.contexts);
-                       return -EFAULT;
-               }
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long) &karg);
-       set_fs(old_fs);
-
-       if (!ret) {
-               if (orig_count) {
-                       if (copy_to_user(ulist, karg.contexts,
-                                        (orig_count * sizeof(drm_ctx_t))))
-                               ret = -EFAULT;
-               }
-               if (put_user(karg.count, &uarg->count))
-                       ret = -EFAULT;
-       }
-
-       kfree(karg.contexts);
-       return ret;
-}
-
-#endif
-
 #define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) 
 
@@ -561,11 +31,6 @@ IOCTL_TABLE_START
 #define DECLARES
 #include "compat_ioctl.c"
 
-/* PA-specific ioctls */
-COMPATIBLE_IOCTL(PA_PERF_ON)
-COMPATIBLE_IOCTL(PA_PERF_OFF)
-COMPATIBLE_IOCTL(PA_PERF_VERSION)
-
 /* And these ioctls need translation */
 HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc)
 HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
@@ -590,17 +55,6 @@ HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
 COMPATIBLE_IOCTL(RTC_EPOCH_SET)
 #endif
 
-#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
-#endif /* DRM */
 IOCTL_TABLE_END
 
 int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 006385dbee6600a147c9ebeb3c827a23e0777118..197936d9359a4065332a2c9a67ad8bd69ad04f33 100644 (file)
@@ -30,6 +30,9 @@
 #include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
+#include <asm/io.h>
+
+#include <asm/smp.h>
 
 #undef PARISC_IRQ_CR16_COUNTS
 
@@ -43,26 +46,34 @@ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
 */
 static volatile unsigned long cpu_eiem = 0;
 
-static void cpu_set_eiem(void *info)
-{
-       set_eiem((unsigned long) info);
-}
-
-static inline void cpu_disable_irq(unsigned int irq)
+static void cpu_disable_irq(unsigned int irq)
 {
        unsigned long eirr_bit = EIEM_MASK(irq);
 
        cpu_eiem &= ~eirr_bit;
-        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+       /* Do nothing on the other CPUs.  If they get this interrupt,
+        * The & cpu_eiem in the do_cpu_irq_mask() ensures they won't
+        * handle it, and the set_eiem() at the bottom will ensure it
+        * then gets disabled */
 }
 
 static void cpu_enable_irq(unsigned int irq)
 {
        unsigned long eirr_bit = EIEM_MASK(irq);
 
-       mtctl(eirr_bit, 23);    /* clear EIRR bit before unmasking */
        cpu_eiem |= eirr_bit;
-        on_each_cpu(cpu_set_eiem, (void *) cpu_eiem, 1, 1);
+
+       /* FIXME: while our interrupts aren't nested, we cannot reset
+        * the eiem mask if we're already in an interrupt.  Once we
+        * implement nested interrupts, this can go away
+        */
+       if (!in_interrupt())
+               set_eiem(cpu_eiem);
+
+       /* This is just a simple NOP IPI.  But what it does is cause
+        * all the other CPUs to do a set_eiem(cpu_eiem) at the end
+        * of the interrupt handler */
+       smp_send_all_nop();
 }
 
 static unsigned int cpu_startup_irq(unsigned int irq)
@@ -74,6 +85,35 @@ static unsigned int cpu_startup_irq(unsigned int irq)
 void no_ack_irq(unsigned int irq) { }
 void no_end_irq(unsigned int irq) { }
 
+#ifdef CONFIG_SMP
+int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
+{
+       int cpu_dest;
+
+       /* timer and ipi have to always be received on all CPUs */
+       if (irq == TIMER_IRQ || irq == IPI_IRQ) {
+               /* Bad linux design decision.  The mask has already
+                * been set; we must reset it */
+               irq_affinity[irq] = CPU_MASK_ALL;
+               return -EINVAL;
+       }
+
+       /* whatever mask they set, we just allow one CPU */
+       cpu_dest = first_cpu(*dest);
+       *dest = cpumask_of_cpu(cpu_dest);
+
+       return 0;
+}
+
+static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+       if (cpu_check_affinity(irq, &dest))
+               return;
+
+       irq_affinity[irq] = dest;
+}
+#endif
+
 static struct hw_interrupt_type cpu_interrupt_type = {
        .typename       = "CPU",
        .startup        = cpu_startup_irq,
@@ -82,7 +122,9 @@ static struct hw_interrupt_type cpu_interrupt_type = {
        .disable        = cpu_disable_irq,
        .ack            = no_ack_irq,
        .end            = no_end_irq,
-//     .set_affinity   = cpu_set_affinity_irq,
+#ifdef CONFIG_SMP
+       .set_affinity   = cpu_set_affinity_irq,
+#endif
 };
 
 int show_interrupts(struct seq_file *p, void *v)
@@ -219,6 +261,17 @@ int txn_alloc_irq(unsigned int bits_wide)
        return -1;
 }
 
+
+unsigned long txn_affinity_addr(unsigned int irq, int cpu)
+{
+#ifdef CONFIG_SMP
+       irq_affinity[irq] = cpumask_of_cpu(cpu);
+#endif
+
+       return cpu_data[cpu].txn_addr;
+}
+
+
 unsigned long txn_alloc_addr(unsigned int virt_irq)
 {
        static int next_cpu = -1;
@@ -233,7 +286,7 @@ unsigned long txn_alloc_addr(unsigned int virt_irq)
        if (next_cpu >= NR_CPUS) 
                next_cpu = 0;   /* nothing else, assign monarch */
 
-       return cpu_data[next_cpu].txn_addr;
+       return txn_affinity_addr(virt_irq, next_cpu);
 }
 
 
@@ -250,10 +303,11 @@ void do_cpu_irq_mask(struct pt_regs *regs)
        irq_enter();
 
        /*
-        * Only allow interrupt processing to be interrupted by the
-        * timer tick
+        * Don't allow TIMER or IPI nested interrupts.
+        * Allowing any single interrupt to nest can lead to that CPU
+        * handling interrupts with all enabled interrupts unmasked.
         */
-       set_eiem(EIEM_MASK(TIMER_IRQ));
+       set_eiem(0UL);
 
        /* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
         * 2) We loop here on EIRR contents in order to avoid
@@ -267,23 +321,41 @@ void do_cpu_irq_mask(struct pt_regs *regs)
                if (!eirr_val)
                        break;
 
-               if (eirr_val & EIEM_MASK(TIMER_IRQ))
-                       set_eiem(0);
-
                mtctl(eirr_val, 23); /* reset bits we are going to process */
 
                /* Work our way from MSb to LSb...same order we alloc EIRs */
                for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
+#ifdef CONFIG_SMP
+                       cpumask_t dest = irq_affinity[irq];
+#endif
                        if (!(bit & eirr_val))
                                continue;
 
                        /* clear bit in mask - can exit loop sooner */
                        eirr_val &= ~bit;
 
+#ifdef CONFIG_SMP
+                       /* FIXME: because generic set affinity mucks
+                        * with the affinity before sending it to us
+                        * we can get the situation where the affinity is
+                        * wrong for our CPU type interrupts */
+                       if (irq != TIMER_IRQ && irq != IPI_IRQ &&
+                           !cpu_isset(smp_processor_id(), dest)) {
+                               int cpu = first_cpu(dest);
+
+                               printk(KERN_DEBUG "redirecting irq %d from CPU %d to %d\n",
+                                      irq, smp_processor_id(), cpu);
+                               gsc_writel(irq + CPU_IRQ_BASE,
+                                          cpu_data[cpu].hpa);
+                               continue;
+                       }
+#endif
+
                        __do_IRQ(irq, regs);
                }
        }
-       set_eiem(cpu_eiem);
+
+       set_eiem(cpu_eiem);     /* restore original mask */
        irq_exit();
 }
 
@@ -291,12 +363,14 @@ void do_cpu_irq_mask(struct pt_regs *regs)
 static struct irqaction timer_action = {
        .handler = timer_interrupt,
        .name = "timer",
+       .flags = SA_INTERRUPT,
 };
 
 #ifdef CONFIG_SMP
 static struct irqaction ipi_action = {
        .handler = ipi_interrupt,
        .name = "IPI",
+       .flags = SA_INTERRUPT,
 };
 #endif
 
index 44670d6e06f4dfb9ab8de1afb16f458524a7e463..f6fec62b6a2feb79365695cea0e01f4faf496ad9 100644 (file)
@@ -196,8 +196,7 @@ static int perf_open(struct inode *inode, struct file *file);
 static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
 static ssize_t perf_write(struct file *file, const char __user *buf, size_t count, 
        loff_t *ppos);
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-       unsigned long arg);
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 static void perf_start_counters(void);
 static int perf_stop_counters(uint32_t *raddr);
 static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
@@ -438,48 +437,56 @@ static void perf_patch_images(void)
  * must be running on the processor that you wish to change.
  */
 
-static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-       unsigned long arg)
+static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        long error_start;
-       uint32_t raddr[4];      
+       uint32_t raddr[4];
+       int error = 0;
 
+       lock_kernel();
        switch (cmd) {
 
            case PA_PERF_ON:
                        /* Start the counters */
                        perf_start_counters();
-                       return 0;
+                       break;
 
            case PA_PERF_OFF:
                        error_start = perf_stop_counters(raddr);
                        if (error_start != 0) {
                                printk(KERN_ERR "perf_off: perf_stop_counters = %ld\n", error_start);
-                               return -EFAULT; 
+                               error = -EFAULT;
+                               break;
                        }
 
                        /* copy out the Counters */
                        if (copy_to_user((void __user *)arg, raddr, 
                                        sizeof (raddr)) != 0) {
-                               return -EFAULT;
+                               error =  -EFAULT;
+                               break;
                        }
-                       return 0;
+                       break;
 
            case PA_PERF_VERSION:
                        /* Return the version # */
-                       return put_user(PERF_VERSION, (int *)arg);
+                       error = put_user(PERF_VERSION, (int *)arg);
+                       break;
 
            default:
-                       break;
+                       error = -ENOTTY;
        }
-       return -ENOTTY;
+
+       unlock_kernel();
+
+       return error;
 }
 
 static struct file_operations perf_fops = {
        .llseek = no_llseek,
        .read = perf_read,
        .write = perf_write,
-       .ioctl = perf_ioctl,
+       .unlocked_ioctl = perf_ioctl,
+       .compat_ioctl = perf_ioctl,
        .open = perf_open,
        .release = perf_release
 };
index b6fe202a620d5b4b013029a71e4e8cf75edd1ad4..27160e8bf15ba3f31010ab0fa978961043df2140 100644 (file)
@@ -264,6 +264,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                 * sigkill.  perhaps it should be put in the status
                 * that it wants to exit.
                 */
+               ret = 0;
                DBG("sys_ptrace(KILL)\n");
                if (child->exit_state == EXIT_ZOMBIE)   /* already dead */
                        goto out_tsk;
@@ -344,11 +345,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 
        case PTRACE_GETEVENTMSG:
                 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
-               goto out;
+               goto out_tsk;
 
        default:
                ret = ptrace_request(child, request, addr, data);
-               goto out;
+               goto out_tsk;
        }
 
 out_wake_notrap:
index 82c24e62ab631f7bd57bb187f946238e235cae20..3a25a7bd673ece4e11eccfba23a1a63ffb644df1 100644 (file)
@@ -296,7 +296,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        struct rt_sigframe __user *frame;
        unsigned long rp, usp;
        unsigned long haddr, sigframe_size;
-       struct siginfo si;
        int err = 0;
 #ifdef __LP64__
        compat_int_t compat_val;
index a9ecf6465784eb0272518d648e39c2814d31dc02..ce89da0f654dac0bb43284264179b36eb0d65511 100644 (file)
@@ -181,12 +181,19 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                while (ops) {
                        unsigned long which = ffz(~ops);
 
+                       ops &= ~(1 << which);
+
                        switch (which) {
+                       case IPI_NOP:
+#if (kDEBUG>=100)
+                               printk(KERN_DEBUG "CPU%d IPI_NOP\n",this_cpu);
+#endif /* kDEBUG */
+                               break;
+                               
                        case IPI_RESCHEDULE:
 #if (kDEBUG>=100)
                                printk(KERN_DEBUG "CPU%d IPI_RESCHEDULE\n",this_cpu);
 #endif /* kDEBUG */
-                               ops &= ~(1 << IPI_RESCHEDULE);
                                /*
                                 * Reschedule callback.  Everything to be
                                 * done is done by the interrupt return path.
@@ -197,7 +204,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
                                printk(KERN_DEBUG "CPU%d IPI_CALL_FUNC\n",this_cpu);
 #endif /* kDEBUG */
-                               ops &= ~(1 << IPI_CALL_FUNC);
                                {
                                        volatile struct smp_call_struct *data;
                                        void (*func)(void *info);
@@ -231,7 +237,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
                                printk(KERN_DEBUG "CPU%d IPI_CPU_START\n",this_cpu);
 #endif /* kDEBUG */
-                               ops &= ~(1 << IPI_CPU_START);
 #ifdef ENTRY_SYS_CPUS
                                p->state = STATE_RUNNING;
 #endif
@@ -241,7 +246,6 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
                                printk(KERN_DEBUG "CPU%d IPI_CPU_STOP\n",this_cpu);
 #endif /* kDEBUG */
-                               ops &= ~(1 << IPI_CPU_STOP);
 #ifdef ENTRY_SYS_CPUS
 #else
                                halt_processor();
@@ -252,13 +256,11 @@ ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 #if (kDEBUG>=100)
                                printk(KERN_DEBUG "CPU%d is alive!\n",this_cpu);
 #endif /* kDEBUG */
-                               ops &= ~(1 << IPI_CPU_TEST);
                                break;
 
                        default:
                                printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
                                        this_cpu, which);
-                               ops &= ~(1 << which);
                                return IRQ_NONE;
                        } /* Switch */
                } /* while (ops) */
@@ -312,6 +314,12 @@ smp_send_start(void)       { send_IPI_allbutself(IPI_CPU_START); }
 void 
 smp_send_reschedule(int cpu) { send_IPI_single(cpu, IPI_RESCHEDULE); }
 
+void
+smp_send_all_nop(void)
+{
+       send_IPI_allbutself(IPI_NOP);
+}
+
 
 /**
  * Run a function on all other CPUs.
@@ -338,6 +346,10 @@ smp_call_function (void (*func) (void *info), void *info, int retry, int wait)
 
        /* Can deadlock when called with interrupts disabled */
        WARN_ON(irqs_disabled());
+
+       /* can also deadlock if IPIs are disabled */
+       WARN_ON((get_eiem() & (1UL<<(CPU_IRQ_MAX - IPI_IRQ))) == 0);
+
        
        data.func = func;
        data.info = info;
index b29b76b42bb70cd4f4df3892016665afc744874d..d66163492890203d86a51523f8cab035873d2d13 100644 (file)
@@ -164,7 +164,7 @@ linux_gateway_entry:
 #endif
        STREG   %r2,  TASK_PT_GR30(%r1)         /* ... and save it */
        
-       STREG   %r20, TASK_PT_GR20(%r1)
+       STREG   %r20, TASK_PT_GR20(%r1)         /* Syscall number */
        STREG   %r21, TASK_PT_GR21(%r1)
        STREG   %r22, TASK_PT_GR22(%r1)
        STREG   %r23, TASK_PT_GR23(%r1)         /* 4th argument */
@@ -527,6 +527,7 @@ lws_compare_and_swap:
                We *must* giveup this call and fail.
        */
        ldw     4(%sr2,%r20), %r28                      /* Load thread register */
+       /* WARNING: If cr27 cycles to the same value we have problems */
        mfctl   %cr27, %r21                             /* Get current thread register */
        cmpb,<>,n       %r21, %r28, cas_lock            /* Called recursive? */
        b       lws_exit                                /* Return error! */
index 5a5b246850817984436aa8ee4e957fecaf017f3f..8b6008ab217d4f1d4b481defbeb3b1b871115aeb 100644 (file)
@@ -40,7 +40,7 @@
 #endif
 
 unsigned long pci_probe_only = 1;
-unsigned long pci_assign_all_buses = 0;
+int pci_assign_all_buses = 0;
 
 /*
  * legal IO pages under MAX_ISA_PORT.  This is to ensure we don't touch
@@ -55,11 +55,6 @@ static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void do_bus_setup(struct pci_bus *bus);
 #endif
 
-unsigned int pcibios_assign_all_busses(void)
-{
-       return pci_assign_all_buses;
-}
-
 /* pci_io_base -- the base address from which io bars are offsets.
  * This is the lowest I/O base address (so bar values are always positive),
  * and it *must* be the start of ISA space if an ISA bus exists because
@@ -1186,17 +1181,6 @@ void phbs_remap_io(void)
                remap_bus_range(hose->bus);
 }
 
-/*
- * ppc64 can have multifunction devices that do not respond to function 0.
- * In this case we must scan all functions.
- * XXX this can go now, we use the OF device tree in all the
- * cases that caused problems. -- paulus
- */
-int pcibios_scan_all_fns(struct pci_bus *bus, int devfn)
-{
-       return 0;
-}
-
 static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 {
        struct pci_controller *hose = pci_bus_to_host(dev->bus);
index 59846b40d5216ebe16489e3074a36755083671e6..af4d1bc9a2eb5dc78f3fa1b6503902d32716ce7f 100644 (file)
@@ -146,9 +146,6 @@ EXPORT_SYMBOL(pci_bus_io_base);
 EXPORT_SYMBOL(pci_bus_io_base_phys);
 EXPORT_SYMBOL(pci_bus_mem_base_phys);
 EXPORT_SYMBOL(pci_bus_to_hose);
-EXPORT_SYMBOL(pci_resource_to_bus);
-EXPORT_SYMBOL(pci_phys_to_bus);
-EXPORT_SYMBOL(pci_bus_to_phys);
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
index 3d2abd95c7aea05b23cfb8e9cc8db69ffd9e9838..400793c7130466bc535f02fff0acc32db9b833c2 100644 (file)
@@ -36,8 +36,9 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
+
 #ifdef CONFIG_PPC64
-#include <asm/ptrace-common.h>
+#include "ptrace-common.h"
 #endif
 
 #ifdef CONFIG_PPC32
index 91eb952e0293c63d40580f0b82cde0068a60b140..61762640b8775ea1d1bfb7acb9f22c5b865708b5 100644 (file)
@@ -33,7 +33,8 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/ptrace-common.h>
+
+#include "ptrace-common.h"
 
 /*
  * does not yet catch signals sent when the child dies.
index f4ca29cf53649b6c35941b1c942c9cecac7c6439..f9587bcc6a48f89f375269db28f4d827174e1e38 100644 (file)
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/semaphore.h>
-#include <asm/imalloc.h>
 #include <asm/cacheflush.h>
 
+#include "mmu_decl.h"
+
 static DECLARE_MUTEX(imlist_sem);
 struct vm_struct * imlist = NULL;
 
index 1134f70f231d43bc57d61cd208d791a34f0e4fbd..81cfb0c2ec58bf5bd1d056b48206b551b1aad935 100644 (file)
@@ -64,7 +64,8 @@
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) printk(fmt)
index a4d7a327c0e52bc409e8890a3b91bee4799dda32..bea2d21ac6f789eb642890d2fc086b8ec27e08dd 100644 (file)
@@ -33,7 +33,6 @@ extern void invalidate_tlbcam_entry(int index);
 
 extern int __map_without_bats;
 extern unsigned long ioremap_base;
-extern unsigned long ioremap_bot;
 extern unsigned int rtas_data, rtas_size;
 
 extern PTE *Hash, *Hash_end;
@@ -42,6 +41,7 @@ extern unsigned long Hash_size, Hash_mask;
 extern unsigned int num_tlbcam_entries;
 #endif
 
+extern unsigned long ioremap_bot;
 extern unsigned long __max_low_memory;
 extern unsigned long __initial_memory_limit;
 extern unsigned long total_memory;
@@ -84,4 +84,16 @@ static inline void flush_HPTE(unsigned context, unsigned long va,
        else
                _tlbie(va);
 }
+#else /* CONFIG_PPC64 */
+/* imalloc region types */
+#define IM_REGION_UNUSED       0x1
+#define IM_REGION_SUBSET       0x2
+#define IM_REGION_EXISTS       0x4
+#define IM_REGION_OVERLAP      0x8
+#define IM_REGION_SUPERSET     0x10
+
+extern struct vm_struct * im_get_free_area(unsigned long size);
+extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
+                                     int region_type);
+extern void im_free(void *addr);
 #endif
index c7f7bb6f30b3698769951d6ba63141de9ae82074..2ffca63602c507ba1a201005e7441aee85ccfd3d 100644 (file)
@@ -64,7 +64,8 @@
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
-#include <asm/imalloc.h>
+
+#include "mmu_decl.h"
 
 unsigned long ioremap_bot = IMALLOC_BASE;
 static unsigned long phbs_io_bot = PHBS_IO_BASE;
index 957b091034220553fc6d48545d88e256350a2ef7..fb2a7c798e8278c51e8019e844f5600c134006e2 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/errno.h>
 #include <linux/hardirq.h>
 #include <linux/cpu.h>
+#include <linux/compiler.h>
 
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
@@ -631,8 +632,9 @@ void smp_core99_give_timebase(void)
        mb();
 
        /* wait for the secondary to have taken it */
-       for (t = 100000; t > 0 && sec_tb_reset; --t)
-               udelay(10);
+       /* note: can't use udelay here, since it needs the timebase running */
+       for (t = 10000000; t > 0 && sec_tb_reset; --t)
+               barrier();
        if (sec_tb_reset)
                /* XXX BUG_ON here? */
                printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n");
index 105f05341a414bdd3920857b2a0075a75fc33a87..58d1cc2023c843df763db2b4b3d11aa753172b05 100644 (file)
@@ -361,7 +361,8 @@ static void mpic_enable_irq(unsigned int irq)
        DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
 
        mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-                      mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
+                      mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+                      ~MPIC_VECPRI_MASK);
 
        /* make sure mask gets to controller before we return to user */
        do {
@@ -381,7 +382,8 @@ static void mpic_disable_irq(unsigned int irq)
        DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
 
        mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
-                      mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK);
+                      mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+                      MPIC_VECPRI_MASK);
 
        /* make sure mask gets to controller before we return to user */
        do {
@@ -735,12 +737,13 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
 
        spin_lock_irqsave(&mpic_lock, flags);
        if (is_ipi) {
-               reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK;
+               reg = mpic_ipi_read(irq - mpic->ipi_offset) &
+                       ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_ipi_write(irq - mpic->ipi_offset,
                               reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
        } else {
-               reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
-                       & MPIC_VECPRI_PRIORITY_MASK;
+               reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
+                       & ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
                               reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
        }
index a78e160b59a3545b8a06b78e2c78e503f1494d24..43fa2049568883d6b5c07cc304b77c93d3091abf 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/block/as-iosched.c
- *
  *  Anticipatory & deadline i/o scheduler.
  *
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
@@ -1373,10 +1371,6 @@ static void as_add_request(request_queue_t *q, struct request *rq)
        struct as_rq *alias;
        int data_dir;
 
-       if (arq->state != AS_RQ_PRESCHED) {
-               printk("arq->state: %d\n", arq->state);
-               WARN_ON(1);
-       }
        arq->state = AS_RQ_NEW;
 
        if (rq_data_dir(arq->request) == READ
index 2b64f5852bfd7bb64afe6317d8df72d300c6a6e9..ee0bb41694b05b5fbfc0efd111e60990e8116728 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/block/cfq-iosched.c
- *
  *  CFQ, or complete fairness queueing, disk scheduler.
  *
  *  Based on ideas from a previously unfinished io
index 7929471d7df7efb6a6f885f698da89c8f4c76cf7..9cbec09e8415fa83ecb828c91d30eb43ce16cfec 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/block/deadline-iosched.c
- *
  *  Deadline i/o scheduler.
  *
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
index e4c58827bb4660bc21bef638a3c9a926b2fc49c1..6c3fc8a10bf210f8cfcb8def13981c6274246b11 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/block/elevator.c
- *
  *  Block device elevator/IO-scheduler.
  *
  *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
index 5f52e30b43f812c75cef8289571e9a1a35bd2808..99c9ca6d5992ab18b3e40fa201423bd3e36a0055 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/block/ll_rw_blk.c
- *
  * Copyright (C) 1991, 1992 Linus Torvalds
  * Copyright (C) 1994,      Karl Keyte: Added support for disk statistics
  * Elevator latency, (C) 2000  Andrea Arcangeli <andrea@suse.de> SuSE
index e239a6c2923052c4271f5d6414d7eec87f85b508..a9e33db46e68b5432627835ea1945f02d40d861c 100644 (file)
@@ -1017,10 +1017,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                                status = -ENOMEM;
                                goto cleanup1;
                        }
-                       if (ioc->Request.Type.Direction == XFER_WRITE &&
-                               copy_from_user(buff[sg_used], data_ptr, sz)) {
+                       if (ioc->Request.Type.Direction == XFER_WRITE) {
+                               if (copy_from_user(buff[sg_used], data_ptr, sz)) {
                                        status = -ENOMEM;
-                                       goto cleanup1;                  
+                                       goto cleanup1;
+                               }
                        } else {
                                memset(buff[sg_used], 0, sz);
                        }
@@ -1138,8 +1139,15 @@ static int revalidate_allvol(ctlr_info_t *host)
 
        for(i=0; i< NWD; i++) {
                struct gendisk *disk = host->gendisk[i];
-               if (disk->flags & GENHD_FL_UP)
-                       del_gendisk(disk);
+               if (disk) {
+                       request_queue_t *q = disk->queue;
+
+                       if (disk->flags & GENHD_FL_UP)
+                               del_gendisk(disk);
+                       if (q)
+                               blk_cleanup_queue(q);
+                       put_disk(disk);
+               }
        }
 
         /*
@@ -1453,10 +1461,13 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv,
         * allows us to delete disk zero but keep the controller registered.
        */
        if (h->gendisk[0] != disk){
-               if (disk->flags & GENHD_FL_UP){
-                       blk_cleanup_queue(disk->queue);
-               del_gendisk(disk);
-                       drv->queue = NULL;
+               if (disk) {
+                       request_queue_t *q = disk->queue;
+                       if (disk->flags & GENHD_FL_UP)
+                               del_gendisk(disk);
+                       if (q)  
+                               blk_cleanup_queue(q);
+                       put_disk(disk); 
                }
        }
 
@@ -3225,9 +3236,14 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
        /* remove it from the disk list */
        for (j = 0; j < NWD; j++) {
                struct gendisk *disk = hba[i]->gendisk[j];
-               if (disk->flags & GENHD_FL_UP) {
-                       del_gendisk(disk);
-                       blk_cleanup_queue(disk->queue);
+               if (disk) {
+                       request_queue_t *q = disk->queue;
+
+                       if (disk->flags & GENHD_FL_UP) 
+                               del_gendisk(disk);
+                       if (q)
+                               blk_cleanup_queue(q);
+                       put_disk(disk);
                }
        }
 
index 76589782adcbf2f2f2372b919c6b49490bc4d593..810679dcbbb0cb006c619af994bb91f6e60cd7a0 100644 (file)
@@ -416,7 +416,7 @@ static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data
 }
 
 
-static struct aper_size_info_32 uli_sizes[7] =
+static const struct aper_size_info_32 uli_sizes[7] =
 {
        {256, 65536, 6, 10},
        {128, 32768, 5, 9},
@@ -470,7 +470,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev)
 }
 
 
-static struct aper_size_info_32 nforce3_sizes[5] =
+static const struct aper_size_info_32 nforce3_sizes[5] =
 {
        {512,  131072, 7, 0x00000000 },
        {256,  65536,  6, 0x00000008 },
index 27bca34b4a65d3770a0c8f54d8428720c3c76e7f..80ee17a8fc2322ed7e673a611a26201dc8329778 100644 (file)
@@ -97,7 +97,7 @@ void agp_backend_release(struct agp_bridge_data *bridge)
 EXPORT_SYMBOL(agp_backend_release);
 
 
-static struct { int mem, agp; } maxes_table[] = {
+static const struct { int mem, agp; } maxes_table[] = {
        {0, 0},
        {32, 4},
        {64, 28},
index c847df575cf5b96437b73dfb64311122a16326bf..97b0a890ba7f828310342e585e866af36e101136 100644 (file)
@@ -371,6 +371,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
                .device_id      = PCI_DEVICE_ID_VIA_3296_0,
                .chipset_name   = "P4M800",
        },
+       /* P4M800CE */
+       {
+               .device_id      = PCI_DEVICE_ID_VIA_P4M800CE,
+               .chipset_name   = "P4M800CE",
+       },
 
        { }, /* dummy final entry, always present */
 };
@@ -511,6 +516,7 @@ static struct pci_device_id agp_via_pci_table[] = {
        ID(PCI_DEVICE_ID_VIA_3269_0),
        ID(PCI_DEVICE_ID_VIA_83_87XX_1),
        ID(PCI_DEVICE_ID_VIA_3296_0),
+       ID(PCI_DEVICE_ID_VIA_P4M800CE),
        { }
 };
 
index cef024a7d048eaf63b79765700228dbf4fe9f3dd..cd6f45d186ab4d6a3b51ade91cf7bbb8f68a4f3a 100644 (file)
@@ -36,8 +36,6 @@
 #include <asm/hardware.h>      /* Pick up IXP2000-specific bits */
 #include <asm/arch/gpio.h>
 
-static struct device_driver ixp2000_i2c_driver;
-
 static inline int ixp2000_scl_pin(void *data)
 {
        return ((struct ixp2000_i2c_pins*)data)->scl_pin;
@@ -120,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
        drv_data->algo_data.timeout = 100;
 
        drv_data->adapter.id = I2C_HW_B_IXP2000,
-       strlcpy(drv_data->adapter.name, ixp2000_i2c_driver.name,
+       strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
                I2C_NAME_SIZE);
        drv_data->adapter.algo_data = &drv_data->algo_data,
 
@@ -132,7 +130,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev)
        gpio_line_set(gpio->sda_pin, 0);
 
        if ((err = i2c_bit_add_bus(&drv_data->adapter)) != 0) {
-               dev_err(dev, "Could not install, error %d\n", err);
+               dev_err(&plat_dev->dev, "Could not install, error %d\n", err);
                kfree(drv_data);
                return err;
        } 
index f87220be3c87ddc09795e1d77d6dc1eda0e56986..e422d8b2d4d69536f618dc8e883907152b5119bd 100644 (file)
@@ -35,8 +35,6 @@
 
 #include <asm/hardware.h>      /* Pick up IXP4xx-specific bits */
 
-static struct platform_driver ixp4xx_i2c_driver;
-
 static inline int ixp4xx_scl_pin(void *data)
 {
        return ((struct ixp4xx_i2c_pins*)data)->scl_pin;
@@ -128,7 +126,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
        drv_data->algo_data.timeout = 100;
 
        drv_data->adapter.id = I2C_HW_B_IXP4XX;
-       strlcpy(drv_data->adapter.name, ixp4xx_i2c_driver.driver.name,
+       strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
                I2C_NAME_SIZE);
        drv_data->adapter.algo_data = &drv_data->algo_data;
 
@@ -140,8 +138,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
        gpio_line_set(gpio->sda_pin, 0);
 
        if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) {
-               printk(KERN_ERR "ERROR: Could not install %s\n", 
-                               plat_dev->dev.bus_id);
+               printk(KERN_ERR "ERROR: Could not install %s\n", plat_dev->dev.bus_id);
 
                kfree(drv_data);
                return err;
index ed2bc87f475b797a47e688428989bb4d8177d40a..31e649a9ff710a9462057fb894228587c647634d 100644 (file)
@@ -625,7 +625,7 @@ config BLK_DEV_NS87415
        tristate "NS87415 chipset support"
        help
          This driver adds detection and support for the NS87415 chip
-         (used in SPARC64, among others).
+         (used mainly on SPARC64 and PA-RISC machines).
 
          Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
 
index c2f47923d174bd6eedb352ec9164b52eac38b488..9455e42abb23cfba0ab4ed44a7b06068d14cf482 100644 (file)
@@ -3328,8 +3328,8 @@ static ide_proc_entry_t idecd_proc[] = {
 #endif
 
 static ide_driver_t ide_cdrom_driver = {
-       .owner                  = THIS_MODULE,
        .gen_driver = {
+               .owner          = THIS_MODULE,
                .name           = "ide-cdrom",
                .bus            = &ide_bus_type,
                .probe          = ide_cd_probe,
@@ -3510,8 +3510,8 @@ static void __exit ide_cdrom_exit(void)
 {
        driver_unregister(&ide_cdrom_driver.gen_driver);
 }
-static int ide_cdrom_init(void)
+
+static int __init ide_cdrom_init(void)
 {
        return driver_register(&ide_cdrom_driver.gen_driver);
 }
index e827b39e4b3c7f0c02d1a964a6a9a3a5b0a7cb29..f4e3d3527b0e6f5e5cdf12f2a8e8da47e7082e1d 100644 (file)
@@ -1089,8 +1089,8 @@ static void ide_device_shutdown(struct device *dev)
 }
 
 static ide_driver_t idedisk_driver = {
-       .owner                  = THIS_MODULE,
        .gen_driver = {
+               .owner          = THIS_MODULE,
                .name           = "ide-disk",
                .bus            = &ide_bus_type,
                .probe          = ide_disk_probe,
@@ -1266,7 +1266,7 @@ static void __exit idedisk_exit (void)
        driver_unregister(&idedisk_driver.gen_driver);
 }
 
-static int idedisk_init (void)
+static int __init idedisk_init(void)
 {
        return driver_register(&idedisk_driver.gen_driver);
 }
index f615ab759962d3ef50b454e6f178dc81faaa3908..9e293c8063dccfbe20b9589df836b8b0fa34f4f8 100644 (file)
@@ -1925,8 +1925,8 @@ static ide_proc_entry_t idefloppy_proc[] = {
 static int ide_floppy_probe(struct device *);
 
 static ide_driver_t idefloppy_driver = {
-       .owner                  = THIS_MODULE,
        .gen_driver = {
+               .owner          = THIS_MODULE,
                .name           = "ide-floppy",
                .bus            = &ide_bus_type,
                .probe          = ide_floppy_probe,
@@ -2191,10 +2191,7 @@ static void __exit idefloppy_exit (void)
        driver_unregister(&idefloppy_driver.gen_driver);
 }
 
-/*
- *     idefloppy_init will register the driver for each floppy.
- */
-static int idefloppy_init (void)
+static int __init idefloppy_init(void)
 {
        printk("ide-floppy driver " IDEFLOPPY_VERSION "\n");
        return driver_register(&idefloppy_driver.gen_driver);
index 5275cbb1afe9c790fe9b427c0c916dcfa7c4b9a3..ecfafcdafea41ec8a776796e3c9f0e93aa6b1b15 100644 (file)
@@ -1629,12 +1629,6 @@ EXPORT_SYMBOL(ide_init_drive_cmd);
  *     for the new rq to be completed.  This is VERY DANGEROUS, and is
  *     intended for careful use by the ATAPI tape/cdrom driver code.
  *
- *     If action is ide_next, then the rq is queued immediately after
- *     the currently-being-processed-request (if any), and the function
- *     returns without waiting for the new rq to be completed.  As above,
- *     This is VERY DANGEROUS, and is intended for careful use by the
- *     ATAPI tape/cdrom driver code.
- *
  *     If action is ide_end, then the rq is queued at the end of the
  *     request queue, and the function returns immediately without waiting
  *     for the new rq to be completed. This is again intended for careful
index b09a6537c7a8a9b2d975026b38d4edcae53757d5..41d46dbe6c24c0e68ee546633100caf93839d9d0 100644 (file)
@@ -410,10 +410,10 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
 {
        u64 addr = BLK_BOUNCE_HIGH;     /* dma64_addr_t */
 
-       if (on && drive->media == ide_disk) {
-               if (!PCI_DMA_BUS_IS_PHYS)
-                       addr = BLK_BOUNCE_ANY;
-               else if (HWIF(drive)->pci_dev)
+       if (!PCI_DMA_BUS_IS_PHYS) {
+               addr = BLK_BOUNCE_ANY;
+       } else if (on && drive->media == ide_disk) {
+               if (HWIF(drive)->pci_dev)
                        addr = HWIF(drive)->pci_dev->dma_mask;
        }
 
index 0ac7eb8f40d537ae04c2db1b23a2d819df835e69..7d7944ed4158b89b88e73d6fb4220fdb1111609c 100644 (file)
@@ -4748,8 +4748,8 @@ static ide_proc_entry_t idetape_proc[] = {
 static int ide_tape_probe(struct device *);
 
 static ide_driver_t idetape_driver = {
-       .owner                  = THIS_MODULE,
        .gen_driver = {
+               .owner          = THIS_MODULE,
                .name           = "ide-tape",
                .bus            = &ide_bus_type,
                .probe          = ide_tape_probe,
@@ -4916,10 +4916,7 @@ static void __exit idetape_exit (void)
        unregister_chrdev(IDETAPE_MAJOR, "ht");
 }
 
-/*
- *     idetape_init will register the driver for each tape.
- */
-static int idetape_init (void)
+static int __init idetape_init(void)
 {
        int error = 1;
        idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
index 54f9639c2a8cc1fbd42685d0271de662bc1a9210..62ebefd6394a0af83b10a188c86e9a12a4d1520a 100644 (file)
@@ -51,8 +51,6 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-#define DEBUG_TASKFILE 0       /* unset when fixed */
-
 static void ata_bswap_data (void *buffer, int wcount)
 {
        u16 *p = buffer;
@@ -765,9 +763,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
        ide_hwif_t *hwif        = HWIF(drive);
        task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
        hob_struct_t *hobfile   = (hob_struct_t *) task->hobRegister;
-#if DEBUG_TASKFILE
-       u8 status;
-#endif
 
        if (task->data_phase == TASKFILE_MULTI_IN ||
            task->data_phase == TASKFILE_MULTI_OUT) {
@@ -778,19 +773,13 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
        }
 
        /*
-        * (ks) Check taskfile in/out flags.
+        * (ks) Check taskfile in flags.
         * If set, then execute as it is defined.
         * If not set, then define default settings.
         * The default values are:
-        *      write and read all taskfile registers (except data) 
-        *      write and read the hob registers (sector,nsector,lcyl,hcyl)
+        *      read all taskfile registers (except data)
+        *      read the hob registers (sector, nsector, lcyl, hcyl)
         */
-       if (task->tf_out_flags.all == 0) {
-               task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
-               if (drive->addressing == 1)
-                       task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
-        }
-
        if (task->tf_in_flags.all == 0) {
                task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
                if (drive->addressing == 1)
@@ -803,16 +792,6 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
        SELECT_MASK(drive, 0);
 
-#if DEBUG_TASKFILE
-       status = hwif->INB(IDE_STATUS_REG);
-       if (status & 0x80) {
-               printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
-               udelay(100);
-               status = hwif->INB(IDE_STATUS_REG);
-               printk("flagged_taskfile -> Status = %02x\n", status);
-       }
-#endif
-
        if (task->tf_out_flags.b.data) {
                u16 data =  taskfile->data + (hobfile->data << 8);
                hwif->OUTW(data, IDE_DATA_REG);
index 52cadc005d728bb3dd2af6cf443044376475f21e..a21b1e11eef4e5fe0ca849847695b049106fd943 100644 (file)
@@ -65,23 +65,6 @@ static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
 #define BUSCLOCK(D)    \
        ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D)))
 
-#if 0
-               if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
-                       (void) pci_read_config_byte(dev, 0x54, &art);
-                       p += sprintf(p, "DMA Mode:       %s(%s)",
-                               (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO",
-                               (art&0x02)?"2":(art&0x01)?"1":"0");
-                       p += sprintf(p, "          %s(%s)",
-                               (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO",
-                               (art&0x08)?"2":(art&0x04)?"1":"0");
-                       p += sprintf(p, "         %s(%s)",
-                               (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO",
-                               (art&0x20)?"2":(art&0x10)?"1":"0");
-                       p += sprintf(p, "           %s(%s)\n",
-                               (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO",
-                               (art&0x80)?"2":(art&0x40)?"1":"0");
-               } else {
-#endif
 
 /*
  * TO DO: active tuning and correction of cards without a bios.
@@ -112,13 +95,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
        switch(hwif->pci_dev->device) {
                case PCI_DEVICE_ID_ARTOP_ATP865:
                case PCI_DEVICE_ID_ARTOP_ATP865R:
-#if 0
-                       mode = (hwif->INB(hwif->dma_master) & 0x10) ? 4 : 3;
-#else
                        mode = (hwif->INB(((hwif->channel) ?
                                        hwif->mate->dma_status :
                                        hwif->dma_status)) & 0x10) ? 4 : 3;
-#endif
                        break;
                case PCI_DEVICE_ID_ARTOP_ATP860:
                case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -263,35 +242,9 @@ static int aec62xx_irq_timeout (ide_drive_t *drive)
                case PCI_DEVICE_ID_ARTOP_ATP865:
                case PCI_DEVICE_ID_ARTOP_ATP865R:
                        printk(" AEC62XX time out ");
-#if 0
-                       {
-                               int i = 0;
-                               u8 reg49h = 0;
-                               pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, &reg49h);
-                               for (i=0;i<256;i++)
-                                       pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10);
-                               pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10);
-                       }
-                       return 0;
-#endif
                default:
                        break;
        }
-#if 0
-       {
-               ide_hwif_t *hwif        = HWIF(drive);
-               struct pci_dev *dev     = hwif->pci_dev;
-               u8 tmp1 = 0, tmp2 = 0, mode6 = 0;
-
-               pci_read_config_byte(dev, 0x44, &tmp1);
-               pci_read_config_byte(dev, 0x45, &tmp2);
-               printk(" AEC6280 r44=%x r45=%x ",tmp1,tmp2);
-               mode6 = HWIF(drive)->INB(((hwif->channel) ?
-                                          hwif->mate->dma_status :
-                                          hwif->dma_status));
-               printk(" AEC6280 133=%x ", (mode6 & 0x10));
-       }
-#endif
        return 0;
 }
 
index 6cf49394a80f35e946279061980a3489ebcf7df3..cf84350efc550b3dc804dd9a5cb03d8978dc9002 100644 (file)
@@ -876,10 +876,15 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
  
 static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
+       static struct pci_device_id ati_rs100[] = {
+               { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100) },
+               { },
+       };
+
        ide_pci_device_t *d = &ali15x3_chipset;
 
-       if(pci_find_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS100, NULL))
-               printk(KERN_ERR "Warning: ATI Radeon IGP Northbridge is not yet fully tested.\n");
+       if (pci_dev_present(ati_rs100))
+               printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
 
 #if defined(CONFIG_SPARC64)
        d->init_hwif = init_hwif_common_ali15x3;
index 7dc24682d197d44a4be32da254b0beb7b190e3fc..ea3c52cc8ac1cf5c55aad7d31267d6f5d2142a00 100644 (file)
@@ -222,10 +222,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
 
        /* We must not grab the entire device, it has 'ISA' space in its
           BARS too and we will freak out other bits of the kernel */
-       if(pci_enable_device_bars(dev, 1<<2))
-       {
+       if (pci_enable_device_bars(dev, 1<<2)) {
                printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
-               return 1;
+               return -ENODEV;
        }
        pci_set_master(dev);
        if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
index 022d244f2eb098dc3c99a13929ebbb5d109b7102..f1ca154dd52ca088f25ec0c0ac28845a47a59e18 100644 (file)
@@ -6,7 +6,13 @@
  *
  *  May be copied or modified under the terms of the GNU General Public License
  *
- *  Documentation available under NDA only
+ *  Documentation for CMD680:
+ *  http://gkernel.sourceforge.net/specs/sii/sii-0680a-v1.31.pdf.bz2
+ *
+ *  Documentation for SiI 3112:
+ *  http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
+ *
+ *  Errata and other documentation only available under NDA.
  *
  *
  *  FAQ Items:
index 16b3e2d8bfb107635f5489c8b3b75c807b1a291a..75a2253a3e6872813a94179db4767c3751502f4e 100644 (file)
@@ -87,6 +87,7 @@ static const struct {
        u8 chipset_family;
        u8 flags;
 } SiSHostChipInfo[] = {
+       { "SiS965",     PCI_DEVICE_ID_SI_965,   ATA_133  },
        { "SiS745",     PCI_DEVICE_ID_SI_745,   ATA_100  },
        { "SiS735",     PCI_DEVICE_ID_SI_735,   ATA_100  },
        { "SiS733",     PCI_DEVICE_ID_SI_733,   ATA_100  },
index a4d099c937ff731c7627b7a650b5cc727cc5b261..7161ce0ef5aafb78b59bb563921f783a46c37945 100644 (file)
@@ -79,6 +79,7 @@ static struct via_isa_bridge {
        u8 rev_max;
        u16 flags;
 } via_isa_bridges[] = {
+       { "vt6410",     PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
        { "vt8237",     PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
        { "vt8235",     PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
        { "vt8233a",    PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -100,185 +101,14 @@ static struct via_isa_bridge {
        { NULL }
 };
 
-static struct via_isa_bridge *via_config;
-static unsigned int via_80w;
 static unsigned int via_clock;
 static char *via_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA100", "UDMA133" };
 
-/*
- * VIA /proc entry.
- */
-
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
-
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 via_proc = 0;
-static unsigned long via_base;
-static struct pci_dev *bmide_dev, *isa_dev;
-
-static char *via_control3[] = { "No limit", "64", "128", "192" };
-
-#define via_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
-#define via_print_drive(name, format, arg...)\
-       p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
-
-
-/**
- *     via_get_info            -       generate via /proc file 
- *     @buffer: buffer for data
- *     @addr: set to start of data to use
- *     @offset: current file offset
- *     @count: size of read
- *
- *     Fills in buffer with the debugging/configuration information for
- *     the VIA chipset tuning and attached drives
- */
-static int via_get_info(char *buffer, char **addr, off_t offset, int count)
+struct via82cxxx_dev
 {
-       int speed[4], cycle[4], setup[4], active[4], recover[4], den[4],
-                uen[4], udma[4], umul[4], active8b[4], recover8b[4];
-       struct pci_dev *dev = bmide_dev;
-       unsigned int v, u, i;
-       int len;
-       u16 c, w;
-       u8 t, x;
-       char *p = buffer;
-
-       via_print("----------VIA BusMastering IDE Configuration"
-               "----------------");
-
-       via_print("Driver Version:                     3.38");
-       via_print("South Bridge:                       VIA %s",
-               via_config->name);
-
-       pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
-       pci_read_config_byte(dev, PCI_REVISION_ID, &x);
-       via_print("Revision:                           ISA %#x IDE %#x", t, x);
-       via_print("Highest DMA rate:                   %s",
-               via_dma[via_config->flags & VIA_UDMA]);
-
-       via_print("BM-DMA base:                        %#lx", via_base);
-       via_print("PCI clock:                          %d.%dMHz",
-               via_clock / 1000, via_clock / 100 % 10);
-
-       pci_read_config_byte(dev, VIA_MISC_1, &t);
-       via_print("Master Read  Cycle IRDY:            %dws",
-               (t & 64) >> 6);
-       via_print("Master Write Cycle IRDY:            %dws",
-               (t & 32) >> 5);
-       via_print("BM IDE Status Register Read Retry:  %s",
-               (t & 8) ? "yes" : "no");
-
-       pci_read_config_byte(dev, VIA_MISC_3, &t);
-       via_print("Max DRDY Pulse Width:               %s%s",
-               via_control3[(t & 0x03)], (t & 0x03) ? " PCI clocks" : "");
-
-       via_print("-----------------------Primary IDE"
-               "-------Secondary IDE------");
-       via_print("Read DMA FIFO flush:   %10s%20s",
-               (t & 0x80) ? "yes" : "no", (t & 0x40) ? "yes" : "no");
-       via_print("End Sector FIFO flush: %10s%20s",
-               (t & 0x20) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
-       pci_read_config_byte(dev, VIA_IDE_CONFIG, &t);
-       via_print("Prefetch Buffer:       %10s%20s",
-               (t & 0x80) ? "yes" : "no", (t & 0x20) ? "yes" : "no");
-       via_print("Post Write Buffer:     %10s%20s",
-               (t & 0x40) ? "yes" : "no", (t & 0x10) ? "yes" : "no");
-
-       pci_read_config_byte(dev, VIA_IDE_ENABLE, &t);
-       via_print("Enabled:               %10s%20s",
-               (t & 0x02) ? "yes" : "no", (t & 0x01) ? "yes" : "no");
-
-       c = inb(via_base + 0x02) | (inb(via_base + 0x0a) << 8);
-       via_print("Simplex only:          %10s%20s",
-               (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
-
-       via_print("Cable Type:            %10s%20s",
-               (via_80w & 1) ? "80w" : "40w", (via_80w & 2) ? "80w" : "40w");
-
-       via_print("-------------------drive0----drive1"
-               "----drive2----drive3-----");
-
-       pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
-       pci_read_config_dword(dev, VIA_DRIVE_TIMING, &v);
-       pci_read_config_word(dev, VIA_8BIT_TIMING, &w);
-
-       if (via_config->flags & VIA_UDMA)
-               pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-       else u = 0;
-
-       for (i = 0; i < 4; i++) {
-
-               setup[i]     = ((t >> ((3 - i) << 1)) & 0x3) + 1;
-               recover8b[i] = ((w >> ((1 - (i >> 1)) << 3)) & 0xf) + 1;
-               active8b[i]  = ((w >> (((1 - (i >> 1)) << 3) + 4)) & 0xf) + 1;
-               active[i]    = ((v >> (((3 - i) << 3) + 4)) & 0xf) + 1;
-               recover[i]   = ((v >> ((3 - i) << 3)) & 0xf) + 1;
-               udma[i]      = ((u >> ((3 - i) << 3)) & 0x7) + 2;
-               umul[i]      = ((u >> (((3 - i) & 2) << 3)) & 0x8) ? 1 : 2;
-               uen[i]       = ((u >> ((3 - i) << 3)) & 0x20);
-               den[i]       = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
-
-               speed[i] = 2 * via_clock / (active[i] + recover[i]);
-               cycle[i] = 1000000 * (active[i] + recover[i]) / via_clock;
-
-               if (!uen[i] || !den[i])
-                       continue;
-
-               switch (via_config->flags & VIA_UDMA) {
-
-                       case VIA_UDMA_33:
-                               speed[i] = 2 * via_clock / udma[i];
-                               cycle[i] = 1000000 * udma[i] / via_clock;
-                               break;
-
-                       case VIA_UDMA_66:
-                               speed[i] = 4 * via_clock / (udma[i] * umul[i]);
-                               cycle[i] = 500000 * (udma[i] * umul[i]) / via_clock;
-                               break;
-
-                       case VIA_UDMA_100:
-                               speed[i] = 6 * via_clock / udma[i];
-                               cycle[i] = 333333 * udma[i] / via_clock;
-                               break;
-
-                       case VIA_UDMA_133:
-                               speed[i] = 8 * via_clock / udma[i];
-                               cycle[i] = 250000 * udma[i] / via_clock;
-                               break;
-               }
-       }
-
-       via_print_drive("Transfer Mode: ", "%10s",
-               den[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
-
-       via_print_drive("Address Setup: ", "%8dns",
-               1000000 * setup[i] / via_clock);
-       via_print_drive("Cmd Active:    ", "%8dns",
-               1000000 * active8b[i] / via_clock);
-       via_print_drive("Cmd Recovery:  ", "%8dns",
-               1000000 * recover8b[i] / via_clock);
-       via_print_drive("Data Active:   ", "%8dns",
-               1000000 * active[i] / via_clock);
-       via_print_drive("Data Recovery: ", "%8dns",
-               1000000 * recover[i] / via_clock);
-       via_print_drive("Cycle Time:    ", "%8dns",
-               cycle[i]);
-       via_print_drive("Transfer Rate: ", "%4d.%dMB/s",
-               speed[i] / 1000, speed[i] / 100 % 10);
-
-       /* hoping it is less than 4K... */
-       len = (p - buffer) - offset;
-       *addr = buffer + offset;
-
-       return len > count ? count : len;
-}
-
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
+       struct via_isa_bridge *via_config;
+       unsigned int via_80w;
+};
 
 /**
  *     via_set_speed                   -       write timing registers
@@ -289,11 +119,13 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
  *     via_set_speed writes timing values to the chipset registers
  */
 
-static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
+static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
 {
+       struct pci_dev *dev = hwif->pci_dev;
+       struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
        u8 t;
 
-       if (~via_config->flags & VIA_BAD_AST) {
+       if (~vdev->via_config->flags & VIA_BAD_AST) {
                pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t);
                t = (t & ~(3 << ((3 - dn) << 1))) | ((FIT(timing->setup, 1, 4) - 1) << ((3 - dn) << 1));
                pci_write_config_byte(dev, VIA_ADDRESS_SETUP, t);
@@ -305,7 +137,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
        pci_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - dn),
                ((FIT(timing->active, 1, 16) - 1) << 4) | (FIT(timing->recover, 1, 16) - 1));
 
-       switch (via_config->flags & VIA_UDMA) {
+       switch (vdev->via_config->flags & VIA_UDMA) {
                case VIA_UDMA_33:  t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 5) - 2)) : 0x03; break;
                case VIA_UDMA_66:  t = timing->udma ? (0xe8 | (FIT(timing->udma, 2, 9) - 2)) : 0x0f; break;
                case VIA_UDMA_100: t = timing->udma ? (0xe0 | (FIT(timing->udma, 2, 9) - 2)) : 0x07; break;
@@ -329,6 +161,7 @@ static void via_set_speed(struct pci_dev *dev, u8 dn, struct ide_timing *timing)
 static int via_set_drive(ide_drive_t *drive, u8 speed)
 {
        ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
+       struct via82cxxx_dev *vdev = ide_get_hwifdata(drive->hwif);
        struct ide_timing t, p;
        unsigned int T, UT;
 
@@ -337,7 +170,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
 
        T = 1000000000 / via_clock;
 
-       switch (via_config->flags & VIA_UDMA) {
+       switch (vdev->via_config->flags & VIA_UDMA) {
                case VIA_UDMA_33:   UT = T;   break;
                case VIA_UDMA_66:   UT = T/2; break;
                case VIA_UDMA_100:  UT = T/3; break;
@@ -352,7 +185,7 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
                ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
        }
 
-       via_set_speed(HWIF(drive)->pci_dev, drive->dn, &t);
+       via_set_speed(HWIF(drive), drive->dn, &t);
 
        if (!drive->init_speed)
                drive->init_speed = speed;
@@ -390,20 +223,41 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
  
 static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 {
-       u16 w80 = HWIF(drive)->udma_four;
+       ide_hwif_t *hwif = HWIF(drive);
+       struct via82cxxx_dev *vdev = ide_get_hwifdata(hwif);
+       u16 w80 = hwif->udma_four;
 
        u16 speed = ide_find_best_mode(drive,
                XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
-               (via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
-               (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
-               (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
-               (w80 && (via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
+               (vdev->via_config->flags & VIA_UDMA ? XFER_UDMA : 0) |
+               (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_66 ? XFER_UDMA_66 : 0) |
+               (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_100 ? XFER_UDMA_100 : 0) |
+               (w80 && (vdev->via_config->flags & VIA_UDMA) >= VIA_UDMA_133 ? XFER_UDMA_133 : 0));
 
        via_set_drive(drive, speed);
 
        if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
-               return HWIF(drive)->ide_dma_on(drive);
-       return HWIF(drive)->ide_dma_off_quietly(drive);
+               return hwif->ide_dma_on(drive);
+       return hwif->ide_dma_off_quietly(drive);
+}
+
+static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
+{
+       struct via_isa_bridge *via_config;
+       u8 t;
+
+       for (via_config = via_isa_bridges; via_config->id; via_config++)
+               if ((*isa = pci_find_device(PCI_VENDOR_ID_VIA +
+                       !!(via_config->flags & VIA_BAD_ID),
+                       via_config->id, NULL))) {
+
+                       pci_read_config_byte(*isa, PCI_REVISION_ID, &t);
+                       if (t >= via_config->rev_min &&
+                           t <= via_config->rev_max)
+                               break;
+               }
+
+       return via_config;
 }
 
 /**
@@ -418,82 +272,28 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
 static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name)
 {
        struct pci_dev *isa = NULL;
+       struct via_isa_bridge *via_config;
        u8 t, v;
        unsigned int u;
-       int i;
 
        /*
         * Find the ISA bridge to see how good the IDE is.
         */
-
-       for (via_config = via_isa_bridges; via_config->id; via_config++)
-               if ((isa = pci_find_device(PCI_VENDOR_ID_VIA +
-                       !!(via_config->flags & VIA_BAD_ID),
-                       via_config->id, NULL))) {
-
-                       pci_read_config_byte(isa, PCI_REVISION_ID, &t);
-                       if (t >= via_config->rev_min &&
-                           t <= via_config->rev_max)
-                               break;
-               }
-
+       via_config = via_config_find(&isa);
        if (!via_config->id) {
                printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
                return -ENODEV;
        }
 
        /*
-        * Check 80-wire cable presence and setup Clk66.
+        * Setup or disable Clk66 if appropriate
         */
 
-       switch (via_config->flags & VIA_UDMA) {
-
-               case VIA_UDMA_66:
-                       /* Enable Clk66 */
-                       pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-                       pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
-                       for (i = 24; i >= 0; i -= 8)
-                               if (((u >> (i & 16)) & 8) &&
-                                   ((u >> i) & 0x20) &&
-                                    (((u >> i) & 7) < 2)) {
-                                       /*
-                                        * 2x PCI clock and
-                                        * UDMA w/ < 3T/cycle
-                                        */
-                                       via_80w |= (1 << (1 - (i >> 4)));
-                               }
-                       break;
-
-               case VIA_UDMA_100:
-                       pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-                       for (i = 24; i >= 0; i -= 8)
-                               if (((u >> i) & 0x10) ||
-                                   (((u >> i) & 0x20) &&
-                                    (((u >> i) & 7) < 4))) {
-                                       /* BIOS 80-wire bit or
-                                        * UDMA w/ < 60ns/cycle
-                                        */
-                                       via_80w |= (1 << (1 - (i >> 4)));
-                               }
-                       break;
-
-               case VIA_UDMA_133:
-                       pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
-                       for (i = 24; i >= 0; i -= 8)
-                               if (((u >> i) & 0x10) ||
-                                   (((u >> i) & 0x20) &&
-                                    (((u >> i) & 7) < 6))) {
-                                       /* BIOS 80-wire bit or
-                                        * UDMA w/ < 60ns/cycle
-                                        */
-                                       via_80w |= (1 << (1 - (i >> 4)));
-                               }
-                       break;
-
-       }
-
-       /* Disable Clk66 */
-       if (via_config->flags & VIA_BAD_CLK66) {
+       if ((via_config->flags & VIA_UDMA) == VIA_UDMA_66) {
+               /* Enable Clk66 */
+               pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+               pci_write_config_dword(dev, VIA_UDMA_TIMING, u|0x80008);
+       } else if (via_config->flags & VIA_BAD_CLK66) {
                /* Would cause trouble on 596a and 686 */
                pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
                pci_write_config_dword(dev, VIA_UDMA_TIMING, u & ~0x80008);
@@ -560,26 +360,78 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
                via_dma[via_config->flags & VIA_UDMA],
                pci_name(dev));
 
-       /*
-        * Setup /proc/ide/via entry.
-        */
+       return 0;
+}
+
+/*
+ * Check and handle 80-wire cable presence
+ */
+static void __devinit via_cable_detect(struct pci_dev *dev, struct via82cxxx_dev *vdev)
+{
+       unsigned int u;
+       int i;
+       pci_read_config_dword(dev, VIA_UDMA_TIMING, &u);
+
+       switch (vdev->via_config->flags & VIA_UDMA) {
+
+               case VIA_UDMA_66:
+                       for (i = 24; i >= 0; i -= 8)
+                               if (((u >> (i & 16)) & 8) &&
+                                   ((u >> i) & 0x20) &&
+                                    (((u >> i) & 7) < 2)) {
+                                       /*
+                                        * 2x PCI clock and
+                                        * UDMA w/ < 3T/cycle
+                                        */
+                                       vdev->via_80w |= (1 << (1 - (i >> 4)));
+                               }
+                       break;
+
+               case VIA_UDMA_100:
+                       for (i = 24; i >= 0; i -= 8)
+                               if (((u >> i) & 0x10) ||
+                                   (((u >> i) & 0x20) &&
+                                    (((u >> i) & 7) < 4))) {
+                                       /* BIOS 80-wire bit or
+                                        * UDMA w/ < 60ns/cycle
+                                        */
+                                       vdev->via_80w |= (1 << (1 - (i >> 4)));
+                               }
+                       break;
+
+               case VIA_UDMA_133:
+                       for (i = 24; i >= 0; i -= 8)
+                               if (((u >> i) & 0x10) ||
+                                   (((u >> i) & 0x20) &&
+                                    (((u >> i) & 7) < 6))) {
+                                       /* BIOS 80-wire bit or
+                                        * UDMA w/ < 60ns/cycle
+                                        */
+                                       vdev->via_80w |= (1 << (1 - (i >> 4)));
+                               }
+                       break;
 
-#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
-       if (!via_proc) {
-               via_base = pci_resource_start(dev, 4);
-               bmide_dev = dev;
-               isa_dev = isa;
-               ide_pci_create_host_proc("via", via_get_info);
-               via_proc = 1;
        }
-#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS */
-       return 0;
 }
 
 static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 {
+       struct via82cxxx_dev *vdev = kmalloc(sizeof(struct via82cxxx_dev),
+               GFP_KERNEL);
+       struct pci_dev *isa = NULL;
        int i;
 
+       if (vdev == NULL) {
+               printk(KERN_ERR "VP_IDE: out of memory :(\n");
+               return;
+       }
+
+       memset(vdev, 0, sizeof(struct via82cxxx_dev));
+       ide_set_hwifdata(hwif, vdev);
+
+       vdev->via_config = via_config_find(&isa);
+       via_cable_detect(hwif->pci_dev, vdev);
+
        hwif->autodma = 0;
 
        hwif->tuneproc = &via82cxxx_tune_drive;
@@ -594,7 +446,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
 
        for (i = 0; i < 2; i++) {
                hwif->drives[i].io_32bit = 1;
-               hwif->drives[i].unmask = (via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
+               hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
                hwif->drives[i].autotune = 1;
                hwif->drives[i].dn = hwif->channel * 2 + i;
        }
@@ -608,7 +460,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
        hwif->swdma_mask = 0x07;
 
        if (!hwif->udma_four)
-               hwif->udma_four = (via_80w >> hwif->channel) & 1;
+               hwif->udma_four = (vdev->via_80w >> hwif->channel) & 1;
        hwif->ide_dma_check = &via82cxxx_ide_dma_check;
        if (!noautodma)
                hwif->autodma = 1;
@@ -616,24 +468,35 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
-static ide_pci_device_t via82cxxx_chipset __devinitdata = {
-       .name           = "VP_IDE",
-       .init_chipset   = init_chipset_via82cxxx,
-       .init_hwif      = init_hwif_via82cxxx,
-       .channels       = 2,
-       .autodma        = NOAUTODMA,
-       .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
-       .bootable       = ON_BOARD,
+static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
+       {       /* 0 */
+               .name           = "VP_IDE",
+               .init_chipset   = init_chipset_via82cxxx,
+               .init_hwif      = init_hwif_via82cxxx,
+               .channels       = 2,
+               .autodma        = NOAUTODMA,
+               .enablebits     = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
+               .bootable       = ON_BOARD
+       },{     /* 1 */
+               .name           = "VP_IDE",
+               .init_chipset   = init_chipset_via82cxxx,
+               .init_hwif      = init_hwif_via82cxxx,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .enablebits     = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
+               .bootable       = ON_BOARD,
+       }
 };
 
 static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       return ide_setup_pci_device(dev, &via82cxxx_chipset);
+       return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
 }
 
 static struct pci_device_id via_pci_tbl[] = {
        { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_6410,     PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, via_pci_tbl);
index 136911a86e84f67c3a0509a4b3bda6c8b5794029..16b28357885b38e4a534ea8664dce97e7535615a 100644 (file)
@@ -1401,20 +1401,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        /* We probe the hwif now */
        probe_hwif_init(hwif);
 
-       /* The code IDE code will have set hwif->present if we have devices attached,
-        * if we don't, the discard the interface except if we are on a media bay slot
-        */
-       if (!hwif->present && !pmif->mediabay) {
-               printk(KERN_INFO "ide%d: Bus empty, interface released.\n",
-                       hwif->index);
-               default_hwif_iops(hwif);
-               for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; ++i)
-                       hwif->io_ports[i] = 0;
-               hwif->chipset = ide_unknown;
-               hwif->noprobe = 1;
-               return -ENODEV;
-       }
-
        return 0;
 }
 
index d4f2111d43641e5701a86384242c1e70991f3429..7ebf992e8c2f40f2050060ea2e3f8cd53d188436 100644 (file)
@@ -787,7 +787,7 @@ static int pre_init = 1;            /* Before first ordered IDE scan */
 static LIST_HEAD(ide_pci_drivers);
 
 /*
- *     __ide_register_pci_driver       -       attach IDE driver
+ *     __ide_pci_register_driver       -       attach IDE driver
  *     @driver: pci driver
  *     @module: owner module of the driver
  *
index 5ea741f47fc88c4d3b90b0f725b837a61af8ba51..e73f81c223811954e5656f0ed97749b161758cdd 100644 (file)
@@ -312,7 +312,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
        int ret, length, hdr_len, copy_offset;
        int rmpp_active = 0;
 
-       if (count < sizeof (struct ib_user_mad))
+       if (count < sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)
                return -EINVAL;
 
        length = count - sizeof (struct ib_user_mad);
index 760c418d5bc9b3b77ab52f054035fa2782dfe130..dd4e13303e96e8f470e50c37e6d2a35377f1a373 100644 (file)
@@ -730,14 +730,15 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
        }
 
        if (attr_mask & IB_QP_ACCESS_FLAGS) {
+               qp_context->params2 |=
+                       cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
+                                   MTHCA_QP_BIT_RWE : 0);
+
                /*
-                * Only enable RDMA/atomics if we have responder
-                * resources set to a non-zero value.
+                * Only enable RDMA reads and atomics if we have
+                * responder resources set to a non-zero value.
                 */
                if (qp->resp_depth) {
-                       qp_context->params2 |=
-                               cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ?
-                                           MTHCA_QP_BIT_RWE : 0);
                        qp_context->params2 |=
                                cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ?
                                            MTHCA_QP_BIT_RRE : 0);
@@ -759,22 +760,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
                if (qp->resp_depth && !attr->max_dest_rd_atomic) {
                        /*
                         * Lowering our responder resources to zero.
-                        * Turn off RDMA/atomics as responder.
-                        * (RWE/RRE/RAE in params2 already zero)
+                        * Turn off reads RDMA and atomics as responder.
+                        * (RRE/RAE in params2 already zero)
                         */
-                       qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
-                                                               MTHCA_QP_OPTPAR_RRE |
+                       qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
                                                                MTHCA_QP_OPTPAR_RAE);
                }
 
                if (!qp->resp_depth && attr->max_dest_rd_atomic) {
                        /*
                         * Increasing our responder resources from
-                        * zero.  Turn on RDMA/atomics as appropriate.
+                        * zero.  Turn on RDMA reads and atomics as
+                        * appropriate.
                         */
-                       qp_context->params2 |=
-                               cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_WRITE ?
-                                           MTHCA_QP_BIT_RWE : 0);
                        qp_context->params2 |=
                                cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ?
                                            MTHCA_QP_BIT_RRE : 0);
@@ -782,8 +780,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
                                cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ?
                                            MTHCA_QP_BIT_RAE : 0);
 
-                       qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE |
-                                                               MTHCA_QP_OPTPAR_RRE |
+                       qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE |
                                                                MTHCA_QP_OPTPAR_RAE);
                }
 
@@ -921,10 +918,12 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev,
         else
                qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
 
-       qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
-       qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
-                       sizeof (struct mthca_next_seg)) /
-                       sizeof (struct mthca_data_seg);
+       qp->sq.max_gs = min_t(int, dev->limits.max_sg,
+                             max_data_size / sizeof (struct mthca_data_seg));
+       qp->rq.max_gs = min_t(int, dev->limits.max_sg,
+                              (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
+                               sizeof (struct mthca_next_seg)) /
+                              sizeof (struct mthca_data_seg));
 }
 
 /*
index 321a3a10e69baabad357caba9a208c3d24a4b8b8..ee9fe226ae994408f50b1180632c8c4b9ba7d7db 100644 (file)
@@ -802,13 +802,21 @@ static int srp_post_recv(struct srp_target_port *target)
 
 /*
  * Must be called with target->scsi_host->host_lock held to protect
- * req_lim and tx_head.
+ * req_lim and tx_head.  Lock cannot be dropped between call here and
+ * call to __srp_post_send().
  */
 static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target)
 {
        if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE)
                return NULL;
 
+       if (unlikely(target->req_lim < 1)) {
+               if (printk_ratelimit())
+                       printk(KERN_DEBUG PFX "Target has req_lim %d\n",
+                              target->req_lim);
+               return NULL;
+       }
+
        return target->tx_ring[target->tx_head & SRP_SQ_SIZE];
 }
 
@@ -823,11 +831,6 @@ static int __srp_post_send(struct srp_target_port *target,
        struct ib_send_wr wr, *bad_wr;
        int ret = 0;
 
-       if (target->req_lim < 1) {
-               printk(KERN_ERR PFX "Target has req_lim %d\n", target->req_lim);
-               return -EAGAIN;
-       }
-
        list.addr   = iu->dma;
        list.length = len;
        list.lkey   = target->srp_host->mr->lkey;
@@ -1417,6 +1420,8 @@ static ssize_t srp_create_target(struct class_device *class_dev,
        if (!target_host)
                return -ENOMEM;
 
+       target_host->max_lun = SRP_MAX_LUN;
+
        target = host_to_target(target_host);
        memset(target, 0, sizeof *target);
 
index 4fec28a71367f1631981bf046147bbe265c91643..b564f18caf783049ee1b95bfe6c2c8b3be0bd65f 100644 (file)
@@ -54,6 +54,7 @@ enum {
        SRP_PORT_REDIRECT       = 1,
        SRP_DLID_REDIRECT       = 2,
 
+       SRP_MAX_LUN             = 512,
        SRP_MAX_IU_LEN          = 256,
 
        SRP_RQ_SHIFT            = 6,
index 0506934244f001861f309f40fa33e0eee4e0fc3b..caac6d63d46f4a7da7ffc70293aad635d7c6bb37 100644 (file)
@@ -339,14 +339,20 @@ static struct gameport_event *gameport_get_event(void)
        return event;
 }
 
-static void gameport_handle_events(void)
+static void gameport_handle_event(void)
 {
        struct gameport_event *event;
        struct gameport_driver *gameport_drv;
 
        down(&gameport_sem);
 
-       while ((event = gameport_get_event())) {
+       /*
+        * Note that we handle only one event here to give swsusp
+        * a chance to freeze kgameportd thread. Gameport events
+        * should be pretty rare so we are not concerned about
+        * taking performance hit.
+        */
+       if ((event = gameport_get_event())) {
 
                switch (event->type) {
                        case GAMEPORT_REGISTER_PORT:
@@ -433,7 +439,7 @@ static struct gameport *gameport_get_pending_child(struct gameport *parent)
 static int gameport_thread(void *nothing)
 {
        do {
-               gameport_handle_events();
+               gameport_handle_event();
                wait_event_interruptible(gameport_wait,
                        kthread_should_stop() || !list_empty(&gameport_event_list));
                try_to_freeze();
index c8ae2bb054e026c4e4e2cf44214c26316737f0dc..bdd2a7fc268dac799210be077f223a56b3255a31 100644 (file)
@@ -536,7 +536,7 @@ static struct attribute *input_dev_attrs[] = {
        NULL
 };
 
-static struct attribute_group input_dev_group = {
+static struct attribute_group input_dev_attr_group = {
        .attrs  = input_dev_attrs,
 };
 
@@ -717,35 +717,14 @@ struct input_dev *input_allocate_device(void)
        return dev;
 }
 
-static void input_register_classdevice(struct input_dev *dev)
-{
-       static atomic_t input_no = ATOMIC_INIT(0);
-       const char *path;
-
-       __module_get(THIS_MODULE);
-
-       dev->dev = dev->cdev.dev;
-
-       snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
-                "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
-
-       path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
-       printk(KERN_INFO "input: %s as %s/%s\n",
-               dev->name ? dev->name : "Unspecified device",
-               path ? path : "", dev->cdev.class_id);
-       kfree(path);
-
-       class_device_add(&dev->cdev);
-       sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
-       sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
-       sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
-}
-
 int input_register_device(struct input_dev *dev)
 {
+       static atomic_t input_no = ATOMIC_INIT(0);
        struct input_handle *handle;
        struct input_handler *handler;
        struct input_device_id *id;
+       const char *path;
+       int error;
 
        if (!dev->dynalloc) {
                printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
@@ -773,7 +752,32 @@ int input_register_device(struct input_dev *dev)
        INIT_LIST_HEAD(&dev->h_list);
        list_add_tail(&dev->node, &input_dev_list);
 
-       input_register_classdevice(dev);
+       dev->cdev.class = &input_class;
+       snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+                "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
+
+       error = class_device_add(&dev->cdev);
+       if (error)
+               return error;
+
+       error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group);
+       if (error)
+               goto fail1;
+
+       error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+       if (error)
+               goto fail2;
+
+       error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
+       if (error)
+               goto fail3;
+
+       __module_get(THIS_MODULE);
+
+       path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
+       printk(KERN_INFO "input: %s as %s\n",
+               dev->name ? dev->name : "Unspecified device", path ? path : "N/A");
+       kfree(path);
 
        list_for_each_entry(handler, &input_handler_list, node)
                if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
@@ -784,6 +788,11 @@ int input_register_device(struct input_dev *dev)
        input_wakeup_procfs_readers();
 
        return 0;
+
+ fail3:        sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+ fail2:        sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
+ fail1:        class_device_del(&dev->cdev);
+       return error;
 }
 
 void input_unregister_device(struct input_dev *dev)
@@ -805,7 +814,7 @@ void input_unregister_device(struct input_dev *dev)
 
        sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
        sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
-       sysfs_remove_group(&dev->cdev.kobj, &input_dev_group);
+       sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group);
        class_device_unregister(&dev->cdev);
 
        input_wakeup_procfs_readers();
index 820c7fd9a6049c7f0e732de29b558a18ce503711..a0256f8de8efab412a1ee6ee22321fb5ca941ce7 100644 (file)
@@ -166,6 +166,9 @@ static unsigned char atkbd_unxlate_table[128] = {
 
 #define ATKBD_SPECIAL          248
 
+#define ATKBD_LED_EVENT_BIT    0
+#define ATKBD_REP_EVENT_BIT    1
+
 static struct {
        unsigned char keycode;
        unsigned char set2;
@@ -211,6 +214,10 @@ struct atkbd {
        unsigned char err_xl;
        unsigned int last;
        unsigned long time;
+
+       struct work_struct event_work;
+       struct semaphore event_sem;
+       unsigned long event_mask;
 };
 
 static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf,
@@ -424,58 +431,86 @@ out:
 }
 
 /*
- * Event callback from the input module. Events that change the state of
- * the hardware are processed here.
+ * atkbd_event_work() is used to complete processing of events that
+ * can not be processed by input_event() which is often called from
+ * interrupt context.
  */
 
-static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+static void atkbd_event_work(void *data)
 {
-       struct atkbd *atkbd = dev->private;
        const short period[32] =
                { 33,  37,  42,  46,  50,  54,  58,  63,  67,  75,  83,  92, 100, 109, 116, 125,
                 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 };
        const short delay[4] =
                { 250, 500, 750, 1000 };
+
+       struct atkbd *atkbd = data;
+       struct input_dev *dev = atkbd->dev;
        unsigned char param[2];
        int i, j;
 
+       down(&atkbd->event_sem);
+
+       if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) {
+               param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
+                        | (test_bit(LED_NUML,    dev->led) ? 2 : 0)
+                        | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0);
+               ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);
+
+               if (atkbd->extra) {
+                       param[0] = 0;
+                       param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
+                                | (test_bit(LED_SLEEP,   dev->led) ? 0x02 : 0)
+                                | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
+                                | (test_bit(LED_MISC,    dev->led) ? 0x10 : 0)
+                                | (test_bit(LED_MUTE,    dev->led) ? 0x20 : 0);
+                       ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
+               }
+       }
+
+       if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) {
+               i = j = 0;
+               while (i < 31 && period[i] < dev->rep[REP_PERIOD])
+                       i++;
+               while (j < 3 && delay[j] < dev->rep[REP_DELAY])
+                       j++;
+               dev->rep[REP_PERIOD] = period[i];
+               dev->rep[REP_DELAY] = delay[j];
+               param[0] = i | (j << 5);
+               ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
+       }
+
+       up(&atkbd->event_sem);
+}
+
+/*
+ * Event callback from the input module. Events that change the state of
+ * the hardware are processed here. If action can not be performed in
+ * interrupt context it is offloaded to atkbd_event_work.
+ */
+
+static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+       struct atkbd *atkbd = dev->private;
+
        if (!atkbd->write)
                return -1;
 
        switch (type) {
 
                case EV_LED:
-
-                       param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
-                                | (test_bit(LED_NUML,    dev->led) ? 2 : 0)
-                                | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0);
-                       ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS);
-
-                       if (atkbd->extra) {
-                               param[0] = 0;
-                               param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0)
-                                        | (test_bit(LED_SLEEP,   dev->led) ? 0x02 : 0)
-                                        | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0)
-                                        | (test_bit(LED_MISC,    dev->led) ? 0x10 : 0)
-                                        | (test_bit(LED_MUTE,    dev->led) ? 0x20 : 0);
-                               ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS);
-                       }
-
+                       set_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask);
+                       wmb();
+                       schedule_work(&atkbd->event_work);
                        return 0;
 
                case EV_REP:
 
-                       if (atkbd->softrepeat) return 0;
-
-                       i = j = 0;
-                       while (i < 31 && period[i] < dev->rep[REP_PERIOD])
-                               i++;
-                       while (j < 3 && delay[j] < dev->rep[REP_DELAY])
-                               j++;
-                       dev->rep[REP_PERIOD] = period[i];
-                       dev->rep[REP_DELAY] = delay[j];
-                       param[0] = i | (j << 5);
-                       ps2_schedule_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
+                       if (!atkbd->softrepeat) {
+                               set_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask);
+                               wmb();
+                               schedule_work(&atkbd->event_work);
+                       }
 
                        return 0;
        }
@@ -810,6 +845,8 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 
        atkbd->dev = dev;
        ps2_init(&atkbd->ps2dev, serio);
+       INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
+       init_MUTEX(&atkbd->event_sem);
 
        switch (serio->id.type) {
 
index b3eaac1b35b64109b27c475a8b4b818ce35be780..07813fc0523f8504a8102fb432fe1999fa42a20f 100644 (file)
@@ -40,6 +40,16 @@ config INPUT_M68K_BEEP
        tristate "M68k Beeper support"
        depends on M68K
 
+config INPUT_WISTRON_BTNS
+       tristate "x86 Wistron laptop button interface"
+       depends on X86 && !X86_64
+       help
+         Say Y here for support of Winstron laptop button interface, used on
+         laptops of various brands, including Acer and Fujitsu-Siemens.
+
+         To compile this driver as a module, choose M here: the module will
+         be called wistron_btns.
+
 config INPUT_UINPUT
        tristate "User level driver support"
        help
index f8d01c69f349567247108e755f4b1725fb3dd96e..ce44cce012855a22142eec77fcc83e38eb88b39e 100644 (file)
@@ -9,4 +9,5 @@ obj-$(CONFIG_INPUT_PCSPKR)              += pcspkr.o
 obj-$(CONFIG_INPUT_M68K_BEEP)          += m68kspkr.o
 obj-$(CONFIG_INPUT_98SPKR)             += 98spkr.o
 obj-$(CONFIG_INPUT_UINPUT)             += uinput.o
+obj-$(CONFIG_INPUT_WISTRON_BTNS)       += wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)               += hp_sdc_rtc.o
index 948c1cc01bc95ea5291a843b107f86f2e7cf70bd..546ed9b4901df211ae125e5395fc5e0675fc7458 100644 (file)
@@ -92,24 +92,19 @@ static void uinput_request_done(struct uinput_device *udev, struct uinput_reques
 {
        /* Mark slot as available */
        udev->requests[request->id] = NULL;
-       wake_up_interruptible(&udev->requests_waitq);
+       wake_up(&udev->requests_waitq);
 
        complete(&request->done);
 }
 
 static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request)
 {
-       int retval;
-
        /* Tell our userspace app about this new request by queueing an input event */
        uinput_dev_event(dev, EV_UINPUT, request->code, request->id);
 
        /* Wait for the request to complete */
-       retval = wait_for_completion_interruptible(&request->done);
-       if (!retval)
-               retval = request->retval;
-
-       return retval;
+       wait_for_completion(&request->done);
+       return request->retval;
 }
 
 static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
@@ -152,67 +147,62 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
        return retval;
 }
 
-static int uinput_create_device(struct uinput_device *udev)
+static void uinput_destroy_device(struct uinput_device *udev)
 {
-       if (!udev->dev->name) {
-               printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
-               return -EINVAL;
+       const char *name, *phys;
+
+       if (udev->dev) {
+               name = udev->dev->name;
+               phys = udev->dev->phys;
+               if (udev->state == UIST_CREATED)
+                       input_unregister_device(udev->dev);
+               else
+                       input_free_device(udev->dev);
+               kfree(name);
+               kfree(phys);
+               udev->dev = NULL;
        }
 
-       udev->dev->event = uinput_dev_event;
-       udev->dev->upload_effect = uinput_dev_upload_effect;
-       udev->dev->erase_effect = uinput_dev_erase_effect;
-       udev->dev->private = udev;
-
-       init_waitqueue_head(&udev->waitq);
-
-       input_register_device(udev->dev);
-
-       set_bit(UIST_CREATED, &udev->state);
-
-       return 0;
+       udev->state = UIST_NEW_DEVICE;
 }
 
-static int uinput_destroy_device(struct uinput_device *udev)
+static int uinput_create_device(struct uinput_device *udev)
 {
-       if (!test_bit(UIST_CREATED, &udev->state)) {
-               printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
+       int error;
+
+       if (udev->state != UIST_SETUP_COMPLETE) {
+               printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
                return -EINVAL;
        }
 
-       input_unregister_device(udev->dev);
+       error = input_register_device(udev->dev);
+       if (error) {
+               uinput_destroy_device(udev);
+               return error;
+       }
 
-       clear_bit(UIST_CREATED, &udev->state);
+       udev->state = UIST_CREATED;
 
        return 0;
 }
 
 static int uinput_open(struct inode *inode, struct file *file)
 {
-       struct uinput_device    *newdev;
-       struct input_dev        *newinput;
+       struct uinput_device *newdev;
 
-       newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
+       newdev = kzalloc(sizeof(struct uinput_device), GFP_KERNEL);
        if (!newdev)
-               goto error;
-       memset(newdev, 0, sizeof(struct uinput_device));
+               return -ENOMEM;
+
+       init_MUTEX(&newdev->sem);
        spin_lock_init(&newdev->requests_lock);
        init_waitqueue_head(&newdev->requests_waitq);
-
-       newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-       if (!newinput)
-               goto cleanup;
-       memset(newinput, 0, sizeof(struct input_dev));
-
-       newdev->dev = newinput;
+       init_waitqueue_head(&newdev->waitq);
+       newdev->state = UIST_NEW_DEVICE;
 
        file->private_data = newdev;
 
        return 0;
-cleanup:
-       kfree(newdev);
-error:
-       return -ENOMEM;
 }
 
 static int uinput_validate_absbits(struct input_dev *dev)
@@ -246,34 +236,55 @@ static int uinput_validate_absbits(struct input_dev *dev)
        return retval;
 }
 
-static int uinput_alloc_device(struct file *file, const char __user *buffer, size_t count)
+static int uinput_allocate_device(struct uinput_device *udev)
+{
+       udev->dev = input_allocate_device();
+       if (!udev->dev)
+               return -ENOMEM;
+
+       udev->dev->event = uinput_dev_event;
+       udev->dev->upload_effect = uinput_dev_upload_effect;
+       udev->dev->erase_effect = uinput_dev_erase_effect;
+       udev->dev->private = udev;
+
+       return 0;
+}
+
+static int uinput_setup_device(struct uinput_device *udev, const char __user *buffer, size_t count)
 {
        struct uinput_user_dev  *user_dev;
        struct input_dev        *dev;
-       struct uinput_device    *udev;
        char                    *name;
        int                     size;
        int                     retval;
 
-       retval = count;
+       if (count != sizeof(struct uinput_user_dev))
+               return -EINVAL;
+
+       if (!udev->dev) {
+               retval = uinput_allocate_device(udev);
+               if (retval)
+                       return retval;
+       }
 
-       udev = file->private_data;
        dev = udev->dev;
 
        user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL);
-       if (!user_dev) {
-               retval = -ENOMEM;
-               goto exit;
-       }
+       if (!user_dev)
+               return -ENOMEM;
 
        if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
                retval = -EFAULT;
                goto exit;
        }
 
-       kfree(dev->name);
-
        size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
+       if (!size) {
+               retval = -EINVAL;
+               goto exit;
+       }
+
+       kfree(dev->name);
        dev->name = name = kmalloc(size, GFP_KERNEL);
        if (!name) {
                retval = -ENOMEM;
@@ -296,32 +307,50 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz
        /* check if absmin/absmax/absfuzz/absflat are filled as
         * told in Documentation/input/input-programming.txt */
        if (test_bit(EV_ABS, dev->evbit)) {
-               int err = uinput_validate_absbits(dev);
-               if (err < 0) {
-                       retval = err;
-                       kfree(dev->name);
-               }
+               retval = uinput_validate_absbits(dev);
+               if (retval < 0)
+                       goto exit;
        }
 
-exit:
+       udev->state = UIST_SETUP_COMPLETE;
+       retval = count;
+
+ exit:
        kfree(user_dev);
        return retval;
 }
 
+static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char __user *buffer, size_t count)
+{
+       struct input_event ev;
+
+       if (count != sizeof(struct input_event))
+               return -EINVAL;
+
+       if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
+               return -EFAULT;
+
+       input_event(udev->dev, ev.type, ev.code, ev.value);
+
+       return sizeof(struct input_event);
+}
+
 static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
        struct uinput_device *udev = file->private_data;
+       int retval;
+
+       retval = down_interruptible(&udev->sem);
+       if (retval)
+               return retval;
 
-       if (test_bit(UIST_CREATED, &udev->state)) {
-               struct input_event      ev;
+       retval = udev->state == UIST_CREATED ?
+                       uinput_inject_event(udev, buffer, count) :
+                       uinput_setup_device(udev, buffer, count);
 
-               if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
-                       return -EFAULT;
-               input_event(udev->dev, ev.type, ev.code, ev.value);
-       } else
-               count = uinput_alloc_device(file, buffer, count);
+       up(&udev->sem);
 
-       return count;
+       return retval;
 }
 
 static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
@@ -329,28 +358,38 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count,
        struct uinput_device *udev = file->private_data;
        int retval = 0;
 
-       if (!test_bit(UIST_CREATED, &udev->state))
+       if (udev->state != UIST_CREATED)
                return -ENODEV;
 
        if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
                return -EAGAIN;
 
        retval = wait_event_interruptible(udev->waitq,
-                       udev->head != udev->tail || !test_bit(UIST_CREATED, &udev->state));
+                       udev->head != udev->tail || udev->state != UIST_CREATED);
        if (retval)
                return retval;
 
-       if (!test_bit(UIST_CREATED, &udev->state))
-               return -ENODEV;
+       retval = down_interruptible(&udev->sem);
+       if (retval)
+               return retval;
 
-       while ((udev->head != udev->tail) &&
-           (retval + sizeof(struct input_event) <= count)) {
-               if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event)))
-                       return -EFAULT;
+       if (udev->state != UIST_CREATED) {
+               retval = -ENODEV;
+               goto out;
+       }
+
+       while (udev->head != udev->tail && retval + sizeof(struct input_event) <= count) {
+               if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) {
+                       retval = -EFAULT;
+                       goto out;
+               }
                udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
                retval += sizeof(struct input_event);
        }
 
+ out:
+       up(&udev->sem);
+
        return retval;
 }
 
@@ -366,28 +405,30 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait)
        return 0;
 }
 
-static int uinput_burn_device(struct uinput_device *udev)
+static int uinput_release(struct inode *inode, struct file *file)
 {
-       if (test_bit(UIST_CREATED, &udev->state))
-               uinput_destroy_device(udev);
+       struct uinput_device *udev = file->private_data;
 
-       kfree(udev->dev->name);
-       kfree(udev->dev->phys);
-       kfree(udev->dev);
+       uinput_destroy_device(udev);
        kfree(udev);
 
        return 0;
 }
 
-static int uinput_close(struct inode *inode, struct file *file)
+#define uinput_set_bit(_arg, _bit, _max)               \
+({                                                     \
+       int __ret = 0;                                  \
+       if (udev->state == UIST_CREATED)                \
+               __ret =  -EINVAL;                       \
+       else if ((_arg) > (_max))                       \
+               __ret = -EINVAL;                        \
+       else set_bit((_arg), udev->dev->_bit);          \
+       __ret;                                          \
+})
+
+static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-       uinput_burn_device(file->private_data);
-       return 0;
-}
-
-static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       int                     retval = 0;
+       int                     retval;
        struct uinput_device    *udev;
        void __user             *p = (void __user *)arg;
        struct uinput_ff_upload ff_up;
@@ -398,19 +439,14 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 
        udev = file->private_data;
 
-       /* device attributes can not be changed after the device is created */
-       switch (cmd) {
-               case UI_SET_EVBIT:
-               case UI_SET_KEYBIT:
-               case UI_SET_RELBIT:
-               case UI_SET_ABSBIT:
-               case UI_SET_MSCBIT:
-               case UI_SET_LEDBIT:
-               case UI_SET_SNDBIT:
-               case UI_SET_FFBIT:
-               case UI_SET_PHYS:
-                       if (test_bit(UIST_CREATED, &udev->state))
-                               return -EINVAL;
+       retval = down_interruptible(&udev->sem);
+       if (retval)
+               return retval;
+
+       if (!udev->dev) {
+               retval = uinput_allocate_device(udev);
+               if (retval)
+                       goto out;
        }
 
        switch (cmd) {
@@ -419,74 +455,50 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                        break;
 
                case UI_DEV_DESTROY:
-                       retval = uinput_destroy_device(udev);
+                       uinput_destroy_device(udev);
                        break;
 
                case UI_SET_EVBIT:
-                       if (arg > EV_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->evbit);
+                       retval = uinput_set_bit(arg, evbit, EV_MAX);
                        break;
 
                case UI_SET_KEYBIT:
-                       if (arg > KEY_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->keybit);
+                       retval = uinput_set_bit(arg, keybit, KEY_MAX);
                        break;
 
                case UI_SET_RELBIT:
-                       if (arg > REL_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->relbit);
+                       retval = uinput_set_bit(arg, relbit, REL_MAX);
                        break;
 
                case UI_SET_ABSBIT:
-                       if (arg > ABS_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->absbit);
+                       retval = uinput_set_bit(arg, absbit, ABS_MAX);
                        break;
 
                case UI_SET_MSCBIT:
-                       if (arg > MSC_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->mscbit);
+                       retval = uinput_set_bit(arg, mscbit, MSC_MAX);
                        break;
 
                case UI_SET_LEDBIT:
-                       if (arg > LED_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->ledbit);
+                       retval = uinput_set_bit(arg, ledbit, LED_MAX);
                        break;
 
                case UI_SET_SNDBIT:
-                       if (arg > SND_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->sndbit);
+                       retval = uinput_set_bit(arg, sndbit, SND_MAX);
                        break;
 
                case UI_SET_FFBIT:
-                       if (arg > FF_MAX) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       set_bit(arg, udev->dev->ffbit);
+                       retval = uinput_set_bit(arg, ffbit, FF_MAX);
+                       break;
+
+               case UI_SET_SWBIT:
+                       retval = uinput_set_bit(arg, swbit, SW_MAX);
                        break;
 
                case UI_SET_PHYS:
+                       if (udev->state == UIST_CREATED) {
+                               retval = -EINVAL;
+                               goto out;
+                       }
                        length = strnlen_user(p, 1024);
                        if (length <= 0) {
                                retval = -EFAULT;
@@ -575,23 +587,26 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd
                default:
                        retval = -EINVAL;
        }
+
+ out:
+       up(&udev->sem);
        return retval;
 }
 
 static struct file_operations uinput_fops = {
-       .owner =        THIS_MODULE,
-       .open =         uinput_open,
-       .release =      uinput_close,
-       .read =         uinput_read,
-       .write =        uinput_write,
-       .poll =         uinput_poll,
-       .ioctl =        uinput_ioctl,
+       .owner          = THIS_MODULE,
+       .open           = uinput_open,
+       .release        = uinput_release,
+       .read           = uinput_read,
+       .write          = uinput_write,
+       .poll           = uinput_poll,
+       .unlocked_ioctl = uinput_ioctl,
 };
 
 static struct miscdevice uinput_misc = {
-       .fops =         &uinput_fops,
-       .minor =        UINPUT_MINOR,
-       .name =         UINPUT_NAME,
+       .fops           = &uinput_fops,
+       .minor          = UINPUT_MINOR,
+       .name           = UINPUT_NAME,
 };
 
 static int __init uinput_init(void)
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
new file mode 100644 (file)
index 0000000..49d0416
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ * Wistron laptop button driver
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * You can redistribute and/or modify this program under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <asm/io.h>
+#include <linux/dmi.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/module.h>
+#include <linux/preempt.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+
+/*
+ * Number of attempts to read data from queue per poll;
+ * the queue can hold up to 31 entries
+ */
+#define MAX_POLL_ITERATIONS 64
+
+#define POLL_FREQUENCY 10 /* Number of polls per second */
+
+#if POLL_FREQUENCY > HZ
+#error "POLL_FREQUENCY too high"
+#endif
+
+/* BIOS subsystem IDs */
+#define WIFI           0x35
+#define BLUETOOTH      0x34
+
+MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
+MODULE_DESCRIPTION("Wistron laptop button driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.1");
+
+static int force; /* = 0; */
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Load even if computer is not in database");
+
+static char *keymap_name; /* = NULL; */
+module_param_named(keymap, keymap_name, charp, 0);
+MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected");
+
+static struct platform_device *wistron_device;
+
+ /* BIOS interface implementation */
+
+static void __iomem *bios_entry_point; /* BIOS routine entry point */
+static void __iomem *bios_code_map_base;
+static void __iomem *bios_data_map_base;
+
+static u8 cmos_address;
+
+struct regs {
+       u32 eax, ebx, ecx;
+};
+
+static void call_bios(struct regs *regs)
+{
+       unsigned long flags;
+
+       preempt_disable();
+       local_irq_save(flags);
+       asm volatile ("pushl %%ebp;"
+                     "movl %7, %%ebp;"
+                     "call *%6;"
+                     "popl %%ebp"
+                     : "=a" (regs->eax), "=b" (regs->ebx), "=c" (regs->ecx)
+                     : "0" (regs->eax), "1" (regs->ebx), "2" (regs->ecx),
+                       "m" (bios_entry_point), "m" (bios_data_map_base)
+                     : "edx", "edi", "esi", "memory");
+       local_irq_restore(flags);
+       preempt_enable();
+}
+
+static size_t __init locate_wistron_bios(void __iomem *base)
+{
+       static const unsigned char __initdata signature[] =
+               { 0x42, 0x21, 0x55, 0x30 };
+       size_t offset;
+
+       for (offset = 0; offset < 0x10000; offset += 0x10) {
+               if (check_signature(base + offset, signature,
+                                   sizeof(signature)) != 0)
+                       return offset;
+       }
+       return -1;
+}
+
+static int __init map_bios(void)
+{
+       void __iomem *base;
+       size_t offset;
+       u32 entry_point;
+
+       base = ioremap(0xF0000, 0x10000); /* Can't fail */
+       offset = locate_wistron_bios(base);
+       if (offset < 0) {
+               printk(KERN_ERR "wistron_btns: BIOS entry point not found\n");
+               iounmap(base);
+               return -ENODEV;
+       }
+
+       entry_point = readl(base + offset + 5);
+       printk(KERN_DEBUG
+               "wistron_btns: BIOS signature found at %p, entry point %08X\n",
+               base + offset, entry_point);
+
+       if (entry_point >= 0xF0000) {
+               bios_code_map_base = base;
+               bios_entry_point = bios_code_map_base + (entry_point & 0xFFFF);
+       } else {
+               iounmap(base);
+               bios_code_map_base = ioremap(entry_point & ~0x3FFF, 0x4000);
+               if (bios_code_map_base == NULL) {
+                       printk(KERN_ERR
+                               "wistron_btns: Can't map BIOS code at %08X\n",
+                               entry_point & ~0x3FFF);
+                       goto err;
+               }
+               bios_entry_point = bios_code_map_base + (entry_point & 0x3FFF);
+       }
+       /* The Windows driver maps 0x10000 bytes, we keep only one page... */
+       bios_data_map_base = ioremap(0x400, 0xc00);
+       if (bios_data_map_base == NULL) {
+               printk(KERN_ERR "wistron_btns: Can't map BIOS data\n");
+               goto err_code;
+       }
+       return 0;
+
+err_code:
+       iounmap(bios_code_map_base);
+err:
+       return -ENOMEM;
+}
+
+static inline void unmap_bios(void)
+{
+       iounmap(bios_code_map_base);
+       iounmap(bios_data_map_base);
+}
+
+ /* BIOS calls */
+
+static u16 bios_pop_queue(void)
+{
+       struct regs regs;
+
+       memset(&regs, 0, sizeof (regs));
+       regs.eax = 0x9610;
+       regs.ebx = 0x061C;
+       regs.ecx = 0x0000;
+       call_bios(&regs);
+
+       return regs.eax;
+}
+
+static void __init bios_attach(void)
+{
+       struct regs regs;
+
+       memset(&regs, 0, sizeof (regs));
+       regs.eax = 0x9610;
+       regs.ebx = 0x012E;
+       call_bios(&regs);
+}
+
+static void bios_detach(void)
+{
+       struct regs regs;
+
+       memset(&regs, 0, sizeof (regs));
+       regs.eax = 0x9610;
+       regs.ebx = 0x002E;
+       call_bios(&regs);
+}
+
+static u8 __init bios_get_cmos_address(void)
+{
+       struct regs regs;
+
+       memset(&regs, 0, sizeof (regs));
+       regs.eax = 0x9610;
+       regs.ebx = 0x051C;
+       call_bios(&regs);
+
+       return regs.ecx;
+}
+
+static u16 __init bios_get_default_setting(u8 subsys)
+{
+       struct regs regs;
+
+       memset(&regs, 0, sizeof (regs));
+       regs.eax = 0x9610;
+       regs.ebx = 0x0200 | subsys;
+       call_bios(&regs);
+
+       return regs.eax;
+}
+
+static void bios_set_state(u8 subsys, int enable)
+{
+       struct regs regs;
+
+       memset(&regs, 0, sizeof (regs));
+       regs.eax = 0x9610;
+       regs.ebx = (enable ? 0x0100 : 0x0000) | subsys;
+       call_bios(&regs);
+}
+
+/* Hardware database */
+
+struct key_entry {
+       char type;              /* See KE_* below */
+       u8 code;
+       unsigned keycode;       /* For KE_KEY */
+};
+
+enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH };
+
+static const struct key_entry *keymap; /* = NULL; Current key map */
+static int have_wifi;
+static int have_bluetooth;
+
+static int __init dmi_matched(struct dmi_system_id *dmi)
+{
+       const struct key_entry *key;
+
+       keymap = dmi->driver_data;
+       for (key = keymap; key->type != KE_END; key++) {
+               if (key->type == KE_WIFI) {
+                       have_wifi = 1;
+                       break;
+               } else if (key->type == KE_BLUETOOTH) {
+                       have_bluetooth = 1;
+                       break;
+               }
+       }
+       return 1;
+}
+
+static struct key_entry keymap_empty[] = {
+       { KE_END, 0 }
+};
+
+static struct key_entry keymap_fs_amilo_pro_v2000[] = {
+       { KE_KEY,  0x01, KEY_HELP },
+       { KE_KEY,  0x11, KEY_PROG1 },
+       { KE_KEY,  0x12, KEY_PROG2 },
+       { KE_WIFI, 0x30, 0 },
+       { KE_KEY,  0x31, KEY_MAIL },
+       { KE_KEY,  0x36, KEY_WWW },
+       { KE_END,  0 }
+};
+
+static struct key_entry keymap_wistron_ms2141[] = {
+       { KE_KEY,  0x11, KEY_PROG1 },
+       { KE_KEY,  0x12, KEY_PROG2 },
+       { KE_WIFI, 0x30, 0 },
+       { KE_KEY,  0x22, KEY_REWIND },
+       { KE_KEY,  0x23, KEY_FORWARD },
+       { KE_KEY,  0x24, KEY_PLAYPAUSE },
+       { KE_KEY,  0x25, KEY_STOPCD },
+       { KE_KEY,  0x31, KEY_MAIL },
+       { KE_KEY,  0x36, KEY_WWW },
+       { KE_END,  0 }
+};
+
+static struct key_entry keymap_acer_aspire_1500[] = {
+       { KE_KEY, 0x11, KEY_PROG1 },
+       { KE_KEY, 0x12, KEY_PROG2 },
+       { KE_WIFI, 0x30, 0 },
+       { KE_KEY, 0x31, KEY_MAIL },
+       { KE_KEY, 0x36, KEY_WWW },
+       { KE_BLUETOOTH, 0x44, 0 },
+       { KE_END, 0 }
+};
+
+/*
+ * 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
+ * with force=1) and the output of dmidecode to $MODULE_AUTHOR.
+ */
+static struct dmi_system_id dmi_ids[] = {
+       {
+               .callback = dmi_matched,
+               .ident = "Fujitsu-Siemens Amilo Pro V2000",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2000"),
+               },
+               .driver_data = keymap_fs_amilo_pro_v2000
+       },
+       {
+               .callback = dmi_matched,
+               .ident = "Acer Aspire 1500",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
+               },
+               .driver_data = keymap_acer_aspire_1500
+       },
+       { 0, }
+};
+
+static int __init select_keymap(void)
+{
+       if (keymap_name != NULL) {
+               if (strcmp (keymap_name, "1557/MS2141") == 0)
+                       keymap = keymap_wistron_ms2141;
+               else {
+                       printk(KERN_ERR "wistron_btns: Keymap unknown\n");
+                       return -EINVAL;
+               }
+       }
+       dmi_check_system(dmi_ids);
+       if (keymap == NULL) {
+               if (!force) {
+                       printk(KERN_ERR "wistron_btns: System unknown\n");
+                       return -ENODEV;
+               }
+               keymap = keymap_empty;
+       }
+       return 0;
+}
+
+ /* Input layer interface */
+
+static struct input_dev *input_dev;
+
+static int __init setup_input_dev(void)
+{
+       const struct key_entry *key;
+       int error;
+
+       input_dev = input_allocate_device();
+       if (!input_dev)
+               return -ENOMEM;
+
+       input_dev->name = "Wistron laptop buttons";
+       input_dev->phys = "wistron/input0";
+       input_dev->id.bustype = BUS_HOST;
+       input_dev->cdev.dev = &wistron_device->dev;
+
+       for (key = keymap; key->type != KE_END; key++) {
+               if (key->type == KE_KEY) {
+                       input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
+                       set_bit(key->keycode, input_dev->keybit);
+               }
+       }
+
+       error = input_register_device(input_dev);
+       if (error) {
+               input_free_device(input_dev);
+               return error;
+       }
+
+       return 0;
+}
+
+static void report_key(unsigned keycode)
+{
+       input_report_key(input_dev, keycode, 1);
+       input_sync(input_dev);
+       input_report_key(input_dev, keycode, 0);
+       input_sync(input_dev);
+}
+
+ /* Driver core */
+
+static int wifi_enabled;
+static int bluetooth_enabled;
+
+static void poll_bios(unsigned long);
+
+static struct timer_list poll_timer = TIMER_INITIALIZER(poll_bios, 0, 0);
+
+static void handle_key(u8 code)
+{
+       const struct key_entry *key;
+
+       for (key = keymap; key->type != KE_END; key++) {
+               if (code == key->code) {
+                       switch (key->type) {
+                       case KE_KEY:
+                               report_key(key->keycode);
+                               break;
+
+                       case KE_WIFI:
+                               if (have_wifi) {
+                                       wifi_enabled = !wifi_enabled;
+                                       bios_set_state(WIFI, wifi_enabled);
+                               }
+                               break;
+
+                       case KE_BLUETOOTH:
+                               if (have_bluetooth) {
+                                       bluetooth_enabled = !bluetooth_enabled;
+                                       bios_set_state(BLUETOOTH, bluetooth_enabled);
+                               }
+                               break;
+
+                       case KE_END:
+                       default:
+                               BUG();
+                       }
+                       return;
+               }
+       }
+       printk(KERN_NOTICE "wistron_btns: Unknown key code %02X\n", code);
+}
+
+static void poll_bios(unsigned long discard)
+{
+       u8 qlen;
+       u16 val;
+
+       for (;;) {
+               qlen = CMOS_READ(cmos_address);
+               if (qlen == 0)
+                       break;
+               val = bios_pop_queue();
+               if (val != 0 && !discard)
+                       handle_key((u8)val);
+       }
+
+       mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
+}
+
+static int wistron_suspend(struct platform_device *dev, pm_message_t state)
+{
+       del_timer_sync(&poll_timer);
+
+       if (have_wifi)
+               bios_set_state(WIFI, 0);
+
+       if (have_bluetooth)
+               bios_set_state(BLUETOOTH, 0);
+
+       return 0;
+}
+
+static int wistron_resume(struct platform_device *dev)
+{
+       if (have_wifi)
+               bios_set_state(WIFI, wifi_enabled);
+
+       if (have_bluetooth)
+               bios_set_state(BLUETOOTH, bluetooth_enabled);
+
+       poll_bios(1);
+
+       return 0;
+}
+
+static struct platform_driver wistron_driver = {
+       .suspend        = wistron_suspend,
+       .resume         = wistron_resume,
+       .driver         = {
+               .name   = "wistron-bios",
+       },
+};
+
+static int __init wb_module_init(void)
+{
+       int err;
+
+       err = select_keymap();
+       if (err)
+               return err;
+
+       err = map_bios();
+       if (err)
+               return err;
+
+       bios_attach();
+       cmos_address = bios_get_cmos_address();
+
+       err = platform_driver_register(&wistron_driver);
+       if (err)
+               goto err_detach_bios;
+
+       wistron_device = platform_device_register_simple("wistron-bios", -1, NULL, 0);
+       if (IS_ERR(wistron_device)) {
+               err = PTR_ERR(wistron_device);
+               goto err_unregister_driver;
+       }
+
+       if (have_wifi) {
+               u16 wifi = bios_get_default_setting(WIFI);
+               if (wifi & 1)
+                       wifi_enabled = (wifi & 2) ? 1 : 0;
+               else
+                       have_wifi = 0;
+
+               if (have_wifi)
+                       bios_set_state(WIFI, wifi_enabled);
+       }
+
+       if (have_bluetooth) {
+               u16 bt = bios_get_default_setting(BLUETOOTH);
+               if (bt & 1)
+                       bluetooth_enabled = (bt & 2) ? 1 : 0;
+               else
+                       have_bluetooth = 0;
+
+               if (have_bluetooth)
+                       bios_set_state(BLUETOOTH, bluetooth_enabled);
+       }
+
+       err = setup_input_dev();
+       if (err)
+               goto err_unregister_device;
+
+       poll_bios(1); /* Flush stale event queue and arm timer */
+
+       return 0;
+
+ err_unregister_device:
+       platform_device_unregister(wistron_device);
+ err_unregister_driver:
+       platform_driver_unregister(&wistron_driver);
+ err_detach_bios:
+       bios_detach();
+       unmap_bios();
+
+       return err;
+}
+
+static void __exit wb_module_exit(void)
+{
+       del_timer_sync(&poll_timer);
+       input_unregister_device(input_dev);
+       platform_device_unregister(wistron_device);
+       platform_driver_unregister(&wistron_driver);
+       bios_detach();
+       unmap_bios();
+}
+
+module_init(wb_module_init);
+module_exit(wb_module_exit);
index edd15db17715852ff05e1119ddd02b5de248e469..fbb69ef6a77b0a6a8659ec5b19b107bb32812040 100644 (file)
@@ -269,14 +269,20 @@ static struct serio_event *serio_get_event(void)
        return event;
 }
 
-static void serio_handle_events(void)
+static void serio_handle_event(void)
 {
        struct serio_event *event;
        struct serio_driver *serio_drv;
 
        down(&serio_sem);
 
-       while ((event = serio_get_event())) {
+       /*
+        * Note that we handle only one event here to give swsusp
+        * a chance to freeze kseriod thread. Serio events should
+        * be pretty rare so we are not concerned about taking
+        * performance hit.
+        */
+       if ((event = serio_get_event())) {
 
                switch (event->type) {
                        case SERIO_REGISTER_PORT:
@@ -368,7 +374,7 @@ static struct serio *serio_get_pending_child(struct serio *parent)
 static int serio_thread(void *nothing)
 {
        do {
-               serio_handle_events();
+               serio_handle_event();
                wait_event_interruptible(serio_wait,
                        kthread_should_stop() || !list_empty(&serio_event_list));
                try_to_freeze();
index 801c98f30e5c7c767e1a39822033d68b81540626..c82105920d7187e6c46a3487fa90b6de94b82c94 100644 (file)
@@ -110,7 +110,7 @@ config HISAX_16_3
 
 config HISAX_TELESPCI
        bool "Teles PCI"
-       depends on PCI && (BROKEN || !(SPARC64 || PPC))
+       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
        help
          This enables HiSax support for the Teles PCI.
          See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -238,7 +238,7 @@ config HISAX_MIC
 
 config HISAX_NETJET
        bool "NETjet card"
-       depends on PCI && (BROKEN || !(SPARC64 || PPC))
+       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
        help
          This enables HiSax support for the NetJet from Traverse
          Technologies.
@@ -249,7 +249,7 @@ config HISAX_NETJET
 
 config HISAX_NETJET_U
        bool "NETspider U card"
-       depends on PCI && (BROKEN || !(SPARC64 || PPC))
+       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
        help
          This enables HiSax support for the Netspider U interface ISDN card
          from Traverse Technologies.
@@ -317,7 +317,7 @@ config HISAX_GAZEL
 
 config HISAX_HFC_PCI
        bool "HFC PCI-Bus cards"
-       depends on PCI && (BROKEN || !(SPARC64 || PPC))
+       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
        help
          This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
@@ -344,14 +344,14 @@ config HISAX_HFC_SX
 
 config HISAX_ENTERNOW_PCI
        bool "Formula-n enter:now PCI card"
-       depends on PCI && (BROKEN || !(SPARC64 || PPC))
+       depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
        help
          This enables HiSax support for the Formula-n enter:now PCI
          ISDN card.
 
 config HISAX_AMD7930
        bool "Am7930 (EXPERIMENTAL)"
-       depends on EXPERIMENTAL && (SPARC32 || SPARC64)
+       depends on EXPERIMENTAL && SPARC
        help
          This enables HiSax support for the AMD7930 chips on some SPARCs.
          This code is not finished yet.
index f06997faef16b06385b365bc5b1bf45ba56c1c4d..0933881ab0c263f903985a7973cd6b17a3974e2a 100644 (file)
@@ -3,7 +3,7 @@
 #
 config ISDN_DRV_PCBIT
        tristate "PCBIT-D support"
-       depends on ISDN_I4L && ISA && (BROKEN || !PPC)
+       depends on ISDN_I4L && ISA && (BROKEN || X86)
        help
          This enables support for the PCBIT ISDN-card.  This card is
          manufactured in Portugal by Octal.  For running this card,
index fb394a0d838c8df550b523eee0e17e7ad908cda2..336fc284fa523138d2bfd923146039ce8855db6a 100644 (file)
@@ -772,7 +772,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
        input_dev->name = DRIVER_NAME " remote control";
        input_dev->phys = cinergyt2->phys;
        input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-       for (i = 0; ARRAY_SIZE(rc_keys); i += 3)
+       for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3)
                set_bit(rc_keys[i + 2], input_dev->keybit);
        input_dev->keycodesize = 0;
        input_dev->keycodemax = 0;
index 5abfc0fbf6de984b6473b990afd5a6ac9280fb66..6345e29e4951c2bb717a9ced1d19b3fdd89c7e52 100644 (file)
@@ -673,7 +673,6 @@ static int ir_probe(struct device *dev)
        snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
                 pci_name(sub->core->pci));
 
-       ir->sub = sub;
        ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
        input_dev->name = ir->name;
        input_dev->phys = ir->phys;
@@ -688,6 +687,9 @@ static int ir_probe(struct device *dev)
        }
        input_dev->cdev.dev = &sub->core->pci->dev;
 
+       ir->input = input_dev;
+       ir->sub = sub;
+
        if (ir->polling) {
                INIT_WORK(&ir->work, ir_work, ir);
                init_timer(&ir->timer);
@@ -708,7 +710,6 @@ static int ir_probe(struct device *dev)
        /* all done */
        dev_set_drvdata(dev, ir);
        input_register_device(ir->input);
-       printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
 
        /* the remote isn't as bouncy as a keyboard */
        ir->input->rep[REP_DELAY] = repeat_delay;
index e648cc3bc96d33220527a7bd409034370ae72e4c..ab75ca5ac356b16862b0957f9a85d56dd5f650b4 100644 (file)
@@ -713,6 +713,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                return -ENOMEM;
        }
 
+       ir->dev = input_dev;
+
        /* init hardware-specific stuff */
        ir->mask_keycode = mask_keycode;
        ir->mask_keydown = mask_keydown;
index 35097c9bbf50c5bb560fe5fce3b039a3a4c4eba3..b8ccb0a9578984221c5ad3caad30ee3caa9d03d3 100644 (file)
@@ -246,7 +246,7 @@ int __init ipaq_mtd_init(void)
                        ipaq_map[i].size = h3xxx_max_flash_size;
                        ipaq_map[i].set_vpp = h3xxx_set_vpp;
                        ipaq_map[i].phys = cs_phys[i];
-                       ipaq_map[i].virt = __ioremap(cs_phys[i], 0x04000000, 0, 1);
+                       ipaq_map[i].virt = ioremap(cs_phys[i], 0x04000000);
                        if (machine_is_h3100 () || machine_is_h1900())
                                ipaq_map[i].bankwidth = 2;
                }
@@ -280,7 +280,7 @@ int __init ipaq_mtd_init(void)
                nb_parts = ARRAY_SIZE(jornada_partitions);
                ipaq_map[0].size = jornada_max_flash_size;
                ipaq_map[0].set_vpp = jornada56x_set_vpp;
-               ipaq_map[0].virt = (__u32)__ioremap(0x0, 0x04000000, 0, 1);
+               ipaq_map[0].virt = (__u32)ioremap(0x0, 0x04000000);
        }
 #endif
 #ifdef CONFIG_SA1100_JORNADA720
@@ -442,7 +442,7 @@ static int __init h1900_special_case(void)
        ipaq_map[0].size = 0x80000;
        ipaq_map[0].set_vpp = h3xxx_set_vpp;
        ipaq_map[0].phys = 0x0;
-       ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
+       ipaq_map[0].virt = ioremap(0x0, 0x04000000);
        ipaq_map[0].bankwidth = 2;
 
        printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
index fc7a78e31735bc4ea35f56f9a34480e79aa23101..2c9cc7f37e9216fcf5cae2d8e526514114e178b1 100644 (file)
@@ -159,12 +159,12 @@ static int ixp2000_flash_probe(struct platform_device *dev)
                return -ENODEV;
 
        window_size = dev->resource->end - dev->resource->start + 1;
-       dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
-                       ixp_data->nr_banks, ((u32)window_size >> 20));
+       dev_info(&dev->dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
+                ixp_data->nr_banks, ((u32)window_size >> 20));
 
        if (plat->width != 1) {
-               dev_err(_dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
-                               plat->width * 8);
+               dev_err(&dev->dev, "IXP2000 MTD map only supports 8-bit mode, asking for %d\n",
+                       plat->width * 8);
                return -EIO;
        }
 
@@ -202,7 +202,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
                        dev->resource->end - dev->resource->start + 1,
                        dev->dev.bus_id);
        if (!info->res) {
-               dev_err(_dev, "Could not reserve memory region\n");
+               dev_err(&dev->dev, "Could not reserve memory region\n");
                err = -ENOMEM;
                goto Error;
        }
@@ -210,7 +210,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
        info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
                                dev->resource->end - dev->resource->start + 1);
        if (!info->map.map_priv_1) {
-               dev_err(_dev, "Failed to ioremap flash region\n");
+               dev_err(&dev->dev, "Failed to ioremap flash region\n");
                err = -EIO;
                goto Error;
        }
@@ -221,13 +221,13 @@ static int ixp2000_flash_probe(struct platform_device *dev)
         */
 
        erratum44_workaround = ixp2000_has_broken_slowport();
-       dev_info(_dev, "Erratum 44 workaround %s\n",
+       dev_info(&dev->dev, "Erratum 44 workaround %s\n",
               erratum44_workaround ? "enabled" : "disabled");
 #endif
 
        info->mtd = do_map_probe(plat->map_name, &info->map);
        if (!info->mtd) {
-               dev_err(_dev, "map_probe failed\n");
+               dev_err(&dev->dev, "map_probe failed\n");
                err = -ENXIO;
                goto Error;
        }
@@ -237,7 +237,7 @@ static int ixp2000_flash_probe(struct platform_device *dev)
        if (err > 0) {
                err = add_mtd_partitions(info->mtd, info->partitions, err);
                if(err)
-                       dev_err(_dev, "Could not parse partitions\n");
+                       dev_err(&dev->dev, "Could not parse partitions\n");
        }
 
        if (err)
@@ -251,8 +251,8 @@ Error:
 }
 
 static struct platform_driver ixp2000_flash_driver = {
-       .probe          = &ixp2000_flash_probe,
-       .remove         = &ixp2000_flash_remove
+       .probe          = ixp2000_flash_probe,
+       .remove         = ixp2000_flash_remove,
        .driver         = {
                .name   = "IXP2000-Flash",
        },
index 041e4b3358fbce2d953ef14d77e4c5e9e609e048..f68f7a99a6309bafb051d76b634654f52c0bbe7e 100644 (file)
@@ -112,7 +112,7 @@ static int __init h1910_init (void)
        if (!machine_is_h1900())
                return -ENODEV;
 
-       nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
+       nandaddr = ioremap(0x08000000, 0x1000);
        if (!nandaddr) {
                printk("Failed to ioremap nand flash.\n");
                return -ENOMEM;
index 332e9953c55cdd4d80a50ba1fcfcaa0be6d52b45..cd0b1dccfb6102119334a357762b1c93502fec72 100644 (file)
@@ -32,6 +32,7 @@
  * 
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
index 7a6aeae2c9fa9698f6ccd8bc9914e4b1e6b3e850..22cd045567075d33f26356cac785866212362506 100644 (file)
 
 #define DRV_NAME               "e100"
 #define DRV_EXT                "-NAPI"
-#define DRV_VERSION            "3.4.14-k2"DRV_EXT
+#define DRV_VERSION            "3.4.14-k4"DRV_EXT
 #define DRV_DESCRIPTION                "Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT          "Copyright(c) 1999-2005 Intel Corporation"
 #define PFX                    DRV_NAME ": "
@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
 
 static void e100_get_defaults(struct nic *nic)
 {
-       struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
-       struct param_range cbs  = { .min = 64, .max = 256, .count = 64 };
+       struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
+       struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
 
        pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
        /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@@ -1007,25 +1007,264 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
                c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
 }
 
+/********************************************************/
+/*  Micro code for 8086:1229 Rev 8                      */
+/********************************************************/
+
+/*  Parameter values for the D101M B-step  */
+#define D101M_CPUSAVER_TIMER_DWORD             78
+#define D101M_CPUSAVER_BUNDLE_DWORD            65
+#define D101M_CPUSAVER_MIN_SIZE_DWORD          126
+
+#define D101M_B_RCVBUNDLE_UCODE \
+{\
+0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
+0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
+0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
+0x00380438, 0x00000000, 0x00140000, 0x00380555, \
+0x00308000, 0x00100662, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
+0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
+0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
+0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
+0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
+0x00041000, 0x00010004, 0x00130826, 0x000C0006, \
+0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380C34, 0x00000000, 0x00000000, \
+0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
+0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
+0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
+0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
+0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
+0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
+0x00130826, 0x000C0001, 0x00220559, 0x00101313, \
+0x00380559, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00130831, 0x0010090B, 0x00124813, \
+0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
+0x003806A8, 0x00000000, 0x00000000, 0x00000000, \
+}
+
+/********************************************************/
+/*  Micro code for 8086:1229 Rev 9                      */
+/********************************************************/
+
+/*  Parameter values for the D101S  */
+#define D101S_CPUSAVER_TIMER_DWORD             78
+#define D101S_CPUSAVER_BUNDLE_DWORD            67
+#define D101S_CPUSAVER_MIN_SIZE_DWORD          128
+
+#define D101S_RCVBUNDLE_UCODE \
+{\
+0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
+0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
+0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
+0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
+0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
+0x00308000, 0x00100610, 0x00100561, 0x000E0408, \
+0x00134861, 0x000C0002, 0x00103093, 0x00308000, \
+0x00100624, 0x00100561, 0x000E0408, 0x00100861, \
+0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
+0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
+0x003A047E, 0x00044010, 0x00380819, 0x00000000, \
+0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
+0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
+0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
+0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
+0x00101313, 0x00380700, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00080600, 0x00101B10, 0x00050004, 0x00100826, \
+0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
+0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
+0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
+0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
+0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
+0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
+0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
+0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
+0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00130831, \
+0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
+0x00041000, 0x00010004, 0x00380700  \
+}
+
+/********************************************************/
+/*  Micro code for the 8086:1229 Rev F/10               */
+/********************************************************/
+
+/*  Parameter values for the D102 E-step  */
+#define D102_E_CPUSAVER_TIMER_DWORD            42
+#define D102_E_CPUSAVER_BUNDLE_DWORD           54
+#define D102_E_CPUSAVER_MIN_SIZE_DWORD         46
+
+#define     D102_E_RCVBUNDLE_UCODE \
+{\
+0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
+0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
+0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
+0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
+0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
+0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
+0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+0x00000000, 0x00000000, 0x00000000, 0x00000000, \
+}
+
 static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 {
-       int i;
-       static const u32 ucode[UCODE_SIZE] = {
-               /* NFS packets are misinterpreted as TCO packets and
-                * incorrectly routed to the BMC over SMBus.  This
-                * microcode patch checks the fragmented IP bit in the
-                * NFS/UDP header to distinguish between NFS and TCO. */
-               0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
-               0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
-               0x00906EFD, 0x00900EFD, 0x00E00EF8,
-       };
-
-       if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
-               for(i = 0; i < UCODE_SIZE; i++)
+/* *INDENT-OFF* */
+       static struct {
+               u32 ucode[UCODE_SIZE + 1];
+               u8 mac;
+               u8 timer_dword;
+               u8 bundle_dword;
+               u8 min_size_dword;
+       } ucode_opts[] = {
+               { D101M_B_RCVBUNDLE_UCODE,
+                 mac_82559_D101M,
+                 D101M_CPUSAVER_TIMER_DWORD,
+                 D101M_CPUSAVER_BUNDLE_DWORD,
+                 D101M_CPUSAVER_MIN_SIZE_DWORD },
+               { D101S_RCVBUNDLE_UCODE,
+                 mac_82559_D101S,
+                 D101S_CPUSAVER_TIMER_DWORD,
+                 D101S_CPUSAVER_BUNDLE_DWORD,
+                 D101S_CPUSAVER_MIN_SIZE_DWORD },
+               { D102_E_RCVBUNDLE_UCODE,
+                 mac_82551_F,
+                 D102_E_CPUSAVER_TIMER_DWORD,
+                 D102_E_CPUSAVER_BUNDLE_DWORD,
+                 D102_E_CPUSAVER_MIN_SIZE_DWORD },
+               { D102_E_RCVBUNDLE_UCODE,
+                 mac_82551_10,
+                 D102_E_CPUSAVER_TIMER_DWORD,
+                 D102_E_CPUSAVER_BUNDLE_DWORD,
+                 D102_E_CPUSAVER_MIN_SIZE_DWORD },
+               { {0}, 0, 0, 0, 0}
+       }, *opts;
+/* *INDENT-ON* */
+
+/*************************************************************************
+*  CPUSaver parameters
+*
+*  All CPUSaver parameters are 16-bit literals that are part of a
+*  "move immediate value" instruction.  By changing the value of
+*  the literal in the instruction before the code is loaded, the
+*  driver can change the algorithm.
+*
+*  INTDELAY - This loads the dead-man timer with its inital value.
+*    When this timer expires the interrupt is asserted, and the 
+*    timer is reset each time a new packet is received.  (see
+*    BUNDLEMAX below to set the limit on number of chained packets)
+*    The current default is 0x600 or 1536.  Experiments show that
+*    the value should probably stay within the 0x200 - 0x1000.
+*
+*  BUNDLEMAX - 
+*    This sets the maximum number of frames that will be bundled.  In
+*    some situations, such as the TCP windowing algorithm, it may be
+*    better to limit the growth of the bundle size than let it go as
+*    high as it can, because that could cause too much added latency.
+*    The default is six, because this is the number of packets in the
+*    default TCP window size.  A value of 1 would make CPUSaver indicate
+*    an interrupt for every frame received.  If you do not want to put
+*    a limit on the bundle size, set this value to xFFFF.
+*
+*  BUNDLESMALL - 
+*    This contains a bit-mask describing the minimum size frame that
+*    will be bundled.  The default masks the lower 7 bits, which means
+*    that any frame less than 128 bytes in length will not be bundled,
+*    but will instead immediately generate an interrupt.  This does
+*    not affect the current bundle in any way.  Any frame that is 128
+*    bytes or large will be bundled normally.  This feature is meant
+*    to provide immediate indication of ACK frames in a TCP environment.
+*    Customers were seeing poor performance when a machine with CPUSaver
+*    enabled was sending but not receiving.  The delay introduced when
+*    the ACKs were received was enough to reduce total throughput, because
+*    the sender would sit idle until the ACK was finally seen.
+*
+*    The current default is 0xFF80, which masks out the lower 7 bits.
+*    This means that any frame which is x7F (127) bytes or smaller
+*    will cause an immediate interrupt.  Because this value must be a 
+*    bit mask, there are only a few valid values that can be used.  To
+*    turn this feature off, the driver can write the value xFFFF to the
+*    lower word of this instruction (in the same way that the other
+*    parameters are used).  Likewise, a value of 0xF800 (2047) would
+*    cause an interrupt to be generated for every frame, because all
+*    standard Ethernet frames are <= 2047 bytes in length.
+*************************************************************************/
+
+/* if you wish to disable the ucode functionality, while maintaining the 
+ * workarounds it provides, set the following defines to:
+ * BUNDLESMALL 0
+ * BUNDLEMAX 1
+ * INTDELAY 1
+ */
+#define BUNDLESMALL 1
+#define BUNDLEMAX (u16)6
+#define INTDELAY (u16)1536 /* 0x600 */
+
+       /* do not load u-code for ICH devices */
+       if (nic->flags & ich)
+               goto noloaducode;
+
+       /* Search for ucode match against h/w rev_id */
+       for (opts = ucode_opts; opts->mac; opts++) {
+               int i;
+               u32 *ucode = opts->ucode;
+               if (nic->mac != opts->mac)
+                       continue;
+
+               /* Insert user-tunable settings */
+               ucode[opts->timer_dword] &= 0xFFFF0000;
+               ucode[opts->timer_dword] |= INTDELAY;
+               ucode[opts->bundle_dword] &= 0xFFFF0000;
+               ucode[opts->bundle_dword] |= BUNDLEMAX;
+               ucode[opts->min_size_dword] &= 0xFFFF0000;
+               ucode[opts->min_size_dword] |= (BUNDLESMALL) ? 0xFFFF : 0xFF80;
+
+               for (i = 0; i < UCODE_SIZE; i++)
                        cb->u.ucode[i] = cpu_to_le32(ucode[i]);
                cb->command = cpu_to_le16(cb_ucode);
-       } else
-               cb->command = cpu_to_le16(cb_nop);
+               return;
+       }
+
+noloaducode:
+       cb->command = cpu_to_le16(cb_nop);
 }
 
 static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
index 94e7a9af87055f0642abccb1309a43a2ec95d8cc..a84c232395e3fdf72dc63c070341ad756d2aaa39 100644 (file)
@@ -1,6 +1,6 @@
 config FEC_8XX
        tristate "Motorola 8xx FEC driver"
-       depends on NET_ETHERNET && FEC
+       depends on NET_ETHERNET && 8xx
        select MII
 
 config FEC_8XX_GENERIC_PHY
index 6a3129bc15a6d6327c5dec32f8e518049e6c5787..9b8295ee06ef1fb069f283a950f12a67b0ae113b 100644 (file)
@@ -1360,7 +1360,7 @@ static struct pci_driver ioc3_driver = {
 
 static int __init ioc3_init_module(void)
 {
-       return pci_module_init(&ioc3_driver);
+       return pci_register_driver(&ioc3_driver);
 }
 
 static void __exit ioc3_cleanup_module(void)
index 159b56a56ef49112fc5e58083c76a3066eb76958..14a76f7cf900fa86493ba745bf9fe1bbabb23c6c 100644 (file)
@@ -1346,10 +1346,8 @@ rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
        } else {
                if (netif_msg_probe(tp)) {
                        printk(KERN_ERR PFX
-                              "Cannot find PowerManagement capability. "
-                              "Aborting.\n");
+                              "PowerManagement capability not found.\n");
                }
-               goto err_out_mwi;
        }
 
        /* make sure PCI base addr 1 is MMIO */
@@ -2516,7 +2514,7 @@ rtl8169_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
        } while (boguscnt > 0);
 
        if (boguscnt <= 0) {
-               if (net_ratelimit() && netif_msg_intr(tp)) {
+               if (netif_msg_intr(tp) && net_ratelimit() ) {
                        printk(KERN_WARNING
                               "%s: Too much work at interrupt!\n", dev->name);
                }
index 9e9da6b4080fa2ab27b5961d4af9ae1e9761e0da..a7e9d29a86a725ae67fdde869b1b9df2c6511e8e 100644 (file)
@@ -1,6 +1,7 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2000, 2005  MIPS Technologies, Inc.  All rights reserved.
+ *     Authors: Carsten Langgaard <carstenl@mips.com>
+ *              Maciej W. Rozycki <macro@mips.com>
  *
  * ########################################################################
  *
 
 /* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
 #define SAA9730_LAN_REGS_ADDR   0x20400
+#define SAA9730_LAN_REGS_SIZE   0x00400
 
 struct lan_saa9730_regmap {
        volatile unsigned int TxBuffA;                  /* 0x20400 */
@@ -309,6 +311,7 @@ typedef volatile struct lan_saa9730_regmap t_lan_saa9730_regmap;
 
 /* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
 #define SAA9730_EVM_REGS_ADDR   0x02000
+#define SAA9730_EVM_REGS_SIZE   0x00400
 
 struct evm_saa9730_regmap {
        volatile unsigned int InterruptStatus1;         /* 0x2000 */
@@ -329,16 +332,32 @@ typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
 
 
 struct lan_saa9730_private {
+       /*
+        * Rx/Tx packet buffers.
+        * The Rx and Tx packets must be PACKET_SIZE aligned.
+        */
+       void            *buffer_start;
+       unsigned int    buffer_size;
+
+       /*
+        * DMA address of beginning of this object, returned
+        * by pci_alloc_consistent().
+        */
+       dma_addr_t      dma_addr;
+
+       /* Pointer to the associated pci device structure */
+       struct pci_dev  *pci_dev;
+
        /* Pointer for the SAA9730 LAN controller register set. */
        t_lan_saa9730_regmap *lan_saa9730_regs;
 
        /* Pointer to the SAA9730 EVM register. */
        t_evm_saa9730_regmap *evm_saa9730_regs;
 
-       /* TRUE if the next buffer to write is RxBuffA,  FALSE if RxBuffB. */
-       unsigned char NextRcvToUseIsA;
        /* Rcv buffer Index. */
        unsigned char NextRcvPacketIndex;
+       /* Next buffer index. */
+       unsigned char NextRcvBufferIndex;
 
        /* Index of next packet to use in that buffer. */
        unsigned char NextTxmPacketIndex;
@@ -353,13 +372,8 @@ struct lan_saa9730_private {
        unsigned char DmaRcvPackets;
        unsigned char DmaTxmPackets;
 
-       unsigned char RcvAIndex;        /* index into RcvBufferSpace[] for Blk A */
-       unsigned char RcvBIndex;        /* index into RcvBufferSpace[] for Blk B */
-
-       unsigned int
-           TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
-       unsigned int
-           RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
+       void          *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
+       void          *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
        unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
 
        unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
index c91e2e81f131aa368ca81b9eb20bb5722aa8c765..28bf2e69eb5e1a1c9f181d2810447f8dd30ac10a 100644 (file)
@@ -154,6 +154,12 @@ MODULE_LICENSE("GPL");
  */
 #define MEMORY_WAIT_TIME       16
 
+/*
+ * The maximum number of processing loops allowed for each call to the
+ * IRQ handler.  
+ */
+#define MAX_IRQ_LOOPS          8
+
 /*
  * This selects whether TX packets are sent one by one to the SMC91x internal
  * memory and throttled until transmission completes.  This may prevent
@@ -684,7 +690,6 @@ static void smc_hardware_send_pkt(unsigned long data)
 
        /* queue the packet for TX */
        SMC_SET_MMU_CMD(MC_ENQUEUE);
-       SMC_ACK_INT(IM_TX_EMPTY_INT);
        smc_special_unlock(&lp->lock);
 
        dev->trans_start = jiffies;
@@ -1207,6 +1212,7 @@ static void smc_phy_configure(void *data)
        smc_phy_check_media(dev, 1);
 
 smc_phy_configure_exit:
+       SMC_SELECT_BANK(2);
        spin_unlock_irq(&lp->lock);
        lp->work_pending = 0;
 }
@@ -1305,7 +1311,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        SMC_SET_INT_MASK(0);
 
        /* set a timeout value, so I don't stay here forever */
-       timeout = 8;
+       timeout = MAX_IRQ_LOOPS;
 
        do {
                status = SMC_GET_INT();
@@ -1372,10 +1378,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        /* restore register states */
        SMC_SET_PTR(saved_pointer);
        SMC_SET_INT_MASK(mask);
-
        spin_unlock(&lp->lock);
 
-       DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
+       if (timeout == MAX_IRQ_LOOPS)
+               PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
+                      dev->name, mask);
+       DBG(3, "%s: Interrupt done (%d loops)\n",
+              dev->name, MAX_IRQ_LOOPS - timeout);
 
        /*
         * We return IRQ_HANDLED unconditionally here even if there was
index a01efa6d5c629bd81457a64769f015f75ebea4c7..1fd04662c4fce290534991bee6c8476dc8a7efcd 100644 (file)
@@ -192,7 +192,9 @@ static int cisco_rx(struct sk_buff *skb)
                                               "uptime %ud%uh%um%us)\n",
                                               dev->name, days, hrs,
                                               min, sec);
+#if 0
                                        netif_carrier_on(dev);
+#endif
                                        hdlc->state.cisco.up = 1;
                                }
                        }
@@ -225,7 +227,9 @@ static void cisco_timer(unsigned long arg)
                       hdlc->state.cisco.settings.timeout * HZ)) {
                hdlc->state.cisco.up = 0;
                printk(KERN_INFO "%s: Link down\n", dev->name);
+#if 0
                netif_carrier_off(dev);
+#endif
        }
 
        cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
@@ -261,8 +265,10 @@ static void cisco_stop(struct net_device *dev)
 {
        hdlc_device *hdlc = dev_to_hdlc(dev);
        del_timer_sync(&hdlc->state.cisco.timer);
+#if 0
        if (netif_carrier_ok(dev))
                netif_carrier_off(dev);
+#endif
        hdlc->state.cisco.up = 0;
        hdlc->state.cisco.request_sent = 0;
 }
index e1601d35dceddf133379a57155ca9472294b2eac..523afe17564e20f1c728b98a9d148ec9d309aced 100644 (file)
@@ -545,8 +545,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
 
        hdlc->state.fr.reliable = reliable;
        if (reliable) {
+#if 0
                if (!netif_carrier_ok(dev))
                        netif_carrier_on(dev);
+#endif
 
                hdlc->state.fr.n391cnt = 0; /* Request full status */
                hdlc->state.fr.dce_changed = 1;
@@ -560,8 +562,10 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
                        }
                }
        } else {
+#if 0
                if (netif_carrier_ok(dev))
                        netif_carrier_off(dev);
+#endif
 
                while (pvc) {           /* Deactivate all PVCs */
                        pvc_carrier(0, pvc);
index cdd4c09c2d90355adee28e09d42f560ab42d040f..46cef8f921333ac245f31a4beb13584def82fb25 100644 (file)
@@ -79,11 +79,13 @@ static void __hdlc_set_carrier_on(struct net_device *dev)
        hdlc_device *hdlc = dev_to_hdlc(dev);
        if (hdlc->proto.start)
                return hdlc->proto.start(dev);
+#if 0
 #ifdef DEBUG_LINK
        if (netif_carrier_ok(dev))
                printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
 #endif
        netif_carrier_on(dev);
+#endif
 }
 
 
@@ -94,11 +96,13 @@ static void __hdlc_set_carrier_off(struct net_device *dev)
        if (hdlc->proto.stop)
                return hdlc->proto.stop(dev);
 
+#if 0
 #ifdef DEBUG_LINK
        if (!netif_carrier_ok(dev))
                printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
 #endif
        netif_carrier_off(dev);
+#endif
 }
 
 
@@ -294,8 +298,10 @@ int register_hdlc_device(struct net_device *dev)
        if (result != 0)
                return -EIO;
 
+#if 0
        if (netif_carrier_ok(dev))
                netif_carrier_off(dev); /* no carrier until DCD goes up */
+#endif
 
        return 0;
 }
index 579480dad3746cba6f956792c0c09ae445dd50ae..346c6febb033b89e217591819727e21ae62ecc43 100644 (file)
@@ -398,7 +398,7 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
  *
  * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
  */
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
                     u16 id, u16 offset)
 {
        int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -424,7 +424,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
  *
  * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
  */
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
                      u16 id, u16 offset)
 {
        int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -450,7 +450,7 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
  *
  * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
  */
-int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len,
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, int len,
                      u16 id, u16 offset)
 {
        int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
index a6bd472d75d4c83924131a6b4d19a9cfb8540fe8..7644f72a9f4efd3269c40cd46b09cefbda196e85 100644 (file)
@@ -372,12 +372,12 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
                      struct hermes_response *resp);
 int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
 
-int hermes_bap_pread(hermes_t *hw, int bap, void *buf, unsigned len,
+int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
                       u16 id, u16 offset);
-int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
+int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
                        u16 id, u16 offset);
 int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
-                       unsigned data_len, unsigned len, u16 id, u16 offset);
+                       unsigned data_len, int len, u16 id, u16 offset);
 int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
                    u16 *length, void *buf);
 int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
index 33acb8add4d6242a0d39ff8fdfeb1aa7fd84ca2d..afac5c7a323d35c77f2f6aa9d31d24184b1500df 100644 (file)
@@ -7,11 +7,16 @@
  *
  * Copyright 1994, Anders Klemets <klemets@it.kth.se>
  *
- * This software may be freely distributed for noncommercial purposes
- * as long as this notice is retained.
- * 
  * HISTORY
  * i82593.h,v
+ * Revision 1.4  2005/11/4  09:15:00  baroniunas
+ * Modified copyright with permission of author as follows:
+ *
+ *   "If I82539.H is the only file with my copyright statement
+ *    that is included in the Source Forge project, then you have
+ *    my approval to change the copyright statement to be a GPL
+ *    license, in the way you proposed on October 10."
+ *
  * Revision 1.1  1996/07/17 15:23:12  root
  * Initial revision
  *
index a2e6214169e914ba6e79b4d8bfe631a730449633..77d2a21d4cd00f879abe206480f80ea75441aca7 100644 (file)
@@ -6344,7 +6344,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        dev->ethtool_ops = &ipw2100_ethtool_ops;
        dev->tx_timeout = ipw2100_tx_timeout;
        dev->wireless_handlers = &ipw2100_wx_handler_def;
-       dev->get_wireless_stats = ipw2100_wx_wireless_stats;
+       priv->wireless_data.ieee80211 = priv->ieee;
+       dev->wireless_data = &priv->wireless_data;
        dev->set_mac_address = ipw2100_set_address;
        dev->watchdog_timeo = 3 * HZ;
        dev->irq = 0;
@@ -7178,6 +7179,11 @@ static int ipw2100_wx_get_range(struct net_device *dev,
        }
        range->num_frequency = val;
 
+       /* Event capability (kernel + driver) */
+       range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+                               IW_EVENT_CAPA_MASK(SIOCGIWAP));
+       range->event_capa[1] = IW_EVENT_CAPA_K_1;
+
        IPW_DEBUG_WX("GET Range\n");
 
        return 0;
@@ -8446,16 +8452,6 @@ static iw_handler ipw2100_private_handler[] = {
 #endif                         /* CONFIG_IPW2100_MONITOR */
 };
 
-static struct iw_handler_def ipw2100_wx_handler_def = {
-       .standard = ipw2100_wx_handlers,
-       .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
-       .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
-       .num_private_args = sizeof(ipw2100_private_args) /
-           sizeof(struct iw_priv_args),
-       .private = (iw_handler *) ipw2100_private_handler,
-       .private_args = (struct iw_priv_args *)ipw2100_private_args,
-};
-
 /*
  * Get wireless statistics.
  * Called by /proc/net/wireless
@@ -8597,6 +8593,17 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
        return (struct iw_statistics *)NULL;
 }
 
+static struct iw_handler_def ipw2100_wx_handler_def = {
+       .standard = ipw2100_wx_handlers,
+       .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
+       .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
+       .num_private_args = sizeof(ipw2100_private_args) /
+           sizeof(struct iw_priv_args),
+       .private = (iw_handler *) ipw2100_private_handler,
+       .private_args = (struct iw_priv_args *)ipw2100_private_args,
+       .get_wireless_stats = ipw2100_wx_wireless_stats,
+};
+
 static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
 {
        union iwreq_data wrqu;
index 140fdf2a0a09a58afdcbe36658a07476c16474c4..7c65b10bb164d00b0d2a0fb393b4ec1e97cdd85b 100644 (file)
@@ -571,6 +571,8 @@ struct ipw2100_priv {
        struct net_device *net_dev;
        struct iw_statistics wstats;
 
+       struct iw_public_data wireless_data;
+
        struct tasklet_struct irq_tasklet;
 
        struct workqueue_struct *workqueue;
index 109a96d90007ba53ad39a15cec8be73ed56945f4..23deee69974b3eeed03af5a59a7286208f276ad4 100644 (file)
@@ -164,12 +164,12 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
                /* assert the Wakeup interrupt in the Device Interrupt Register */
                isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_WAKEUP,
                                  ISL38XX_DEV_INT_REG);
+
+#if VERBOSE > SHOW_ERROR_MESSAGES
                udelay(ISL38XX_WRITEIO_DELAY);
 
                /* perform another read on the Device Status Register */
                reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
                do_gettimeofday(&current_time);
                DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
                      current_time.tv_sec, (long)current_time.tv_usec, reg);
index a39fbfef789a9ad6783d4da67f47eef6b4eb2d68..19657efa8dc3989741d1df2ddd38ea8ff2b5db86 100644 (file)
@@ -700,6 +700,28 @@ static unsigned int iosapic_startup_irq(unsigned int irq)
        return 0;
 }
 
+#ifdef CONFIG_SMP
+static void iosapic_set_affinity_irq(unsigned int irq, cpumask_t dest)
+{
+       struct vector_info *vi = iosapic_get_vector(irq);
+       u32 d0, d1, dummy_d0;
+       unsigned long flags;
+
+       if (cpu_check_affinity(irq, &dest))
+               return;
+
+       vi->txn_addr = txn_affinity_addr(irq, first_cpu(dest));
+
+       spin_lock_irqsave(&iosapic_lock, flags);
+       /* d1 contains the destination CPU, so only want to set that
+        * entry */
+       iosapic_rd_irt_entry(vi, &d0, &d1);
+       iosapic_set_irt_data(vi, &dummy_d0, &d1);
+       iosapic_wr_irt_entry(vi, d0, d1);
+       spin_unlock_irqrestore(&iosapic_lock, flags);
+}
+#endif
+
 static struct hw_interrupt_type iosapic_interrupt_type = {
        .typename =     "IO-SAPIC-level",
        .startup =      iosapic_startup_irq,
@@ -708,7 +730,9 @@ static struct hw_interrupt_type iosapic_interrupt_type = {
        .disable =      iosapic_disable_irq,
        .ack =          no_ack_irq,
        .end =          iosapic_end_irq,
-//     .set_affinity = iosapic_set_affinity_irq,
+#ifdef CONFIG_SMP
+       .set_affinity = iosapic_set_affinity_irq,
+#endif
 };
 
 int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
index bab3bcabcb6ee6bf83a223a34bfc0ec9b4361121..d14888e149bbeeb6f3c7bf517739e0be6e37b096 100644 (file)
@@ -24,6 +24,9 @@
  *      Major changes to get basic interrupt infrastructure working to
  *      hopefully be able to support all SuperIO devices. Currently
  *      works with serial. -- John Marvin <jsm@fc.hp.com>
+ *
+ *     Converted superio_init() to be a PCI_FIXUP_FINAL callee.
+ *         -- Kyle McMartin <kyle@parisc-linux.org>
  */
 
 
@@ -141,10 +144,10 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs)
 }
 
 /* Initialize Super I/O device */
-
-static void __devinit
-superio_init(struct superio_device *sio)
+static void
+superio_init(struct pci_dev *pcidev)
 {
+       struct superio_device *sio = &sio_dev;
        struct pci_dev *pdev = sio->lio_pdev;
        u16 word;
 
@@ -160,8 +163,8 @@ superio_init(struct superio_device *sio)
        /* ...then properly fixup the USB to point at suckyio PIC */
        sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev);
 
-       printk (KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
-               pci_name(pdev),pdev->irq);
+       printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n",
+              pci_name(pdev), pdev->irq);
 
        pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base);
        sio->sp1_base &= ~1;
@@ -274,7 +277,7 @@ superio_init(struct superio_device *sio)
 
        sio->suckyio_irq_enabled = 1;
 }
-
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO, superio_init);
 
 static void superio_disable_irq(unsigned int irq)
 {
@@ -452,8 +455,10 @@ static void superio_fixup_pci(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415, superio_fixup_pci);
 
 
-static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit
+superio_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
+       struct superio_device *sio = &sio_dev;
 
        /*
        ** superio_probe(00:0e.0) ven 0x100b dev 0x2 sv 0x0 sd 0x0 class 0x1018a
@@ -466,7 +471,8 @@ static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_
                dev->subsystem_vendor, dev->subsystem_device,
                dev->class);
 
-       superio_init(&sio_dev);
+       if (!sio->suckyio_irq_enabled)
+               BUG(); /* Enabled by PCI_FIXUP_FINAL */
 
        if (dev->device == PCI_DEVICE_ID_NS_87560_LIO) {        /* Function 1 */
                superio_parport_init();
@@ -481,19 +487,21 @@ static int __devinit superio_probe(struct pci_dev *dev, const struct pci_device_
                DBG_INIT("superio_probe: WTF? Fire Extinguisher?\n");
        }
 
-       /* Let appropriate other driver claim this device. */ 
+       /* Let appropriate other driver claim this device. */
        return -ENODEV;
 }
 
 static struct pci_device_id superio_tbl[] = {
-       { PCI_VENDOR_ID_NS, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_LIO) },
+       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87560_USB) },
+       { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415) },
        { 0, }
 };
 
 static struct pci_driver superio_driver = {
-       .name =         "SuperIO",
-       .id_table =     superio_tbl,
-       .probe =        superio_probe,
+       .name =         "SuperIO",
+       .id_table =     superio_tbl,
+       .probe =        superio_probe,
 };
 
 static int __init superio_modinit(void)
@@ -506,6 +514,5 @@ static void __exit superio_exit(void)
        pci_unregister_driver(&superio_driver);
 }
 
-
 module_init(superio_modinit);
 module_exit(superio_exit);
index e1960d69fb90dd756eb69b09c532a012259819c3..4cb1f3ed910036becf5f63c8ea6bccd0639646dc 100644 (file)
@@ -784,8 +784,8 @@ static ide_proc_entry_t idescsi_proc[] = {
 #endif
 
 static ide_driver_t idescsi_driver = {
-       .owner                  = THIS_MODULE,
        .gen_driver = {
+               .owner          = THIS_MODULE,
                .name           = "ide-scsi",
                .bus            = &ide_bus_type,
                .probe          = ide_scsi_probe,
index ac184e60797e5f1ffe055c999d648cd06e58c557..ab7432a5778e278a7ece69777d253911b365646e 100644 (file)
@@ -2,6 +2,7 @@
  * sata_mv.c - Marvell SATA support
  *
  * Copyright 2005: EMC Corporation, all rights reserved.
+ * Copyright 2005 Red Hat, Inc.  All rights reserved.
  *
  * Please ALWAYS copy linux-ide@vger.kernel.org on emails.
  *
@@ -36,7 +37,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "sata_mv"
-#define DRV_VERSION    "0.25"
+#define DRV_VERSION    "0.5"
 
 enum {
        /* BAR's are enumerated in terms of pci_resource_start() terms */
index cb1933a3bd55e03ca88ccfe9e5e6af74dd9a07e6..e0d6f194f54f50217b047083300c32133b35e18e 100644 (file)
@@ -5,17 +5,6 @@
  *
  * Based on preview driver from Silicon Image.
  *
- * NOTE: No NCQ/ATAPI support yet.  The preview driver didn't support
- * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
- * those work.  Enabling those shouldn't be difficult.  Basic
- * structure is all there (in libata-dev tree).  If you have any
- * information about this hardware, please contact me or linux-ide.
- * Info is needed on...
- *
- * - How to issue tagged commands and turn on sactive on issue accordingly.
- * - Where to put an ATAPI command and how to tell the device to send it.
- * - How to enable/use 64bit.
- *
  * 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, or (at your option) any
@@ -42,7 +31,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "sata_sil24"
-#define DRV_VERSION    "0.22"  /* Silicon Image's preview driver was 0.10 */
+#define DRV_VERSION    "0.23"
 
 /*
  * Port request block (PRB) 32 bytes
@@ -221,11 +210,22 @@ enum {
        IRQ_STAT_4PORTS         = 0xf,
 };
 
-struct sil24_cmd_block {
+struct sil24_ata_block {
        struct sil24_prb prb;
        struct sil24_sge sge[LIBATA_MAX_PRD];
 };
 
+struct sil24_atapi_block {
+       struct sil24_prb prb;
+       u8 cdb[16];
+       struct sil24_sge sge[LIBATA_MAX_PRD - 1];
+};
+
+union sil24_cmd_block {
+       struct sil24_ata_block ata;
+       struct sil24_atapi_block atapi;
+};
+
 /*
  * ap->private_data
  *
@@ -233,7 +233,7 @@ struct sil24_cmd_block {
  * here from the previous interrupt.
  */
 struct sil24_port_priv {
-       struct sil24_cmd_block *cmd_block;      /* 32 cmd blocks */
+       union sil24_cmd_block *cmd_block;       /* 32 cmd blocks */
        dma_addr_t cmd_block_dma;               /* DMA base addr for them */
        struct ata_taskfile tf;                 /* Cached taskfile registers */
 };
@@ -244,6 +244,7 @@ struct sil24_host_priv {
        void __iomem *port_base;        /* port registers (4 * 8192 bytes @BAR2) */
 };
 
+static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
 static u8 sil24_check_status(struct ata_port *ap);
 static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
 static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -297,6 +298,8 @@ static struct scsi_host_template sil24_sht = {
 static const struct ata_port_operations sil24_ops = {
        .port_disable           = ata_port_disable,
 
+       .dev_config             = sil24_dev_config,
+
        .check_status           = sil24_check_status,
        .check_altstatus        = sil24_check_status,
        .dev_select             = ata_noop_dev_select,
@@ -333,7 +336,7 @@ static struct ata_port_info sil24_port_info[] = {
        {
                .sht            = &sil24_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
                                  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -344,7 +347,7 @@ static struct ata_port_info sil24_port_info[] = {
        {
                .sht            = &sil24_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
                                  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -355,7 +358,7 @@ static struct ata_port_info sil24_port_info[] = {
        {
                .sht            = &sil24_sht,
                .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+                                 ATA_FLAG_SRST | ATA_FLAG_MMIO |
                                  ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -364,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = {
        },
 };
 
+static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
+{
+       void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+
+       if (ap->cdb_len == 16)
+               writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
+       else
+               writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);
+}
+
 static inline void sil24_update_tf(struct ata_port *ap)
 {
        struct sil24_port_priv *pp = ap->private_data;
@@ -415,22 +428,73 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
        *tf = pp->tf;
 }
 
-static void sil24_phy_reset(struct ata_port *ap)
+static int sil24_issue_SRST(struct ata_port *ap)
 {
-       __sata_phy_reset(ap);
+       void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+       struct sil24_port_priv *pp = ap->private_data;
+       struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
+       dma_addr_t paddr = pp->cmd_block_dma;
+       u32 irq_enable, irq_stat;
+       int cnt;
+
+       /* temporarily turn off IRQs during SRST */
+       irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
+       writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
+
        /*
-        * No ATAPI yet.  Just unconditionally indicate ATA device.
-        * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
-        * and libata core will ignore the device.
+        * XXX: Not sure whether the following sleep is needed or not.
+        * The original driver had it.  So....
         */
-       if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
-               ap->device[0].class = ATA_DEV_ATA;
+       msleep(10);
+
+       prb->ctrl = PRB_CTRL_SRST;
+       prb->fis[1] = 0; /* no PM yet */
+
+       writel((u32)paddr, port + PORT_CMD_ACTIVATE);
+
+       for (cnt = 0; cnt < 100; cnt++) {
+               irq_stat = readl(port + PORT_IRQ_STAT);
+               writel(irq_stat, port + PORT_IRQ_STAT);         /* clear irq */
+
+               irq_stat >>= PORT_IRQ_RAW_SHIFT;
+               if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
+                       break;
+
+               msleep(1);
+       }
+
+       /* restore IRQs */
+       writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
+
+       if (!(irq_stat & PORT_IRQ_COMPLETE))
+               return -1;
+
+       /* update TF */
+       sil24_update_tf(ap);
+       return 0;
+}
+
+static void sil24_phy_reset(struct ata_port *ap)
+{
+       struct sil24_port_priv *pp = ap->private_data;
+
+       __sata_phy_reset(ap);
+       if (ap->flags & ATA_FLAG_PORT_DISABLED)
+               return;
+
+       if (sil24_issue_SRST(ap) < 0) {
+               printk(KERN_ERR DRV_NAME
+                      " ata%u: SRST failed, disabling port\n", ap->id);
+               ap->ops->port_disable(ap);
+               return;
+       }
+
+       ap->device->class = ata_dev_classify(&pp->tf);
 }
 
 static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
-                                struct sil24_cmd_block *cb)
+                                struct sil24_sge *sge)
 {
-       struct sil24_sge *sge = cb->sge;
        struct scatterlist *sg;
        unsigned int idx = 0;
 
@@ -451,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        struct sil24_port_priv *pp = ap->private_data;
-       struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;
-       struct sil24_prb *prb = &cb->prb;
+       union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
+       struct sil24_prb *prb;
+       struct sil24_sge *sge;
 
        switch (qc->tf.protocol) {
        case ATA_PROT_PIO:
        case ATA_PROT_DMA:
        case ATA_PROT_NODATA:
+               prb = &cb->ata.prb;
+               sge = cb->ata.sge;
+               prb->ctrl = 0;
+               break;
+
+       case ATA_PROT_ATAPI:
+       case ATA_PROT_ATAPI_DMA:
+       case ATA_PROT_ATAPI_NODATA:
+               prb = &cb->atapi.prb;
+               sge = cb->atapi.sge;
+               memset(cb->atapi.cdb, 0, 32);
+               memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len);
+
+               if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
+                       if (qc->tf.flags & ATA_TFLAG_WRITE)
+                               prb->ctrl = PRB_CTRL_PACKET_WRITE;
+                       else
+                               prb->ctrl = PRB_CTRL_PACKET_READ;
+               } else
+                       prb->ctrl = 0;
+
                break;
+
        default:
-               /* ATAPI isn't supported yet */
+               prb = NULL;     /* shut up, gcc */
+               sge = NULL;
                BUG();
        }
 
        ata_tf_to_fis(&qc->tf, prb->fis, 0);
 
        if (qc->flags & ATA_QCFLAG_DMAMAP)
-               sil24_fill_sg(qc, cb);
+               sil24_fill_sg(qc, sge);
 }
 
 static int sil24_qc_issue(struct ata_queued_cmd *qc)
@@ -486,6 +574,31 @@ static void sil24_irq_clear(struct ata_port *ap)
        /* unused */
 }
 
+static int __sil24_restart_controller(void __iomem *port)
+{
+       u32 tmp;
+       int cnt;
+
+       writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
+
+       /* Max ~10ms */
+       for (cnt = 0; cnt < 10000; cnt++) {
+               tmp = readl(port + PORT_CTRL_STAT);
+               if (tmp & PORT_CS_RDY)
+                       return 0;
+               udelay(1);
+       }
+
+       return -1;
+}
+
+static void sil24_restart_controller(struct ata_port *ap)
+{
+       if (__sil24_restart_controller((void __iomem *)ap->ioaddr.cmd_addr))
+               printk(KERN_ERR DRV_NAME
+                      " ata%u: failed to restart controller\n", ap->id);
+}
+
 static int __sil24_reset_controller(void __iomem *port)
 {
        int cnt;
@@ -505,7 +618,11 @@ static int __sil24_reset_controller(void __iomem *port)
 
        if (tmp & PORT_CS_DEV_RST)
                return -1;
-       return 0;
+
+       if (tmp & PORT_CS_RDY)
+               return 0;
+
+       return __sil24_restart_controller(port);
 }
 
 static void sil24_reset_controller(struct ata_port *ap)
@@ -567,9 +684,15 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
        if (serror)
                writel(serror, port + PORT_SERROR);
 
-       printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"
-              "  stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
-              ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
+       /*
+        * Don't log ATAPI device errors.  They're supposed to happen
+        * and any serious errors will be logged using sense data by
+        * the SCSI layer.
+        */
+       if (ap->device[0].class != ATA_DEV_ATAPI || cmd_err > PORT_CERR_SDB)
+               printk("ata%u: error interrupt on port%d\n"
+                      "  stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
+                      ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
 
        if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
                /*
@@ -577,6 +700,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
                 */
                sil24_update_tf(ap);
                err_mask = ac_err_mask(pp->tf.command);
+               sil24_restart_controller(ap);
        } else {
                /*
                 * Other errors.  libata currently doesn't have any
@@ -584,12 +708,11 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
                 * ATA_ERR.
                 */
                err_mask = AC_ERR_OTHER;
+               sil24_reset_controller(ap);
        }
 
        if (qc)
                ata_qc_complete(qc, err_mask);
-
-       sil24_reset_controller(ap);
 }
 
 static inline void sil24_host_intr(struct ata_port *ap)
@@ -665,7 +788,7 @@ static int sil24_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
        struct sil24_port_priv *pp;
-       struct sil24_cmd_block *cb;
+       union sil24_cmd_block *cb;
        size_t cb_size = sizeof(*cb);
        dma_addr_t cb_dma;
        int rc = -ENOMEM;
index ff36f0c9fdad7f152144bd31a0ede55a5cf72290..ad47c1b84c3f0677f0d6459c89294e4eb912d331 100644 (file)
@@ -507,7 +507,7 @@ config SERIAL_SUNSU_CONSOLE
 
 config SERIAL_MUX
        tristate "Serial MUX support"
-       depends on PARISC
+       depends on GSC
        select SERIAL_CORE
        default y
        ---help---
index 938d185841c9eeb138f04b6c3389d48a03d0a11c..89d7bd3eaee39272c7ede6175ab4c26d478b7bac 100644 (file)
@@ -49,7 +49,6 @@
 #include <linux/serial.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/sizes.h>
 #include <asm/hardware/amba.h>
 #include <asm/hardware/clock.h>
@@ -63,7 +62,8 @@
 
 #define AMBA_ISR_PASS_LIMIT    256
 
-#define UART_DUMMY_RSR_RX      256
+#define UART_DR_ERROR          (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
+#define UART_DUMMY_DR_RX       (1 << 16)
 
 /*
  * We wrap our port structure around the generic uart_port.
@@ -116,7 +116,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
 #endif
 {
        struct tty_struct *tty = uap->port.info->tty;
-       unsigned int status, ch, flag, rsr, max_count = 256;
+       unsigned int status, ch, flag, max_count = 256;
 
        status = readw(uap->port.membase + UART01x_FR);
        while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
@@ -129,7 +129,7 @@ pl011_rx_chars(struct uart_amba_port *uap)
                         */
                }
 
-               ch = readw(uap->port.membase + UART01x_DR);
+               ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
                flag = TTY_NORMAL;
                uap->port.icount.rx++;
 
@@ -137,34 +137,33 @@ pl011_rx_chars(struct uart_amba_port *uap)
                 * Note that the error handling code is
                 * out of the main execution path
                 */
-               rsr = readw(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
-               if (unlikely(rsr & UART01x_RSR_ANY)) {
-                       if (rsr & UART01x_RSR_BE) {
-                               rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
+               if (unlikely(ch & UART_DR_ERROR)) {
+                       if (ch & UART011_DR_BE) {
+                               ch &= ~(UART011_DR_FE | UART011_DR_PE);
                                uap->port.icount.brk++;
                                if (uart_handle_break(&uap->port))
                                        goto ignore_char;
-                       } else if (rsr & UART01x_RSR_PE)
+                       } else if (ch & UART011_DR_PE)
                                uap->port.icount.parity++;
-                       else if (rsr & UART01x_RSR_FE)
+                       else if (ch & UART011_DR_FE)
                                uap->port.icount.frame++;
-                       if (rsr & UART01x_RSR_OE)
+                       if (ch & UART011_DR_OE)
                                uap->port.icount.overrun++;
 
-                       rsr &= uap->port.read_status_mask;
+                       ch &= uap->port.read_status_mask;
 
-                       if (rsr & UART01x_RSR_BE)
+                       if (ch & UART011_DR_BE)
                                flag = TTY_BREAK;
-                       else if (rsr & UART01x_RSR_PE)
+                       else if (ch & UART011_DR_PE)
                                flag = TTY_PARITY;
-                       else if (rsr & UART01x_RSR_FE)
+                       else if (ch & UART011_DR_FE)
                                flag = TTY_FRAME;
                }
 
                if (uart_handle_sysrq_char(&uap->port, ch, regs))
                        goto ignore_char;
 
-               uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
+               uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
 
        ignore_char:
                status = readw(uap->port.membase + UART01x_FR);
@@ -476,33 +475,33 @@ pl011_set_termios(struct uart_port *port, struct termios *termios,
         */
        uart_update_timeout(port, termios->c_cflag, baud);
 
-       port->read_status_mask = UART01x_RSR_OE;
+       port->read_status_mask = UART011_DR_OE | 255;
        if (termios->c_iflag & INPCK)
-               port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+               port->read_status_mask |= UART011_DR_FE | UART011_DR_PE;
        if (termios->c_iflag & (BRKINT | PARMRK))
-               port->read_status_mask |= UART01x_RSR_BE;
+               port->read_status_mask |= UART011_DR_BE;
 
        /*
         * Characters to ignore
         */
        port->ignore_status_mask = 0;
        if (termios->c_iflag & IGNPAR)
-               port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
+               port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE;
        if (termios->c_iflag & IGNBRK) {
-               port->ignore_status_mask |= UART01x_RSR_BE;
+               port->ignore_status_mask |= UART011_DR_BE;
                /*
                 * If we're ignoring parity and break indicators,
                 * ignore overruns too (for real raw support).
                 */
                if (termios->c_iflag & IGNPAR)
-                       port->ignore_status_mask |= UART01x_RSR_OE;
+                       port->ignore_status_mask |= UART011_DR_OE;
        }
 
        /*
         * Ignore all characters if CREAD is not set.
         */
        if ((termios->c_cflag & CREAD) == 0)
-               port->ignore_status_mask |= UART_DUMMY_RSR_RX;
+               port->ignore_status_mask |= UART_DUMMY_DR_RX;
 
        if (UART_ENABLE_MS(port, termios->c_cflag))
                pl011_enable_ms(port);
index 355cd93a8a873aa277dbcc65bf3d4c41c5f49d0e..83c4c12165877c4e02b2449a63969dbdba05ab04 100644 (file)
@@ -994,7 +994,7 @@ static int __init imx_serial_init(void)
 static void __exit imx_serial_exit(void)
 {
        uart_unregister_driver(&imx_reg);
-       driver_unregister(&serial_imx_driver);
+       platform_driver_unregister(&serial_imx_driver);
 }
 
 module_init(imx_serial_init);
index 660bae5ba179bf87a5197905265f726f00b0165d..7633132a10aab7d553f96f156d2af34affb5ceda 100644 (file)
@@ -65,8 +65,8 @@ static struct uart_driver mux_driver = {
 
 static struct timer_list mux_timer;
 
-#define UART_PUT_CHAR(p, c) __raw_writel((c), (unsigned long)(p)->membase + IO_DATA_REG_OFFSET)
-#define UART_GET_FIFO_CNT(p) __raw_readl((unsigned long)(p)->membase + IO_DCOUNT_REG_OFFSET)
+#define UART_PUT_CHAR(p, c) __raw_writel((c), (p)->membase + IO_DATA_REG_OFFSET)
+#define UART_GET_FIFO_CNT(p) __raw_readl((p)->membase + IO_DCOUNT_REG_OFFSET)
 #define GET_MUX_PORTS(iodc_data) ((((iodc_data)[4] & 0xf0) >> 4) * 8) + 8
 
 /**
@@ -79,10 +79,7 @@ static struct timer_list mux_timer;
  */
 static unsigned int mux_tx_empty(struct uart_port *port)
 {
-       unsigned int cnt = __raw_readl((unsigned long)port->membase 
-                               + IO_DCOUNT_REG_OFFSET);
-
-       return cnt ? 0 : TIOCSER_TEMT;
+       return UART_GET_FIFO_CNT(port) ? 0 : TIOCSER_TEMT;
 } 
 
 /**
@@ -218,8 +215,7 @@ static void mux_read(struct uart_port *port)
        __u32 start_count = port->icount.rx;
 
        while(1) {
-               data = __raw_readl((unsigned long)port->membase
-                                               + IO_DATA_REG_OFFSET);
+               data = __raw_readl(port->membase + IO_DATA_REG_OFFSET);
 
                if (MUX_STATUS(data))
                        continue;
@@ -481,6 +477,13 @@ static int __init mux_probe(struct parisc_device *dev)
                port->ops       = &mux_pops;
                port->flags     = UPF_BOOT_AUTOCONF;
                port->line      = port_cnt;
+
+               /* The port->timeout needs to match what is present in
+                * uart_wait_until_sent in serial_core.c.  Otherwise
+                * the time spent in msleep_interruptable will be very
+                * long, causing the appearance of a console hang.
+                */
+               port->timeout   = HZ / 50;
                spin_lock_init(&port->lock);
                status = uart_add_one_port(&mux_driver, port);
                BUG_ON(status);
index 0e3daf6d7b502575f05baf78d90bb7f37919f2d2..25a086458ab9bcb431d06eb6a7d92e71d3e7f405 100644 (file)
@@ -161,7 +161,6 @@ static void sa1100_stop_tx(struct uart_port *port)
 static void sa1100_start_tx(struct uart_port *port)
 {
        struct sa1100_port *sport = (struct sa1100_port *)port;
-       unsigned long flags;
        u32 utcr3;
 
        utcr3 = UART_GET_UTCR3(sport);
index eab3750cf3048507a8785958139c00e512e1b76c..6bded10c0d507c01ece3e758d162882398beafd7 100644 (file)
@@ -3,6 +3,8 @@ Version 1.39
 Defer close of a file handle slightly if pending writes depend on that file handle
 (this reduces the EBADF bad file handle errors that can be logged under heavy
 stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 
+Fix SFU style symlinks and mknod needed for servers which do not support the CIFS
+Unix Extensions.  Fix setfacl/getfacl on bigendian. 
 
 Version 1.38
 ------------
index 4e12053f0806bed870906a3280d428ad8a9d9186..d2b128255944269506f5395506528a4009d7d6dd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifs_unicode.c
  *
- *   Copyright (c) International Business Machines  Corp., 2000,2002
+ *   Copyright (c) International Business Machines  Corp., 2000,2005
  *   Modified by Steve French (sfrench@us.ibm.com)
  *
  *   This program is free software;  you can redistribute it and/or modify
@@ -31,7 +31,7 @@
  *
  */
 int
-cifs_strfromUCS_le(char *to, const wchar_t * from,     /* LITTLE ENDIAN */
+cifs_strfromUCS_le(char *to, const __le16 * from,      
                   int len, const struct nls_table *codepage)
 {
        int i;
@@ -60,25 +60,26 @@ cifs_strfromUCS_le(char *to, const wchar_t * from,  /* LITTLE ENDIAN */
  *
  */
 int
-cifs_strtoUCS(wchar_t * to, const char *from, int len,
+cifs_strtoUCS(__le16 * to, const char *from, int len,
              const struct nls_table *codepage)
 {
        int charlen;
        int i;
+       wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */  
 
        for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
 
                /* works for 2.4.0 kernel or later */
-               charlen = codepage->char2uni(from, len, &to[i]);
+               charlen = codepage->char2uni(from, len, &wchar_to[i]);
                if (charlen < 1) {
                        cERROR(1,
                               ("cifs_strtoUCS: char2uni returned %d",
                                charlen));
                        /* A question mark */
-                       to[i] = (wchar_t)cpu_to_le16(0x003f);
+                       to[i] = cpu_to_le16(0x003f);
                        charlen = 1;
                } else 
-                       to[i] = (wchar_t)cpu_to_le16(to[i]);
+                       to[i] = cpu_to_le16(wchar_to[i]);
 
        }
 
index da8dde9652751b4506af896b0b528c532f4a9e30..39e5b970325f6a14428eef357e98da44808356d1 100644 (file)
@@ -5,7 +5,7 @@
  *     Convert a unicode character to upper or lower case using
  *     compressed tables.
  *
- *   Copyright (c) International Business Machines  Corp., 2000,2002
+ *   Copyright (c) International Business Machines  Corp., 2000,2005555555555555555555555555555555555555555555555555555555
  *
  *   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
@@ -59,8 +59,8 @@ extern struct UniCaseRange UniLowerRange[];
 #endif                         /* UNIUPR_NOLOWER */
 
 #ifdef __KERNEL__
-int cifs_strfromUCS_le(char *, const wchar_t *, int, const struct nls_table *);
-int cifs_strtoUCS(wchar_t *, const char *, int, const struct nls_table *);
+int cifs_strfromUCS_le(char *, const __le16 *, int, const struct nls_table *);
+int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *);
 #endif
 
 /*
index 1959c7c4b185b48793ed81aee9d1cd61b50cc070..fe2bb7c4c9121c4bcc2cfeeb5ca9ec9669bcc944 100644 (file)
@@ -149,7 +149,7 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
        char temp_hash[16];
        struct HMACMD5Context ctx;
        char * ucase_buf;
-       wchar_t * unicode_buf;
+       __le16 * unicode_buf;
        unsigned int i,user_name_len,dom_name_len;
 
        if(ses == NULL)
index 682b0235ad9a170df904563eea37d9a132291ce2..51548ed2e9cce885869c1c66bd074c119c5abdf6 100644 (file)
@@ -483,57 +483,30 @@ cifs_get_sb(struct file_system_type *fs_type,
        return sb;
 }
 
-static ssize_t
-cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
-          loff_t * poffset)
+static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
+                               unsigned long nr_segs, loff_t *ppos)
 {
-       if(file->f_dentry == NULL)
-               return -EIO;
-       else if(file->f_dentry->d_inode == NULL)
-               return -EIO;
-
-       cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
+       struct inode *inode = file->f_dentry->d_inode;
+       ssize_t written;
 
-       if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {
-               return generic_file_read(file,read_data,read_size,poffset);
-       } else {
-               /* BB do we need to lock inode from here until after invalidate? */
-/*             if(file->f_dentry->d_inode->i_mapping) {
-                       filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
-                       filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
-               }*/
-/*             cifs_revalidate(file->f_dentry);*/ /* BB fixme */
-
-               /* BB we should make timer configurable - perhaps 
-                  by simply calling cifs_revalidate here */
-               /* invalidate_remote_inode(file->f_dentry->d_inode);*/
-               return generic_file_read(file,read_data,read_size,poffset);
-       }
+       written = generic_file_writev(file, iov, nr_segs, ppos);
+       if (!CIFS_I(inode)->clientCanCacheAll)
+               filemap_fdatawrite(inode->i_mapping);
+       return written;
 }
 
-static ssize_t
-cifs_write_wrapper(struct file * file, const char __user *write_data,
-           size_t write_size, loff_t * poffset) 
+static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
+                                  size_t count, loff_t pos)
 {
+       struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
        ssize_t written;
 
-       if(file->f_dentry == NULL)
-               return -EIO;
-       else if(file->f_dentry->d_inode == NULL)
-               return -EIO;
-
-       cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));
-
-       written = generic_file_write(file,write_data,write_size,poffset);
-       if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll)  {
-               if(file->f_dentry->d_inode->i_mapping) {
-                       filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
-               }
-       }
+       written = generic_file_aio_write(iocb, buf, count, pos);
+       if (!CIFS_I(inode)->clientCanCacheAll)
+               filemap_fdatawrite(inode->i_mapping);
        return written;
 }
 
-
 static struct file_system_type cifs_fs_type = {
        .owner = THIS_MODULE,
        .name = "cifs",
@@ -594,8 +567,12 @@ struct inode_operations cifs_symlink_inode_ops = {
 };
 
 struct file_operations cifs_file_ops = {
-       .read = cifs_read_wrapper,
-       .write = cifs_write_wrapper, 
+       .read = do_sync_read,
+       .write = do_sync_write,
+       .readv = generic_file_readv,
+       .writev = cifs_file_writev,
+       .aio_read = generic_file_aio_read,
+       .aio_write = cifs_file_aio_write,
        .open = cifs_open,
        .release = cifs_close,
        .lock = cifs_lock,
@@ -608,10 +585,6 @@ struct file_operations cifs_file_ops = {
 #endif /* CONFIG_CIFS_POSIX */
 
 #ifdef CONFIG_CIFS_EXPERIMENTAL
-       .readv = generic_file_readv,
-       .writev = generic_file_writev,
-       .aio_read = generic_file_aio_read,
-       .aio_write = generic_file_aio_write,
        .dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
 };
@@ -631,6 +604,46 @@ struct file_operations cifs_file_direct_ops = {
        .ioctl  = cifs_ioctl,
 #endif /* CONFIG_CIFS_POSIX */
 
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+       .dir_notify = cifs_dir_notify,
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
+};
+struct file_operations cifs_file_nobrl_ops = {
+       .read = do_sync_read,
+       .write = do_sync_write,
+       .readv = generic_file_readv,
+       .writev = cifs_file_writev,
+       .aio_read = generic_file_aio_read,
+       .aio_write = cifs_file_aio_write,
+       .open = cifs_open,
+       .release = cifs_close,
+       .fsync = cifs_fsync,
+       .flush = cifs_flush,
+       .mmap  = cifs_file_mmap,
+       .sendfile = generic_file_sendfile,
+#ifdef CONFIG_CIFS_POSIX
+       .ioctl  = cifs_ioctl,
+#endif /* CONFIG_CIFS_POSIX */
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+       .dir_notify = cifs_dir_notify,
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
+};
+
+struct file_operations cifs_file_direct_nobrl_ops = {
+       /* no mmap, no aio, no readv - 
+          BB reevaluate whether they can be done with directio, no cache */
+       .read = cifs_user_read,
+       .write = cifs_user_write,
+       .open = cifs_open,
+       .release = cifs_close,
+       .fsync = cifs_fsync,
+       .flush = cifs_flush,
+       .sendfile = generic_file_sendfile, /* BB removeme BB */
+#ifdef CONFIG_CIFS_POSIX
+       .ioctl  = cifs_ioctl,
+#endif /* CONFIG_CIFS_POSIX */
+
 #ifdef CONFIG_CIFS_EXPERIMENTAL
        .dir_notify = cifs_dir_notify,
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
index 1223fa81dbd269fc696e90951787e29426273f64..9ec40e0e54fc4eed289eb9070aeb0c8120f610cd 100644 (file)
@@ -63,6 +63,8 @@ extern struct inode_operations cifs_symlink_inode_ops;
 /* Functions related to files and directories */
 extern struct file_operations cifs_file_ops;
 extern struct file_operations cifs_file_direct_ops; /* if directio mount */
+extern struct file_operations cifs_file_nobrl_ops;
+extern struct file_operations cifs_file_direct_nobrl_ops; /* if directio mount */
 extern int cifs_open(struct inode *inode, struct file *file);
 extern int cifs_close(struct inode *inode, struct file *file);
 extern int cifs_closedir(struct inode *inode, struct file *file);
index 48a05b9df7eb5f6ef8d66e8b252ee534dbfd257f..33e1859fd2f67ced969247e6a6bc365a941a8895 100644 (file)
@@ -603,7 +603,9 @@ typedef struct smb_com_logoff_andx_rsp {
        __u16 ByteCount;
 } __attribute__((packed)) LOGOFF_ANDX_RSP;
 
-typedef union smb_com_tree_disconnect {        /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */
+typedef union smb_com_tree_disconnect {        /* as an altetnative can use flag on 
+                                       tree_connect PDU to effect disconnect */
+                                       /* tdis is probably simplest SMB PDU */
        struct {
                struct smb_hdr hdr;     /* wct = 0 */
                __u16 ByteCount;        /* bcc = 0 */
@@ -2025,6 +2027,12 @@ typedef struct {
 } __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO;   /* level 0x104 FF response data area */
 
 
+struct win_dev {
+       unsigned char type[8]; /* IntxCHR or IntxBLK */
+       __le64 major;
+       __le64 minor;   
+} __attribute__((packed));
+
 struct gea {
        unsigned char name_len;
        char name[1];
index a53c596e1082fe3c90bc6e93c4736b120ef9d277..d179b0c3eee45e4bc01bd4c6e3242b38f5559a81 100644 (file)
@@ -1142,7 +1142,9 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
        int bytes_returned, wct;
        int smb_hdr_len;
 
-       cFYI(1,("write2 at %lld %d bytes",offset,count)); /* BB removeme BB */
+       /* BB removeme BB */
+       cFYI(1,("write2 at %lld %d bytes", (long long)offset, count));
+
        if(tcon->ses->capabilities & CAP_LARGE_FILES)
                wct = 14;
        else
@@ -1553,7 +1555,7 @@ createSymLinkRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, PATH_MAX
+                   cifs_strtoUCS((__le16 *) pSMB->FileName, fromName, PATH_MAX
                                  /* find define for this maxpathcomponent */
                                  , nls_codepage);
                name_len++;     /* trailing null */
@@ -1577,7 +1579,7 @@ createSymLinkRetry:
        data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len_target =
-                   cifs_strtoUCS((wchar_t *) data_offset, toName, PATH_MAX
+                   cifs_strtoUCS((__le16 *) data_offset, toName, PATH_MAX
                                  /* find define for this maxpathcomponent */
                                  , nls_codepage);
                name_len_target++;      /* trailing null */
@@ -1803,7 +1805,7 @@ querySymLinkRetry:
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
-                   cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX
+                   cifs_strtoUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX
                                  /* find define for this maxpathcomponent */
                                  , nls_codepage);
                name_len++;     /* trailing null */
@@ -1860,7 +1862,7 @@ querySymLinkRetry:
                                        min_t(const int, buflen,count) / 2);
                        /* BB FIXME investigate remapping reserved chars here */
                                cifs_strfromUCS_le(symlinkinfo,
-                                       (wchar_t *) ((char *)&pSMBr->hdr.Protocol +
+                                       (__le16 *) ((char *)&pSMBr->hdr.Protocol +
                                                data_offset),
                                        name_len, nls_codepage);
                        } else {
@@ -1951,7 +1953,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
                                                        reparse_buf->TargetNameOffset),
                                                        min(buflen/2, reparse_buf->TargetNameLen / 2)); 
                                        cifs_strfromUCS_le(symlinkinfo,
-                                               (wchar_t *) (reparse_buf->LinkNamesBuf + 
+                                               (__le16 *) (reparse_buf->LinkNamesBuf + 
                                                reparse_buf->TargetNameOffset),
                                                name_len, nls_codepage);
                                } else { /* ASCII names */
@@ -1983,9 +1985,9 @@ qreparse_out:
 static void cifs_convert_ace(posix_acl_xattr_entry * ace, struct cifs_posix_ace * cifs_ace)
 {
        /* u8 cifs fields do not need le conversion */
-       ace->e_perm = (__u16)cifs_ace->cifs_e_perm; 
-       ace->e_tag  = (__u16)cifs_ace->cifs_e_tag;
-       ace->e_id   = (__u32)le64_to_cpu(cifs_ace->cifs_uid);
+       ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
+       ace->e_tag  = cpu_to_le16(cifs_ace->cifs_e_tag);
+       ace->e_id   = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
        /* cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id)); */
 
        return;
@@ -2037,7 +2039,7 @@ static int cifs_copy_posix_acl(char * trgt,char * src, const int buflen,
        } else if(size > buflen) {
                return -ERANGE;
        } else /* buffer big enough */ {
-               local_acl->a_version = POSIX_ACL_XATTR_VERSION;
+               local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
                for(i = 0;i < count ;i++) {
                        cifs_convert_ace(&local_acl->a_entries[i],pACE);
                        pACE ++;
@@ -2051,14 +2053,14 @@ static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace,
 {
        __u16 rc = 0; /* 0 = ACL converted ok */
 
-       cifs_ace->cifs_e_perm = (__u8)cpu_to_le16(local_ace->e_perm);
-       cifs_ace->cifs_e_tag =  (__u8)cpu_to_le16(local_ace->e_tag);
+       cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
+       cifs_ace->cifs_e_tag =  le16_to_cpu(local_ace->e_tag);
        /* BB is there a better way to handle the large uid? */
-       if(local_ace->e_id == -1) {
+       if(local_ace->e_id == cpu_to_le32(-1)) {
        /* Probably no need to le convert -1 on any arch but can not hurt */
                cifs_ace->cifs_uid = cpu_to_le64(-1);
        } else 
-               cifs_ace->cifs_uid = (__u64)cpu_to_le32(local_ace->e_id);
+               cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
         /*cFYI(1,("perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id));*/
        return rc;
 }
@@ -2078,16 +2080,17 @@ static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int bufl
 
        count = posix_acl_xattr_count((size_t)buflen);
        cFYI(1,("setting acl with %d entries from buf of length %d and version of %d",
-               count,buflen,local_acl->a_version));
-       if(local_acl->a_version != 2) {
-               cFYI(1,("unknown POSIX ACL version %d",local_acl->a_version));
+               count, buflen, le32_to_cpu(local_acl->a_version)));
+       if(le32_to_cpu(local_acl->a_version) != 2) {
+               cFYI(1,("unknown POSIX ACL version %d",
+                    le32_to_cpu(local_acl->a_version)));
                return 0;
        }
        cifs_acl->version = cpu_to_le16(1);
        if(acl_type == ACL_TYPE_ACCESS) 
-               cifs_acl->access_entry_count = count;
+               cifs_acl->access_entry_count = cpu_to_le16(count);
        else if(acl_type == ACL_TYPE_DEFAULT)
-               cifs_acl->default_entry_count = count;
+               cifs_acl->default_entry_count = cpu_to_le16(count);
        else {
                cFYI(1,("unknown ACL type %d",acl_type));
                return 0;
@@ -3203,7 +3206,7 @@ getDFSRetry:
                                temp = ((char *)referrals) + le16_to_cpu(referrals->DfsPathOffset);
                                if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
                                        cifs_strfromUCS_le(*targetUNCs,
-                                               (wchar_t *) temp, name_len, nls_codepage);
+                                               (__le16 *) temp, name_len, nls_codepage);
                                } else {
                                        strncpy(*targetUNCs,temp,name_len);
                                }
index 2cb620716bc14661295a8c4fe6782d0e9ac99f62..c467de8576105bdd3bdb4d1983b591be53609b2e 100644 (file)
@@ -1986,32 +1986,32 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                        bytes_returned = 0; /* skill null user */
                else
                        bytes_returned =
-                               cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100,
+                               cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
                                        nls_codepage);
                /* convert number of 16 bit words to bytes */
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;   /* trailing null */
                if (domain == NULL)
                        bytes_returned =
-                           cifs_strtoUCS((wchar_t *) bcc_ptr,
+                           cifs_strtoUCS((__le16 *) bcc_ptr,
                                          "CIFS_LINUX_DOM", 32, nls_codepage);
                else
                        bytes_returned =
-                           cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
+                           cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
                                          nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
+                   cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
                                  64, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
@@ -2081,7 +2081,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                if(ses->serverOS == NULL)
                                        goto sesssetup_nomem;
                                cifs_strfromUCS_le(ses->serverOS,
-                                          (wchar_t *)bcc_ptr, len,nls_codepage);
+                                          (__le16 *)bcc_ptr, len,nls_codepage);
                                bcc_ptr += 2 * (len + 1);
                                remaining_words -= len + 1;
                                ses->serverOS[2 * len] = 0;
@@ -2093,7 +2093,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        if(ses->serverNOS == NULL)
                                                goto sesssetup_nomem;
                                        cifs_strfromUCS_le(ses->serverNOS,
-                                                          (wchar_t *)bcc_ptr,len,nls_codepage);
+                                                          (__le16 *)bcc_ptr,len,nls_codepage);
                                        bcc_ptr += 2 * (len + 1);
                                        ses->serverNOS[2 * len] = 0;
                                        ses->serverNOS[1 + (2 * len)] = 0;
@@ -2111,7 +2111,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                if(ses->serverDomain == NULL)
                                                        goto sesssetup_nomem;
                                                cifs_strfromUCS_le(ses->serverDomain,
-                                                    (wchar_t *)bcc_ptr,len,nls_codepage);
+                                                    (__le16 *)bcc_ptr,len,nls_codepage);
                                                bcc_ptr += 2 * (len + 1);
                                                ses->serverDomain[2*len] = 0;
                                                ses->serverDomain[1+(2*len)] = 0;
@@ -2255,30 +2255,30 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                        bcc_ptr++;
                }
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage);
+                   cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage);
                bcc_ptr += 2 * bytes_returned;  /* convert num of 16 bit words to bytes */
                bcc_ptr += 2;   /* trailing null */
                if (domain == NULL)
                        bytes_returned =
-                           cifs_strtoUCS((wchar_t *) bcc_ptr,
+                           cifs_strtoUCS((__le16 *) bcc_ptr,
                                          "CIFS_LINUX_DOM", 32, nls_codepage);
                else
                        bytes_returned =
-                           cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
+                           cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
                                          nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
+                   cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
                                  nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
                                  64, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;
@@ -2357,7 +2357,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        ses->serverOS =
                                            kzalloc(2 * (len + 1), GFP_KERNEL);
                                        cifs_strfromUCS_le(ses->serverOS,
-                                                          (wchar_t *)
+                                                          (__le16 *)
                                                           bcc_ptr, len,
                                                           nls_codepage);
                                        bcc_ptr += 2 * (len + 1);
@@ -2372,7 +2372,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                    kzalloc(2 * (len + 1),
                                                            GFP_KERNEL);
                                                cifs_strfromUCS_le(ses->serverNOS,
-                                                                  (wchar_t *)bcc_ptr,
+                                                                  (__le16 *)bcc_ptr,
                                                                   len,
                                                                   nls_codepage);
                                                bcc_ptr += 2 * (len + 1);
@@ -2384,9 +2384,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                             /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
                                                        ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
                                                        cifs_strfromUCS_le(ses->serverDomain,
-                                                            (wchar_t *)bcc_ptr, 
-                                 len,
-                                                            nls_codepage);
+                                                            (__le16 *)bcc_ptr, 
+                                                            len, nls_codepage);
                                                        bcc_ptr += 2*(len+1);
                                                        ses->serverDomain[2*len] = 0;
                                                        ses->serverDomain[1+(2*len)] = 0;
@@ -2560,16 +2559,16 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                }
 
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
+                   cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
                                  nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;   /* null terminate Linux version */
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
                                  64, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                *(bcc_ptr + 1) = 0;
@@ -2673,7 +2672,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                        ses->serverOS =
                                            kzalloc(2 * (len + 1), GFP_KERNEL);
                                        cifs_strfromUCS_le(ses->serverOS,
-                                                          (wchar_t *)
+                                                          (__le16 *)
                                                           bcc_ptr, len,
                                                           nls_codepage);
                                        bcc_ptr += 2 * (len + 1);
@@ -2690,7 +2689,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                            GFP_KERNEL);
                                                cifs_strfromUCS_le(ses->
                                                                   serverNOS,
-                                                                  (wchar_t *)
+                                                                  (__le16 *)
                                                                   bcc_ptr,
                                                                   len,
                                                                   nls_codepage);
@@ -2708,23 +2707,15 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
                                                                     1),
                                                                    GFP_KERNEL);
                                                        cifs_strfromUCS_le
-                                                           (ses->
-                                                            serverDomain,
-                                                            (wchar_t *)
-                                                            bcc_ptr, len,
-                                                            nls_codepage);
+                                                           (ses->serverDomain,
+                                                            (__le16 *)bcc_ptr,
+                                                            len, nls_codepage);
                                                        bcc_ptr +=
                                                            2 * (len + 1);
-                                                       ses->
-                                                           serverDomain[2
-                                                                        * len]
+                                                       ses->serverDomain[2*len]
                                                            = 0;
-                                                       ses->
-                                                           serverDomain[1
-                                                                        +
-                                                                        (2
-                                                                         *
-                                                                         len)]
+                                                       ses->serverDomain
+                                                               [1 + (2 * len)]
                                                            = 0;
                                                } /* else no more room so create dummy domain string */
                                                else
@@ -2903,7 +2894,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                        SecurityBlob->DomainName.MaximumLength = 0;
                } else {
                        __u16 len =
-                           cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
+                           cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
                                          nls_codepage);
                        len *= 2;
                        SecurityBlob->DomainName.MaximumLength =
@@ -2921,7 +2912,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                        SecurityBlob->UserName.MaximumLength = 0;
                } else {
                        __u16 len =
-                           cifs_strtoUCS((wchar_t *) bcc_ptr, user, 64,
+                           cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
                                          nls_codepage);
                        len *= 2;
                        SecurityBlob->UserName.MaximumLength =
@@ -2934,7 +2925,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                            cpu_to_le16(len);
                }
 
-               /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((wchar_t *) bcc_ptr, "AMACHINE",64, nls_codepage);
+               /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
                   SecurityBlob->WorkstationName.Length *= 2;
                   SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
                   SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
@@ -2947,16 +2938,16 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                        bcc_ptr++;
                }
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
+                   cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
                                  32, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
                                  nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                bcc_ptr += 2;   /* null term version string */
                bytes_returned =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
+                   cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
                                  64, nls_codepage);
                bcc_ptr += 2 * bytes_returned;
                *(bcc_ptr + 1) = 0;
@@ -3069,7 +3060,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                        ses->serverOS =
                                            kzalloc(2 * (len + 1), GFP_KERNEL);
                                        cifs_strfromUCS_le(ses->serverOS,
-                                                          (wchar_t *)
+                                                          (__le16 *)
                                                           bcc_ptr, len,
                                                           nls_codepage);
                                        bcc_ptr += 2 * (len + 1);
@@ -3086,7 +3077,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                            GFP_KERNEL);
                                                cifs_strfromUCS_le(ses->
                                                                   serverNOS,
-                                                                  (wchar_t *)
+                                                                  (__le16 *)
                                                                   bcc_ptr,
                                                                   len,
                                                                   nls_codepage);
@@ -3105,7 +3096,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
                                                        cifs_strfromUCS_le
                                                            (ses->
                                                             serverDomain,
-                                                            (wchar_t *)
+                                                            (__le16 *)
                                                             bcc_ptr, len,
                                                             nls_codepage);
                                                        bcc_ptr +=
@@ -3227,7 +3218,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
        if (ses->capabilities & CAP_UNICODE) {
                smb_buffer->Flags2 |= SMBFLG2_UNICODE;
                length =
-                   cifs_strtoUCS((wchar_t *) bcc_ptr, tree, 100, nls_codepage);
+                   cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage);
                bcc_ptr += 2 * length;  /* convert num of 16 bit words to bytes */
                bcc_ptr += 2;   /* skip trailing null */
        } else {                /* ASCII */
@@ -3263,7 +3254,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                                tcon->nativeFileSystem =
                                    kzalloc(length + 2, GFP_KERNEL);
                                cifs_strfromUCS_le(tcon->nativeFileSystem,
-                                                  (wchar_t *) bcc_ptr,
+                                                  (__le16 *) bcc_ptr,
                                                   length, nls_codepage);
                                bcc_ptr += 2 * length;
                                bcc_ptr[0] = 0; /* null terminate the string */
index 8dfe717a332abaef46800beae64c781b26bdb831..16b21522e8fe1bbd06a97a7da2297e38cc8056d3 100644 (file)
@@ -292,7 +292,8 @@ cifs_create_out:
        return rc;
 }
 
-int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t device_number) 
+int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, 
+               dev_t device_number) 
 {
        int rc = -EPERM;
        int xid;
@@ -368,7 +369,34 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, dev_t dev
 
                        if(!rc) {
                                /* BB Do not bother to decode buf since no
-                                  local inode yet to put timestamps in */
+                                  local inode yet to put timestamps in,
+                                  but we can reuse it safely */
+                               int bytes_written;
+                               struct win_dev *pdev;
+                               pdev = (struct win_dev *)buf;
+                               if(S_ISCHR(mode)) {
+                                       memcpy(pdev->type, "IntxCHR", 8);
+                                       pdev->major =
+                                             cpu_to_le64(MAJOR(device_number));
+                                       pdev->minor = 
+                                             cpu_to_le64(MINOR(device_number));
+                                       rc = CIFSSMBWrite(xid, pTcon,
+                                               fileHandle,
+                                               sizeof(struct win_dev),
+                                               0, &bytes_written, (char *)pdev,
+                                               NULL, 0);
+                               } else if(S_ISBLK(mode)) {
+                                       memcpy(pdev->type, "IntxBLK", 8);
+                                       pdev->major =
+                                             cpu_to_le64(MAJOR(device_number));
+                                       pdev->minor =
+                                             cpu_to_le64(MINOR(device_number));
+                                       rc = CIFSSMBWrite(xid, pTcon,
+                                               fileHandle,
+                                               sizeof(struct win_dev),
+                                               0, &bytes_written, (char *)pdev,
+                                               NULL, 0);
+                               } /* else if(S_ISFIFO */
                                CIFSSMBClose(xid, pTcon, fileHandle);
                                d_drop(direntry);
                        }
index da4f5e10b3cc0f84c922660e89745bb14631cff1..14a1c72ced92e1cc98024494ea217b2a7413921d 100644 (file)
@@ -489,8 +489,10 @@ int cifs_close(struct inode *inode, struct file *file)
                                        the struct would be in each open file,
                                        but this should give enough time to 
                                        clear the socket */
+                                       write_unlock(&file->f_owner.lock);
                                        cERROR(1,("close with pending writes"));
                                        msleep(timeout);
+                                       write_lock(&file->f_owner.lock);
                                        timeout *= 4;
                                } 
                                write_unlock(&file->f_owner.lock);
index 923d071163b2769f86e4a5b47d2e77878d13a072..05b525812adb5ba238a8f2bc1138eac7f108a43c 100644 (file)
@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
        char *tmp_path;
 
        pTcon = cifs_sb->tcon;
-       cFYI(1, (" Getting info on %s ", search_path));
+       cFYI(1, ("Getting info on %s ", search_path));
        /* could have done a find first instead but this returns more info */
        rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
                                  cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                inode = *pinode;
                cifsInfo = CIFS_I(inode);
 
-               cFYI(1, (" Old time %ld ", cifsInfo->time));
+               cFYI(1, ("Old time %ld ", cifsInfo->time));
                cifsInfo->time = jiffies;
-               cFYI(1, (" New time %ld ", cifsInfo->time));
+               cFYI(1, ("New time %ld ", cifsInfo->time));
                /* this is ok to set on every inode revalidate */
                atomic_set(&cifsInfo->inUse,1);
 
@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                inode->i_ctime =
                    cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
                inode->i_mode = le64_to_cpu(findData.Permissions);
+               /* since we set the inode type below we need to mask off
+                   to avoid strange results if bits set above */
+                        inode->i_mode &= ~S_IFMT;
                if (type == UNIX_FILE) {
                        inode->i_mode |= S_IFREG;
                } else if (type == UNIX_SYMLINK) {
@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                        inode->i_mode |= S_IFIFO;
                } else if (type == UNIX_SOCKET) {
                        inode->i_mode |= S_IFSOCK;
+               } else {
+                       /* safest to call it a file if we do not know */
+                       inode->i_mode |= S_IFREG;
+                       cFYI(1,("unknown type %d",type));
                }
                inode->i_uid = le64_to_cpu(findData.Uid);
                inode->i_gid = le64_to_cpu(findData.Gid);
@@ -155,34 +162,39 @@ int cifs_get_inode_info_unix(struct inode **pinode,
                }
 
                if (num_of_bytes < end_of_file)
-                       cFYI(1, ("allocation size less than end of file "));
+                       cFYI(1, ("allocation size less than end of file"));
                cFYI(1,
                     ("Size %ld and blocks %ld",
                      (unsigned long) inode->i_size, inode->i_blocks));
                if (S_ISREG(inode->i_mode)) {
-                       cFYI(1, (" File inode "));
+                       cFYI(1, ("File inode"));
                        inode->i_op = &cifs_file_inode_ops;
-                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
-                               inode->i_fop = &cifs_file_direct_ops;
-                       else
+                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
+                               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                                       inode->i_fop = 
+                                               &cifs_file_direct_nobrl_ops;
+                               else
+                                       inode->i_fop = &cifs_file_direct_ops;
+                       } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                               inode->i_fop = &cifs_file_nobrl_ops;
+                       else /* not direct, send byte range locks */ 
                                inode->i_fop = &cifs_file_ops;
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
-                               inode->i_fop->lock = NULL;
+
                        inode->i_data.a_ops = &cifs_addr_ops;
                        /* check if server can support readpages */
                        if(pTcon->ses->server->maxBuf < 
                            4096 + MAX_CIFS_HDR_SIZE)
                                inode->i_data.a_ops->readpages = NULL;
                } else if (S_ISDIR(inode->i_mode)) {
-                       cFYI(1, (" Directory inode"));
+                       cFYI(1, ("Directory inode"));
                        inode->i_op = &cifs_dir_inode_ops;
                        inode->i_fop = &cifs_dir_ops;
                } else if (S_ISLNK(inode->i_mode)) {
-                       cFYI(1, (" Symbolic Link inode "));
+                       cFYI(1, ("Symbolic Link inode"));
                        inode->i_op = &cifs_symlink_inode_ops;
                /* tmp_inode->i_fop = */ /* do not need to set to anything */
                } else {
-                       cFYI(1, (" Init special inode "));
+                       cFYI(1, ("Init special inode"));
                        init_special_inode(inode, inode->i_mode,
                                           inode->i_rdev);
                }
@@ -190,6 +202,111 @@ int cifs_get_inode_info_unix(struct inode **pinode,
        return rc;
 }
 
+static int decode_sfu_inode(struct inode * inode, __u64 size,
+                           const unsigned char *path,
+                           struct cifs_sb_info *cifs_sb, int xid)
+{
+       int rc;
+       int oplock = FALSE;
+       __u16 netfid;
+       struct cifsTconInfo *pTcon = cifs_sb->tcon;
+       char buf[24];
+       unsigned int bytes_read;
+       char * pbuf;
+
+       pbuf = buf;
+
+       if(size == 0) {
+               inode->i_mode |= S_IFIFO;
+               return 0;
+       } else if (size < 8) {
+               return -EINVAL;  /* EOPNOTSUPP? */
+       }
+               
+       rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
+                        CREATE_NOT_DIR, &netfid, &oplock, NULL,
+                        cifs_sb->local_nls,
+                        cifs_sb->mnt_cifs_flags &
+                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+       if (rc==0) {
+                       /* Read header */
+               rc = CIFSSMBRead(xid, pTcon,
+                                netfid,
+                                24 /* length */, 0 /* offset */,
+                                &bytes_read, &pbuf);
+               if((rc == 0) && (bytes_read >= 8)) {
+                       if(memcmp("IntxBLK", pbuf, 8) == 0) {
+                               cFYI(1,("Block device"));
+                               inode->i_mode |= S_IFBLK;
+                               if(bytes_read == 24) {
+                                       /* we have enough to decode dev num */
+                                       __u64 mjr; /* major */
+                                       __u64 mnr; /* minor */
+                                       mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
+                                       mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
+                                       inode->i_rdev = MKDEV(mjr, mnr);
+                               }
+                       } else if(memcmp("IntxCHR", pbuf, 8) == 0) {
+                               cFYI(1,("Char device"));
+                               inode->i_mode |= S_IFCHR;
+                               if(bytes_read == 24) {
+                                       /* we have enough to decode dev num */
+                                       __u64 mjr; /* major */
+                                       __u64 mnr; /* minor */
+                                       mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
+                                       mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
+                                       inode->i_rdev = MKDEV(mjr, mnr);
+                                }
+                       } else if(memcmp("IntxLNK", pbuf, 7) == 0) {
+                               cFYI(1,("Symlink"));
+                               inode->i_mode |= S_IFLNK;
+                       } else {
+                               inode->i_mode |= S_IFREG; /* file? */
+                               rc = -EOPNOTSUPP; 
+                       }
+               } else {
+                       inode->i_mode |= S_IFREG; /* then it is a file */
+                       rc = -EOPNOTSUPP; /* or some unknown SFU type */        
+               }
+               CIFSSMBClose(xid, pTcon, netfid);
+       }
+       return rc;
+       
+}
+
+#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */
+
+static int get_sfu_uid_mode(struct inode * inode,
+                       const unsigned char *path,
+                       struct cifs_sb_info *cifs_sb, int xid)
+{
+#ifdef CONFIG_CIFS_XATTR
+       ssize_t rc;
+       char ea_value[4];
+       __u32 mode;
+
+       rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
+                       ea_value, 4 /* size of buf */, cifs_sb->local_nls,
+                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+       if(rc < 0)
+               return (int)rc;
+       else if (rc > 3) {
+               mode = le32_to_cpu(*((__le32 *)ea_value));
+               inode->i_mode &= ~SFBITS_MASK; 
+               cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode));
+               inode->i_mode = (mode &  SFBITS_MASK) | inode->i_mode;
+               cFYI(1,("special mode bits 0%o", mode));
+               return 0;
+       } else {
+               return 0;
+       }
+#else
+       return -EOPNOTSUPP;
+#endif
+
+               
+}
+
 int cifs_get_inode_info(struct inode **pinode,
        const unsigned char *search_path, FILE_ALL_INFO *pfindData,
        struct super_block *sb, int xid)
@@ -202,7 +319,7 @@ int cifs_get_inode_info(struct inode **pinode,
        char *buf = NULL;
 
        pTcon = cifs_sb->tcon;
-       cFYI(1,("Getting info on %s ", search_path));
+       cFYI(1,("Getting info on %s", search_path));
 
        if ((pfindData == NULL) && (*pinode != NULL)) {
                if (CIFS_I(*pinode)->clientCanCacheRead) {
@@ -303,9 +420,9 @@ int cifs_get_inode_info(struct inode **pinode,
                inode = *pinode;
                cifsInfo = CIFS_I(inode);
                cifsInfo->cifsAttrs = attr;
-               cFYI(1, (" Old time %ld ", cifsInfo->time));
+               cFYI(1, ("Old time %ld ", cifsInfo->time));
                cifsInfo->time = jiffies;
-               cFYI(1, (" New time %ld ", cifsInfo->time));
+               cFYI(1, ("New time %ld ", cifsInfo->time));
 
                /* blksize needs to be multiple of two. So safer to default to
                blksize and blkbits set in superblock so 2**blkbits and blksize
@@ -319,13 +436,15 @@ int cifs_get_inode_info(struct inode **pinode,
                    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
                inode->i_ctime =
                    cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
-               cFYI(0, (" Attributes came in as 0x%x ", attr));
+               cFYI(0, ("Attributes came in as 0x%x ", attr));
 
                /* set default mode. will override for dirs below */
                if (atomic_read(&cifsInfo->inUse) == 0)
                        /* new inode, can safely set these fields */
                        inode->i_mode = cifs_sb->mnt_file_mode;
-
+               else /* since we set the inode type below we need to mask off
+                    to avoid strange results if type changes and both get orred in */ 
+                       inode->i_mode &= ~S_IFMT; 
 /*             if (attr & ATTR_REPARSE)  */
                /* We no longer handle these as symlinks because we could not
                   follow them due to the absolute path with drive letter */
@@ -340,10 +459,16 @@ int cifs_get_inode_info(struct inode **pinode,
                           (pfindData->EndOfFile == 0)) {
                        inode->i_mode = cifs_sb->mnt_file_mode;
                        inode->i_mode |= S_IFIFO;
-/* BB Finish for SFU style symlinks and devies */
-/*             } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
-                          (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */
-
+/* BB Finish for SFU style symlinks and devices */
+               } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
+                          (cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
+                       if (decode_sfu_inode(inode, 
+                                        le64_to_cpu(pfindData->EndOfFile),
+                                        search_path,
+                                        cifs_sb, xid)) {
+                               cFYI(1,("Unrecognized sfu inode type"));
+                       }
+                       cFYI(1,("sfu mode 0%o",inode->i_mode));
                } else {
                        inode->i_mode |= S_IFREG;
                        /* treat the dos attribute of read-only as read-only
@@ -368,7 +493,10 @@ int cifs_get_inode_info(struct inode **pinode,
 
                /* BB fill in uid and gid here? with help from winbind? 
                   or retrieve from NTFS stream extended attribute */
-               if (atomic_read(&cifsInfo->inUse) == 0) {
+               if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
+                       /* fill in uid, gid, mode from server ACL */
+                       get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
+               } else if (atomic_read(&cifsInfo->inUse) == 0) {
                        inode->i_uid = cifs_sb->mnt_uid;
                        inode->i_gid = cifs_sb->mnt_gid;
                        /* set so we do not keep refreshing these fields with
@@ -377,24 +505,29 @@ int cifs_get_inode_info(struct inode **pinode,
                }
 
                if (S_ISREG(inode->i_mode)) {
-                       cFYI(1, (" File inode "));
+                       cFYI(1, ("File inode"));
                        inode->i_op = &cifs_file_inode_ops;
-                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
-                               inode->i_fop = &cifs_file_direct_ops;
-                       else
+                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
+                               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                                       inode->i_fop =
+                                               &cifs_file_direct_nobrl_ops;
+                               else
+                                       inode->i_fop = &cifs_file_direct_ops;
+                       } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                               inode->i_fop = &cifs_file_nobrl_ops;
+                       else /* not direct, send byte range locks */
                                inode->i_fop = &cifs_file_ops;
-                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
-                               inode->i_fop->lock = NULL;
+
                        inode->i_data.a_ops = &cifs_addr_ops;
                        if(pTcon->ses->server->maxBuf < 
                             4096 + MAX_CIFS_HDR_SIZE)
                                inode->i_data.a_ops->readpages = NULL;
                } else if (S_ISDIR(inode->i_mode)) {
-                       cFYI(1, (" Directory inode "));
+                       cFYI(1, ("Directory inode"));
                        inode->i_op = &cifs_dir_inode_ops;
                        inode->i_fop = &cifs_dir_ops;
                } else if (S_ISLNK(inode->i_mode)) {
-                       cFYI(1, (" Symbolic Link inode "));
+                       cFYI(1, ("Symbolic Link inode"));
                        inode->i_op = &cifs_symlink_inode_ops;
                } else {
                        init_special_inode(inode, inode->i_mode,
@@ -431,7 +564,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
        struct cifsInodeInfo *cifsInode;
        FILE_BASIC_INFO *pinfo_buf;
 
-       cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode));
+       cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode));
 
        xid = GetXid();
 
@@ -651,7 +784,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
        char *full_path = NULL;
        struct cifsInodeInfo *cifsInode;
 
-       cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode));
+       cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode));
 
        xid = GetXid();
 
@@ -970,7 +1103,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 
        xid = GetXid();
 
-       cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ",
+       cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
                 direntry->d_name.name, attrs->ia_valid));
        cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
        pTcon = cifs_sb->tcon;
@@ -1086,6 +1219,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                                         cifs_sb->mnt_cifs_flags & 
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
        else if (attrs->ia_valid & ATTR_MODE) {
+               rc = 0;
                if ((mode & S_IWUGO) == 0) /* not writeable */ {
                        if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
                                time_buf.Attributes =
index 34a06692e4fa9461e624e8ace35de0536d4240d9..ca27a82c54cdb60f4083b21ba427aa004c43ceb7 100644 (file)
@@ -678,7 +678,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
        __u16 temp;
 
        if(!mapChars) 
-               return cifs_strtoUCS((wchar_t *) target, source, PATH_MAX, cp);
+               return cifs_strtoUCS(target, source, PATH_MAX, cp);
 
        for(i = 0, j = 0; i < maxlen; j++) {
                src_char = source[i];
index a86bd1c076021bb88bec0da95a4d939b0785d69d..9bdaaecae36f683ef52196b4d54cee256b006029 100644 (file)
@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
                tmp_inode->i_gid = cifs_sb->mnt_gid;
                /* set default mode. will override for dirs below */
                tmp_inode->i_mode = cifs_sb->mnt_file_mode;
+       } else {
+               /* mask off the type bits since it gets set
+               below and we do not want to get two type
+               bits set */
+               tmp_inode->i_mode &= ~S_IFMT;
        }
 
        if (attr & ATTR_DIRECTORY) {
@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
                }
                tmp_inode->i_mode |= S_IFDIR;
        } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 
-                  (attr & ATTR_SYSTEM) && (end_of_file == 0)) {
-               *pobject_type = DT_FIFO;
-               tmp_inode->i_mode |= S_IFIFO;
-/* BB Finish for SFU style symlinks and devies */
-/*     } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
-               (attr & ATTR_SYSTEM) && ) { */
+                  (attr & ATTR_SYSTEM)) {
+               if (end_of_file == 0)  {
+                       *pobject_type = DT_FIFO;
+                       tmp_inode->i_mode |= S_IFIFO;
+               } else {
+                       /* rather than get the type here, we mark the
+                       inode as needing revalidate and get the real type
+                       (blk vs chr vs. symlink) later ie in lookup */
+                       *pobject_type = DT_REG;
+                       tmp_inode->i_mode |= S_IFREG; 
+                       cifsInfo->time = 0;     
+               }
 /* we no longer mark these because we could not follow them */
 /*        } else if (attr & ATTR_REPARSE) {
                 *pobject_type = DT_LNK;
@@ -193,8 +204,14 @@ static void fill_in_inode(struct inode *tmp_inode,
        if (S_ISREG(tmp_inode->i_mode)) {
                cFYI(1, ("File inode"));
                tmp_inode->i_op = &cifs_file_inode_ops;
-               if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
-                       tmp_inode->i_fop = &cifs_file_direct_ops;
+               if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
+                       if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                               tmp_inode->i_fop = &cifs_file_direct_nobrl_ops;
+                       else
+                               tmp_inode->i_fop = &cifs_file_direct_ops;
+               
+               } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                       tmp_inode->i_fop = &cifs_file_nobrl_ops;
                else
                        tmp_inode->i_fop = &cifs_file_ops;
                if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
@@ -258,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
            cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
 
        tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
+       /* since we set the inode type below we need to mask off type
+           to avoid strange results if bits above were corrupt */
+        tmp_inode->i_mode &= ~S_IFMT;
        if (type == UNIX_FILE) {
                *pobject_type = DT_REG;
                tmp_inode->i_mode |= S_IFREG;
@@ -283,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
        } else if (type == UNIX_SOCKET) {
                *pobject_type = DT_SOCK;
                tmp_inode->i_mode |= S_IFSOCK;
+       } else {
+               /* safest to just call it a file */
+               *pobject_type = DT_REG;
+               tmp_inode->i_mode |= S_IFREG;
+               cFYI(1,("unknown inode type %d",type)); 
        }
 
        tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
@@ -699,7 +724,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
                                        (__le16 *)filename, len/2, nlt);
                else
                        pqst->len = cifs_strfromUCS_le((char *)pqst->name,
-                                       (wchar_t *)filename,len/2,nlt);
+                                       (__le16 *)filename,len/2,nlt);
        } else {
                pqst->name = filename;
                pqst->len = len;
index 981ea0d8b9cdaa4b06f53f7fdae975b41a1bffa6..41a9659c16bc691552374bc1c83ea8d0fcd8209f 100644 (file)
@@ -522,7 +522,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
                            sizeof (struct smb_hdr) -
                            4 /* do not count RFC1001 header */  +
                            (2 * in_buf->WordCount) + 2 /* bcc */ )
-                               BCC(in_buf) = le16_to_cpu(BCC(in_buf));
+                               BCC(in_buf) = le16_to_cpu(BCC_LE(in_buf));
                } else {
                        rc = -EIO;
                        cFYI(1,("Bad MID state?"));
@@ -786,7 +786,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                            sizeof (struct smb_hdr) -
                            4 /* do not count RFC1001 header */  +
                            (2 * out_buf->WordCount) + 2 /* bcc */ )
-                               BCC(out_buf) = le16_to_cpu(BCC(out_buf));
+                               BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
                } else {
                        rc = -EIO;
                        cERROR(1,("Bad MID state? "));
index 8e71cdbecc7c78cc18f2e14f758b8493e767a07c..0f7abf246d32c80a6f2c8525809d59082ec35f9f 100644 (file)
@@ -268,7 +268,6 @@ out:
 
 #define IOCTL_HASHSIZE 256
 static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
-static DECLARE_RWSEM(ioctl32_sem);
 
 extern struct ioctl_trans ioctl_start[];
 extern int ioctl_table_size;
@@ -390,14 +389,10 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
                break;
        }
 
-       /* When register_ioctl32_conversion is finally gone remove
-          this lock! -AK */
-       down_read(&ioctl32_sem);
        for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
                if (t->cmd == cmd)
                        goto found_handler;
        }
-       up_read(&ioctl32_sem);
 
        if (S_ISSOCK(filp->f_dentry->d_inode->i_mode) &&
            cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
@@ -417,11 +412,9 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
                lock_kernel();
                error = t->handler(fd, cmd, arg, filp);
                unlock_kernel();
-               up_read(&ioctl32_sem);
                goto out_fput;
        }
 
-       up_read(&ioctl32_sem);
  do_ioctl:
        error = vfs_ioctl(filp, fd, cmd, arg);
  out_fput:
index 991c00de5c4e8aa7f429abcc7566c4982d4d5c32..43a2508ac69670d972516a0f5d2ad96f8e7bfa02 100644 (file)
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
 #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
 #define EXT3_IOC32_GETVERSION             _IOR('f', 3, int)
-#define EXT3_IOC32_SETVERSION             _IOR('f', 4, int)
+#define EXT3_IOC32_SETVERSION             _IOW('f', 4, int)
 #define EXT3_IOC32_GETRSVSZ               _IOR('f', 5, int)
 #define EXT3_IOC32_SETRSVSZ               _IOW('f', 6, int)
 #define EXT3_IOC32_GROUP_EXTEND           _IOW('f', 7, unsigned int)
@@ -686,7 +686,8 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
 
        ifr = ifc.ifc_req;
        ifr32 = compat_ptr(ifc32.ifcbuf);
-       for (i = 0, j = 0; i < ifc32.ifc_len && j < ifc.ifc_len;
+       for (i = 0, j = 0;
+             i + sizeof (struct ifreq32) < ifc32.ifc_len && j < ifc.ifc_len;
             i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) {
                if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32)))
                        return -EFAULT;
@@ -702,10 +703,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg)
                i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
                ifc32.ifc_len = i;
        } else {
-               if (i <= ifc32.ifc_len)
-                       ifc32.ifc_len = i;
-               else
-                       ifc32.ifc_len = i - sizeof (struct ifreq32);
+               ifc32.ifc_len = i;
        }
        if (copy_to_user(compat_ptr(arg), &ifc32, sizeof(struct ifconf32)))
                return -EFAULT;
index 68e04c0bb3f74db0ff1baf18bcc49ef1044b9b81..ae048441c9edbcf13458ce6c9da6bbce36233157 100644 (file)
@@ -64,7 +64,7 @@ void __writel(u32 val, void __iomem *addr);
 #define writew(v,b)            __writew(v,b)
 #define writel(v,b)            __writel(v,b)
 
-#define __arch_ioremap(cookie,sz,c,a)  ((void __iomem *)(cookie))
+#define __arch_ioremap(cookie,sz,c)    ((void __iomem *)(cookie))
 #define __arch_iounmap(cookie)         do { } while (0)
 
 extern void insb(unsigned int port, void *buf, int sz);
index 688f7f90d93e6f323ea6c0ea2a6b46184bb2fcb8..942b622455bc438ad2a164580ce190c03bcdeea4 100644 (file)
@@ -59,11 +59,10 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
  * fallback to the default.
  */
 static inline void __iomem *
-__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags, unsigned long align)
+__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags)
 {
-       extern void __iomem * __ioremap(unsigned long, size_t, unsigned long, unsigned long);
        if((addr < 0x48000000) || (addr > 0x4fffffff))
-               return __ioremap(addr, size, flags, align);
+               return __ioremap(addr, size, flags);
 
        return (void *)addr;
 }
@@ -71,13 +70,11 @@ __ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags, unsigned
 static inline void
 __ixp4xx_iounmap(void __iomem *addr)
 {
-       extern void __iounmap(void __iomem *addr);
-
        if ((u32)addr >= VMALLOC_START)
                __iounmap(addr);
 }
 
-#define __arch_ioremap(a, s, f, x)     __ixp4xx_ioremap(a, s, f, x)
+#define __arch_ioremap(a, s, f)                __ixp4xx_ioremap(a, s, f)
 #define        __arch_iounmap(a)               __ixp4xx_iounmap(a)
 
 #define        writeb(v, p)                    __ixp4xx_writeb(v, p)
index 2b149ed59149de6eb8c2b71f89a5094d2c6b0bda..9444958bec1e793b57a98160c12a8c7f50bfea0c 100644 (file)
@@ -47,6 +47,7 @@
  * Queue Manager
  */
 #define IXP4XX_QMGR_BASE_PHYS          (0x60000000)
+#define IXP4XX_QMGR_REGION_SIZE                (0x00004000)
 
 /*
  * Expansion BUS Configuration registers
index 71770aa6389feb9eedcf0884f421bb0fc9cd8bf9..dc726ffccebd862c84237a6561d869f5db0645de 100644 (file)
 #define UART011_ICR            0x44    /* Interrupt clear register. */
 #define UART011_DMACR          0x48    /* DMA control register. */
 
+#define UART011_DR_OE          (1 << 11)
+#define UART011_DR_BE          (1 << 10)
+#define UART011_DR_PE          (1 << 9)
+#define UART011_DR_FE          (1 << 8)
+
 #define UART01x_RSR_OE                 0x08
 #define UART01x_RSR_BE                 0x04
 #define UART01x_RSR_PE                 0x02
index 2e6799632f124ff6e43d86cddfec5dec1aa7ad89..ae69db4a101057ff28fb4ee04a8dbc2b143ed067 100644 (file)
@@ -54,6 +54,12 @@ extern void __raw_readsl(void __iomem *addr, void *data, int longlen);
 #define __raw_readw(a)         (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
 #define __raw_readl(a)         (__chk_io_ptr(a), *(volatile unsigned int __force   *)(a))
 
+/*
+ * Architecture ioremap implementation.
+ */
+extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
+extern void __iounmap(void __iomem *addr);
+
 /*
  * Bad read/write accesses...
  */
@@ -256,18 +262,15 @@ out:
  * ioremap takes a PCI memory address, as specified in
  * Documentation/IO-mapping.txt.
  */
-extern void __iomem * __ioremap(unsigned long, size_t, unsigned long, unsigned long);
-extern void __iounmap(void __iomem *addr);
-
 #ifndef __arch_ioremap
-#define ioremap(cookie,size)           __ioremap(cookie,size,0,1)
-#define ioremap_nocache(cookie,size)   __ioremap(cookie,size,0,1)
-#define ioremap_cached(cookie,size)    __ioremap(cookie,size,L_PTE_CACHEABLE,1)
+#define ioremap(cookie,size)           __ioremap(cookie,size,0)
+#define ioremap_nocache(cookie,size)   __ioremap(cookie,size,0)
+#define ioremap_cached(cookie,size)    __ioremap(cookie,size,L_PTE_CACHEABLE)
 #define iounmap(cookie)                        __iounmap(cookie)
 #else
-#define ioremap(cookie,size)           __arch_ioremap((cookie),(size),0,1)
-#define ioremap_nocache(cookie,size)   __arch_ioremap((cookie),(size),0,1)
-#define ioremap_cached(cookie,size)    __arch_ioremap((cookie),(size),L_PTE_CACHEABLE,1)
+#define ioremap(cookie,size)           __arch_ioremap((cookie),(size),0)
+#define ioremap_nocache(cookie,size)   __arch_ioremap((cookie),(size),0)
+#define ioremap_cached(cookie,size)    __arch_ioremap((cookie),(size),L_PTE_CACHEABLE)
 #define iounmap(cookie)                        __arch_iounmap(cookie)
 #endif
 
index 5d2a1034a02ef331089c94f514e21f11296d138c..8df36818ebc9d2897d3bee39bc6751ec5be4eb0e 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef __ASM_ARM_NUMNODES_H
 #define __ASM_ARM_NUMNODES_H
 
+#include <asm/memory.h>
+
 #ifndef NODES_SHIFT
 # define NODES_SHIFT   2       /* Normally, Max 4 Nodes */
 #endif
index a2fdad0138b3e5bf2e7e2500e97a8821fe7b036e..064f0f5e8e2b9e3361082dbc420b2e6248263c40 100644 (file)
@@ -100,7 +100,6 @@ static inline void set_fs (mm_segment_t fs)
 extern int __get_user_1(void *);
 extern int __get_user_2(void *);
 extern int __get_user_4(void *);
-extern int __get_user_8(void *);
 extern int __get_user_bad(void);
 
 #define __get_user_x(__r2,__p,__e,__s,__i...)                          \
@@ -114,7 +113,7 @@ extern int __get_user_bad(void);
 #define get_user(x,p)                                                  \
        ({                                                              \
                const register typeof(*(p)) __user *__p asm("r0") = (p);\
-               register typeof(*(p)) __r2 asm("r2");                   \
+               register unsigned int __r2 asm("r2");                   \
                register int __e asm("r0");                             \
                switch (sizeof(*(__p))) {                               \
                case 1:                                                 \
@@ -126,12 +125,9 @@ extern int __get_user_bad(void);
                case 4:                                                 \
                        __get_user_x(__r2, __p, __e, 4, "lr");          \
                        break;                                          \
-               case 8:                                                 \
-                       __get_user_x(__r2, __p, __e, 8, "lr");          \
-                       break;                                          \
                default: __e = __get_user_bad(); break;                 \
                }                                                       \
-               x = __r2;                                               \
+               x = (typeof(*(p))) __r2;                                \
                __e;                                                    \
        })
 
index 3f7564dc0aa9bf052b6fee3a20791d4ac7ebb811..2a8b0d92a5d62f139ec98cb0e125883c7e39e122 100644 (file)
@@ -56,6 +56,7 @@
 #define  SN_SAL_BUS_CONFIG                        0x02000037
 #define  SN_SAL_SYS_SERIAL_GET                    0x02000038
 #define  SN_SAL_PARTITION_SERIAL_GET              0x02000039
+#define  SN_SAL_SYSCTL_PARTITION_GET               0x0200003a
 #define  SN_SAL_SYSTEM_POWER_DOWN                 0x0200003b
 #define  SN_SAL_GET_MASTER_BASEIO_NASID                   0x0200003c
 #define  SN_SAL_COHERENCE                          0x0200003d
@@ -580,6 +581,21 @@ sn_partition_serial_number_val(void) {
        return sn_partition_serial_number;
 }
 
+/*
+ * Returns the partition id of the nasid passed in as an argument,
+ * or INVALID_PARTID if the partition id cannot be retrieved.
+ */
+static inline partid_t
+ia64_sn_sysctl_partition_get(nasid_t nasid)
+{
+       struct ia64_sal_retval ret_stuff;
+       SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
+               0, 0, 0, 0, 0, 0);
+       if (ret_stuff.status != 0)
+           return -1;
+       return ((partid_t)ret_stuff.v0);
+}
+
 /*
  * Returns the physical address of the partition's reserved page through
  * an iterative number of calls.
@@ -1018,6 +1034,24 @@ ia64_sn_get_sn_info(int fc, u8 *shubtype, u16 *nasid_bitmask, u8 *nasid_shift,
        ret_stuff.v2 = 0;
        SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0);
 
+/***** BEGIN HACK - temp til old proms no longer supported ********/
+       if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
+               int nasid = get_sapicid() & 0xfff;;
+#define SH_SHUB_ID_NODES_PER_BIT_MASK 0x001f000000000000UL
+#define SH_SHUB_ID_NODES_PER_BIT_SHFT 48
+               if (shubtype) *shubtype = 0;
+               if (nasid_bitmask) *nasid_bitmask = 0x7ff;
+               if (nasid_shift) *nasid_shift = 38;
+               if (systemsize) *systemsize = 10;
+               if (sharing_domain_size) *sharing_domain_size = 8;
+               if (partid) *partid = ia64_sn_sysctl_partition_get(nasid);
+               if (coher) *coher = nasid >> 9;
+               if (reg) *reg = (HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_SHUB_ID)) & SH_SHUB_ID_NODES_PER_BIT_MASK) >>
+                       SH_SHUB_ID_NODES_PER_BIT_SHFT;
+               return 0;
+       }
+/***** END HACK *******/
+
        if (ret_stuff.status < 0)
                return ret_stuff.status;
 
index 22879853e46cb47eb4ea02de11d5d9ebc3e97fd9..ecaddf960086faa9efa10673c30ac25e67483fc5 100644 (file)
@@ -1,22 +1,10 @@
-/**************************************************************************
- *                                                                        *
- *  Unpublished copyright (c) 2005, Silicon Graphics, Inc.                *
- *  THIS IS UNPUBLISHED CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF SGI.  *
- *                                                                        *
- *  The copyright notice above does  not evidence any actual or intended  *
- *  publication  or  disclosure  of  this source  code,  which  includes  *
- *  information that is confidential  and/or proprietary, and is a trade  *
- *  secret, of  Silicon Graphics, Inc.   ANY REPRODUCTION, MODIFICATION,  *
- *  DISTRIBUTION, PUBLIC  PERFORMANCE, OR  PUBLIC DISPLAY OF  OR THROUGH  *
- *  USE  OF THIS  SOURCE CODE  WITHOUT  THE EXPRESS  WRITTEN CONSENT  OF  *
- *  SILICON GRAPHICS, INC.  IS  STRICTLY PROHIBITED, AND IN VIOLATION OF  *
- *  APPLICABLE  LAWS   AND  INTERNATIONAL  TREATIES.    THE  RECEIPT  OR  *
- *  POSSESSION OF  THIS SOURCE CODE AND/OR RELATED  INFORMATION DOES NOT  *
- *  CONVEY OR IMPLY ANY RIGHTS  TO REPRODUCE, DISCLOSE OR DISTRIBUTE ITS  *
- *  CONTENTS,  OR TO  MANUFACTURE, USE,  OR  SELL ANYTHING  THAT IT  MAY  *
- *  DESCRIBE, IN WHOLE OR IN PART.                                        *
- *                                                                        *
- **************************************************************************/
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
+ */
 
 #ifndef __ASM_IA64_SN_TIOCE_H__
 #define __ASM_IA64_SN_TIOCE_H__
index 7f63dec0a79a968256c272df1caeaf5a951029eb..cb414908671d1d77e0f729a925c94a3ffa86a560 100644 (file)
@@ -1,13 +1,10 @@
-/**************************************************************************
- *             Copyright (C) 2005, Silicon Graphics, Inc.                 *
- *                                                                       *
- *  These coded instructions, statements, and computer programs         contain  *
- *  unpublished         proprietary  information of Silicon Graphics, Inc., and  *
- *  are protected by Federal copyright law.  They  may not be disclosed  *
- *  to third  parties  or copied or duplicated in any form, in whole or  *
- *  in part, without the prior written consent of Silicon Graphics, Inc.  *
- *                                                                       *
- **************************************************************************/
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
+ */
 
 #ifndef _ASM_IA64_SN_CE_PROVIDER_H
 #define _ASM_IA64_SN_CE_PROVIDER_H
index f876bdf220569f0f90eaec0436665a8bf95d1464..b0a30e2c9813b7369837a533b3673b7528dfb60c 100644 (file)
@@ -8,6 +8,7 @@
 #define _ASM_PARISC_IRQ_H
 
 #include <linux/config.h>
+#include <linux/cpumask.h>
 #include <asm/types.h>
 
 #define NO_IRQ         (-1)
@@ -49,10 +50,10 @@ extern int txn_alloc_irq(unsigned int nbits);
 extern int txn_claim_irq(int);
 extern unsigned int txn_alloc_data(unsigned int);
 extern unsigned long txn_alloc_addr(unsigned int);
+extern unsigned long txn_affinity_addr(unsigned int irq, int cpu);
 
 extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
-
-extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+extern int cpu_check_affinity(unsigned int irq, cpumask_t *dest);
 
 /* soft power switch support (power.c) */
 extern struct tasklet_struct power_tasklet;
index 9413f67a540bb24ae2b2d2866a48c3fc8dc1a37a..dbdbd2e9fdf9304e658a6ea61a56cdf8c6688e67 100644 (file)
@@ -29,6 +29,7 @@ extern cpumask_t cpu_online_map;
 #define cpu_logical_map(cpu)   (cpu)
 
 extern void smp_send_reschedule(int cpu);
+extern void smp_send_all_nop(void);
 
 #endif /* !ASSEMBLY */
 
@@ -53,7 +54,11 @@ extern unsigned long cpu_present_mask;
 
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
-#endif /* CONFIG_SMP */
+#else /* CONFIG_SMP */
+
+static inline void smp_send_all_nop(void) { return; }
+
+#endif
 
 #define NO_PROC_ID             0xFF            /* No processor magic marker */
 #define ANY_PROC_ID            0xFF            /* Any processor magic marker */
index 7c3f406a746a4f0984b07efc40e533b24d076561..16c2ac075fc5248973f578133376a41857dbd5a6 100644 (file)
@@ -11,18 +11,25 @@ static inline int __raw_spin_is_locked(raw_spinlock_t *x)
        return *a == 0;
 }
 
-#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_spin_lock(lock) __raw_spin_lock_flags(lock, 0)
 #define __raw_spin_unlock_wait(x) \
                do { cpu_relax(); } while (__raw_spin_is_locked(x))
 
-static inline void __raw_spin_lock(raw_spinlock_t *x)
+static inline void __raw_spin_lock_flags(raw_spinlock_t *x,
+                                        unsigned long flags)
 {
        volatile unsigned int *a;
 
        mb();
        a = __ldcw_align(x);
        while (__ldcw(a) == 0)
-               while (*a == 0);
+               while (*a == 0)
+                       if (flags & PSW_SM_I) {
+                               local_irq_enable();
+                               cpu_relax();
+                               local_irq_disable();
+                       } else
+                               cpu_relax();
        mb();
 }
 
@@ -60,26 +67,20 @@ static inline int __raw_spin_trylock(raw_spinlock_t *x)
 
 static  __inline__ void __raw_read_lock(raw_rwlock_t *rw)
 {
-       unsigned long flags;
-       local_irq_save(flags);
        __raw_spin_lock(&rw->lock);
 
        rw->counter++;
 
        __raw_spin_unlock(&rw->lock);
-       local_irq_restore(flags);
 }
 
 static  __inline__ void __raw_read_unlock(raw_rwlock_t *rw)
 {
-       unsigned long flags;
-       local_irq_save(flags);
        __raw_spin_lock(&rw->lock);
 
        rw->counter--;
 
        __raw_spin_unlock(&rw->lock);
-       local_irq_restore(flags);
 }
 
 /* write_lock is less trivial.  We optimistically grab the lock and check
index e97aa8d1eff5f99bf84596d64602e252c356ff71..c9ec39c6fc6cf8b098f41058b4ab456f803ee80f 100644 (file)
  * N class systems, only one PxTLB inter processor broadcast can be
  * active at any one time on the Merced bus.  This tlb purge
  * synchronisation is fairly lightweight and harmless so we activate
- * it on all SMP systems not just the N class. */
-#ifdef CONFIG_SMP
+ * it on all SMP systems not just the N class.  We also need to have
+ * preemption disabled on uniprocessor machines, and spin_lock does that
+ * nicely.
+ */
 extern spinlock_t pa_tlb_lock;
 
 #define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
 #define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
 
-#else
-
-#define purge_tlb_start(x) do { } while(0)
-#define purge_tlb_end(x) do { } while (0)
-
-#endif
-
-
 extern void flush_tlb_all(void);
 
 /*
@@ -88,7 +82,6 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
        if (npages >= 512)  /* 2MB of space: arbitrary, should be tuned */
                flush_tlb_all();
        else {
-               preempt_disable();
                mtsp(vma->vm_mm->context,1);
                purge_tlb_start();
                if (split_tlb) {
@@ -102,7 +95,6 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
                                pdtlb(start);
                                start += PAGE_SIZE;
                        }
-               preempt_enable();
                }
                purge_tlb_end();
        }
similarity index 56%
rename from include/asm-ppc/dma-mapping.h
rename to include/asm-powerpc/dma-mapping.h
index 6e9635114433a94e2a08b934487f6dd82e0b8cf5..59a80163f75fb2abac5dec482958012f784bef16 100644 (file)
@@ -1,15 +1,22 @@
 /*
- * This is based on both include/asm-sh/dma-mapping.h and
- * include/asm-ppc/pci.h
+ * Copyright (C) 2004 IBM
+ *
+ * Implements the generic device dma API for powerpc.
+ * the pci and vio busses
  */
-#ifndef __ASM_PPC_DMA_MAPPING_H
-#define __ASM_PPC_DMA_MAPPING_H
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
 
 #include <linux/config.h>
+#include <linux/types.h>
+#include <linux/cache.h>
 /* need struct page definitions */
 #include <linux/mm.h>
 #include <asm/scatterlist.h>
 #include <asm/io.h>
+#include <asm/bug.h>
+
+#define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
 
 #ifdef CONFIG_NOT_COHERENT_CACHE
 /*
@@ -24,22 +31,12 @@ extern void __dma_free_coherent(size_t size, void *vaddr);
 extern void __dma_sync(void *vaddr, size_t size, int direction);
 extern void __dma_sync_page(struct page *page, unsigned long offset,
                                 size_t size, int direction);
-#define dma_cache_inv(_start,_size) \
-       invalidate_dcache_range(_start, (_start + _size))
-#define dma_cache_wback(_start,_size) \
-       clean_dcache_range(_start, (_start + _size))
-#define dma_cache_wback_inv(_start,_size) \
-       flush_dcache_range(_start, (_start + _size))
 
 #else /* ! CONFIG_NOT_COHERENT_CACHE */
 /*
  * Cache coherent cores.
  */
 
-#define dma_cache_inv(_start,_size)            do { } while (0)
-#define dma_cache_wback(_start,_size)          do { } while (0)
-#define dma_cache_wback_inv(_start,_size)      do { } while (0)
-
 #define __dma_alloc_coherent(gfp, size, handle)        NULL
 #define __dma_free_coherent(size, addr)                do { } while (0)
 #define __dma_sync(addr, size, rw)             do { } while (0)
@@ -47,6 +44,30 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
 
 #endif /* ! CONFIG_NOT_COHERENT_CACHE */
 
+#ifdef CONFIG_PPC64
+
+extern int dma_supported(struct device *dev, u64 mask);
+extern int dma_set_mask(struct device *dev, u64 dma_mask);
+extern void *dma_alloc_coherent(struct device *dev, size_t size,
+               dma_addr_t *dma_handle, gfp_t flag);
+extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+               dma_addr_t dma_handle);
+extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+               size_t size, enum dma_data_direction direction);
+extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+               size_t size, enum dma_data_direction direction);
+extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
+               unsigned long offset, size_t size,
+               enum dma_data_direction direction);
+extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+               size_t size, enum dma_data_direction direction);
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+               enum dma_data_direction direction);
+extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+               int nhwentries, enum dma_data_direction direction);
+
+#else /* CONFIG_PPC64 */
+
 #define dma_supported(dev, mask)       (1)
 
 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
@@ -144,29 +165,27 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 /* We don't do anything here. */
 #define dma_unmap_sg(dev, sg, nents, dir)      do { } while (0)
 
-static inline void
-dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                       size_t size,
-                       enum dma_data_direction direction)
+#endif /* CONFIG_PPC64 */
+
+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(direction == DMA_NONE);
-
        __dma_sync(bus_to_virt(dma_handle), size, 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)
+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(direction == DMA_NONE);
-
        __dma_sync(bus_to_virt(dma_handle), size, direction);
 }
 
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
-                   enum dma_data_direction direction)
+static inline void dma_sync_sg_for_cpu(struct device *dev,
+               struct scatterlist *sg, int nents,
+               enum dma_data_direction direction)
 {
        int i;
 
@@ -176,9 +195,9 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
                __dma_sync_page(sg->page, sg->offset, sg->length, direction);
 }
 
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
-                   enum dma_data_direction direction)
+static inline void dma_sync_sg_for_device(struct device *dev,
+               struct scatterlist *sg, int nents,
+               enum dma_data_direction direction)
 {
        int i;
 
@@ -188,6 +207,15 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
                __dma_sync_page(sg->page, sg->offset, sg->length, direction);
 }
 
+static inline int dma_mapping_error(dma_addr_t dma_addr)
+{
+#ifdef CONFIG_PPC64
+       return (dma_addr == DMA_ERROR_CODE);
+#else
+       return 0;
+#endif
+}
+
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
 #ifdef CONFIG_NOT_COHERENT_CACHE
@@ -198,40 +226,60 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
 
 static inline int dma_get_cache_alignment(void)
 {
+#ifdef CONFIG_PPC64
+       /* no easy way to get cache size on all processors, so return
+        * the maximum possible, to be safe */
+       return (1 << L1_CACHE_SHIFT_MAX);
+#else
        /*
         * Each processor family will define its own L1_CACHE_SHIFT,
         * L1_CACHE_BYTES wraps to this, so this is always safe.
         */
        return L1_CACHE_BYTES;
+#endif
 }
 
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction direction)
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+               dma_addr_t dma_handle, unsigned long offset, size_t size,
+               enum dma_data_direction direction)
 {
        /* just sync everything for now */
        dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
 }
 
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction direction)
+static inline void dma_sync_single_range_for_device(struct device *dev,
+               dma_addr_t dma_handle, unsigned long offset, size_t size,
+               enum dma_data_direction direction)
 {
        /* just sync everything for now */
        dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
 }
 
 static inline void dma_cache_sync(void *vaddr, size_t size,
-                                 enum dma_data_direction direction)
+               enum dma_data_direction direction)
 {
+       BUG_ON(direction == DMA_NONE);
        __dma_sync(vaddr, size, (int)direction);
 }
 
-static inline int dma_mapping_error(dma_addr_t dma_addr)
-{
-       return 0;
-}
-
-#endif                         /* __ASM_PPC_DMA_MAPPING_H */
+/*
+ * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
+ */
+struct dma_mapping_ops {
+       void *          (*alloc_coherent)(struct device *dev, size_t size,
+                               dma_addr_t *dma_handle, gfp_t flag);
+       void            (*free_coherent)(struct device *dev, size_t size,
+                               void *vaddr, dma_addr_t dma_handle);
+       dma_addr_t      (*map_single)(struct device *dev, void *ptr,
+                               size_t size, enum dma_data_direction direction);
+       void            (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
+                               size_t size, enum dma_data_direction direction);
+       int             (*map_sg)(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction direction);
+       void            (*unmap_sg)(struct device *dev, struct scatterlist *sg,
+                               int nents, enum dma_data_direction direction);
+       int             (*dma_supported)(struct device *dev, u64 mask);
+       int             (*dac_dma_supported)(struct device *dev, u64 mask);
+};
+
+#endif /* _ASM_DMA_MAPPING_H */
similarity index 98%
rename from include/asm-ppc64/io.h
rename to include/asm-powerpc/io.h
index 77fc07c3c6bd1868e9fe21b75e4a28c88b795a76..48938d84d055e89086b8665879ce47810e3926d4 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef _PPC64_IO_H
-#define _PPC64_IO_H
+#ifndef _ASM_POWERPC_IO_H
+#define _ASM_POWERPC_IO_H
 
 /* 
  * This program is free software; you can redistribute it and/or
@@ -8,7 +8,10 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#include <linux/config.h>
+#ifndef CONFIG_PPC64
+#include <asm-ppc/io.h>
+#else
+
 #include <linux/compiler.h>
 #include <asm/page.h>
 #include <asm/byteorder.h>
@@ -455,4 +458,5 @@ extern int check_legacy_ioport(unsigned long base_port);
 
 #endif /* __KERNEL__ */
 
-#endif /* _PPC64_IO_H */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_IO_H */
similarity index 98%
rename from include/asm-ppc64/mmu.h
rename to include/asm-powerpc/mmu.h
index 1a7e0afa2dc6175a79d62f0db40101eb99ba8f0c..c1b4bbabbe97f4816c26261ba9488c0acfac0ccb 100644 (file)
@@ -1,3 +1,10 @@
+#ifndef _ASM_POWERPC_MMU_H_
+#define _ASM_POWERPC_MMU_H_
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/mmu.h>
+#else
+
 /*
  * PowerPC memory management structures
  *
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifndef _PPC64_MMU_H_
-#define _PPC64_MMU_H_
-
-#include <linux/config.h>
 #include <asm/asm-compat.h>
 #include <asm/page.h>
 
@@ -392,4 +395,5 @@ static inline unsigned long get_vsid(unsigned long context, unsigned long ea)
 
 #endif /* __ASSEMBLY */
 
-#endif /* _PPC64_MMU_H_ */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_MMU_H_ */
similarity index 91%
rename from include/asm-ppc64/mmu_context.h
rename to include/asm-powerpc/mmu_context.h
index 4f512e9fa6b8fbb484fabc5b9e2d8c027d08e970..ea6798c7d5fcf84c9083d6dc082f47a69145c820 100644 (file)
@@ -1,7 +1,10 @@
-#ifndef __PPC64_MMU_CONTEXT_H
-#define __PPC64_MMU_CONTEXT_H
+#ifndef __ASM_POWERPC_MMU_CONTEXT_H
+#define __ASM_POWERPC_MMU_CONTEXT_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/mmu_context.h>
+#else
 
-#include <linux/config.h>
 #include <linux/kernel.h>      
 #include <linux/mm.h>  
 #include <asm/mmu.h>   
@@ -82,4 +85,5 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
        local_irq_restore(flags);
 }
 
-#endif /* __PPC64_MMU_CONTEXT_H */
+#endif /* CONFIG_PPC64 */
+#endif /* __ASM_POWERPC_MMU_CONTEXT_H */
similarity index 96%
rename from include/asm-ppc64/pci-bridge.h
rename to include/asm-powerpc/pci-bridge.h
index cf04327a597af1107f98f836476aa5c9b725a86e..223ec7bd81da6fb1e0c0ac07a50fb1132bc1600e 100644 (file)
@@ -1,8 +1,10 @@
-#ifdef __KERNEL__
-#ifndef _ASM_PCI_BRIDGE_H
-#define _ASM_PCI_BRIDGE_H
+#ifndef _ASM_POWERPC_PCI_BRIDGE_H
+#define _ASM_POWERPC_PCI_BRIDGE_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/pci-bridge.h>
+#else
 
-#include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/list.h>
 
@@ -147,5 +149,5 @@ extern void pcibios_free_controller(struct pci_controller *phb);
 #define PCI_PROBE_NORMAL       0       /* Do normal PCI probing */
 #define PCI_PROBE_DEVTREE      1       /* Instantiate from device tree */
 
+#endif /* CONFIG_PPC64 */
 #endif
-#endif /* __KERNEL__ */
similarity index 63%
rename from include/asm-ppc64/pci.h
rename to include/asm-powerpc/pci.h
index fafdf885a3cca595091c3520a4bde7b390b5dceb..d5934a076bd0ed68cf7485378e7a1670a7f9c0e6 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __PPC64_PCI_H
-#define __PPC64_PCI_H
+#ifndef __ASM_POWERPC_PCI_H
+#define __ASM_POWERPC_PCI_H
 #ifdef __KERNEL__
 
 /*
@@ -18,6 +18,7 @@
 #include <asm/scatterlist.h>
 #include <asm/io.h>
 #include <asm/prom.h>
+#include <asm/pci-bridge.h>
 
 #include <asm-generic/pci-dma-compat.h>
 
 
 struct pci_dev;
 
-#ifdef CONFIG_PPC_ISERIES
+/* Values for the `which' argument to sys_pciconfig_iobase syscall.  */
+#define IOBASE_BRIDGE_NUMBER   0
+#define IOBASE_MEMORY          1
+#define IOBASE_IO              2
+#define IOBASE_ISA_IO          3
+#define IOBASE_ISA_MEM         4
+
+/*
+ * Set this to 1 if you want the kernel to re-assign all PCI
+ * bus numbers
+ */
+extern int pci_assign_all_buses;
+#define pcibios_assign_all_busses()    (pci_assign_all_buses)
+
 #define pcibios_scan_all_fns(a, b)     0
-#else
-extern int pcibios_scan_all_fns(struct pci_bus *bus, int devfn);
-#endif
 
 static inline void pcibios_set_master(struct pci_dev *dev)
 {
@@ -50,6 +61,7 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
        return channel ? 15 : 14;
 }
 
+#ifdef CONFIG_PPC64
 #define HAVE_ARCH_PCI_MWI 1
 static inline int pcibios_prep_mwi(struct pci_dev *dev)
 {
@@ -64,12 +76,10 @@ static inline int pcibios_prep_mwi(struct pci_dev *dev)
        return 0;
 }
 
-extern unsigned int pcibios_assign_all_busses(void);
-
 extern struct dma_mapping_ops pci_dma_ops;
 
 /* For DAC DMA, we currently don't support it by default, but
- * we let the platform override this
+ * we let 64-bit platforms override this.
  */
 static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
 {
@@ -102,6 +112,35 @@ extern int pci_domain_nr(struct pci_bus *bus);
 /* Decide whether to display the domain number in /proc */
 extern int pci_proc_domain(struct pci_bus *bus);
 
+#else /* 32-bit */
+
+#ifdef CONFIG_PCI
+static inline void pci_dma_burst_advice(struct pci_dev *pdev,
+                                       enum pci_dma_burst_strategy *strat,
+                                       unsigned long *strategy_parameter)
+{
+       *strat = PCI_DMA_BURST_INFINITY;
+       *strategy_parameter = ~0UL;
+}
+#endif
+
+/*
+ * At present there are very few 32-bit PPC machines that can have
+ * memory above the 4GB point, and we don't support that.
+ */
+#define pci_dac_dma_supported(pci_dev, mask)   (0)
+
+/* Return the index of the PCI controller for device PDEV. */
+#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
+
+/* Set the name of the bus as it appears in /proc/bus/pci */
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+       return 0;
+}
+
+#endif /* CONFIG_PPC64 */
+
 struct vm_area_struct;
 /* Map a range of PCI memory or I/O space for a device into user space */
 int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
@@ -110,6 +149,7 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
 /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
 #define HAVE_PCI_MMAP  1
 
+#ifdef CONFIG_PPC64
 /* pci_unmap_{single,page} is not a nop, thus... */
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)      \
        dma_addr_t ADDR_NAME;
@@ -124,22 +164,40 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)          \
        (((PTR)->LEN_NAME) = (VAL))
 
-/* The PCI address space does equal the physical memory
- * address space.  The networking and block device layers use
+/* The PCI address space does not equal the physical memory address
+ * space (we have an IOMMU).  The IDE and SCSI device layers use
  * this boolean for bounce buffer decisions.
  */
 #define PCI_DMA_BUS_IS_PHYS    (0)
+
+#else /* 32-bit */
+
+/* The PCI address space does equal the physical memory
+ * address space (no IOMMU).  The IDE and SCSI device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS     (1)
+
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)         (0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)        do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)           (0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
+
+#endif /* CONFIG_PPC64 */
        
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+extern void pcibios_resource_to_bus(struct pci_dev *dev,
+                       struct pci_bus_region *region,
                        struct resource *res);
 
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+extern void pcibios_bus_to_resource(struct pci_dev *dev,
+                       struct resource *res,
                        struct pci_bus_region *region);
 
-static inline struct resource *
-pcibios_select_root(struct pci_dev *pdev, struct resource *res)
+static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
+                       struct resource *res)
 {
        struct resource *root = NULL;
 
@@ -151,14 +209,12 @@ pcibios_select_root(struct pci_dev *pdev, struct resource *res)
        return root;
 }
 
-extern int
-unmap_bus_range(struct pci_bus *bus);
+extern int unmap_bus_range(struct pci_bus *bus);
 
-extern int
-remap_bus_range(struct pci_bus *bus);
+extern int remap_bus_range(struct pci_bus *bus);
 
-extern void
-pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus);
+extern void pcibios_fixup_device_resources(struct pci_dev *dev,
+                       struct pci_bus *bus);
 
 extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
 
@@ -180,14 +236,12 @@ extern pgprot_t   pci_phys_mem_access_prot(struct file *file,
                                         unsigned long size,
                                         pgprot_t prot);
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
+#if defined(CONFIG_PPC_MULTIPLATFORM) || defined(CONFIG_PPC32)
 #define HAVE_ARCH_PCI_RESOURCE_TO_USER
 extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
                                 const struct resource *rsrc,
                                 u64 *start, u64 *end);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
+#endif /* CONFIG_PPC_MULTIPLATFORM || CONFIG_PPC32 */
 
 #endif /* __KERNEL__ */
-
-#endif /* __PPC64_PCI_H */
+#endif /* __ASM_POWERPC_PCI_H */
similarity index 95%
rename from include/asm-ppc64/pgalloc.h
rename to include/asm-powerpc/pgalloc.h
index dcf3622d19462110dda6332b30f9234feb8f16cc..bfc2113b36309b58cf93795b3081e442fade1482 100644 (file)
@@ -1,5 +1,9 @@
-#ifndef _PPC64_PGALLOC_H
-#define _PPC64_PGALLOC_H
+#ifndef _ASM_POWERPC_PGALLOC_H
+#define _ASM_POWERPC_PGALLOC_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/pgalloc.h>
+#else
 
 #include <linux/mm.h>
 #include <linux/slab.h>
@@ -148,4 +152,5 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
 
 #define check_pgt_cache()      do { } while (0)
 
-#endif /* _PPC64_PGALLOC_H */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_PGALLOC_H */
similarity index 97%
rename from include/asm-ppc64/pgtable.h
rename to include/asm-powerpc/pgtable.h
index a9783ba7fe9898f87291bc59168a7452b656b24d..0303f57366c1286ff9f1798c939f4c78a7496818 100644 (file)
@@ -1,5 +1,9 @@
-#ifndef _PPC64_PGTABLE_H
-#define _PPC64_PGTABLE_H
+#ifndef _ASM_POWERPC_PGTABLE_H
+#define _ASM_POWERPC_PGTABLE_H
+
+#ifndef CONFIG_PPC64
+#include <asm-ppc/pgtable.h>
+#else
 
 /*
  * This file contains the functions and defines necessary to modify and use
@@ -46,6 +50,13 @@ struct mm_struct;
 #define VMALLOC_SIZE  (0x80000000000UL)
 #define VMALLOC_END   (VMALLOC_START + VMALLOC_SIZE)
 
+/*
+ * Define the address range of the imalloc VM area.
+ */
+#define PHBS_IO_BASE   VMALLOC_END
+#define IMALLOC_BASE   (PHBS_IO_BASE + 0x80000000ul)   /* Reserve 2 gigs for PHBs */
+#define IMALLOC_END    (VMALLOC_START + PGTABLE_RANGE)
+
 /*
  * Common bits in a linux-style PTE.  These match the bits in the
  * (hardware-defined) PowerPC PTE as closely as possible. Additional
@@ -69,7 +80,7 @@ struct mm_struct;
 
 #define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY)
 
-/* __pgprot defined in asm-ppc64/page.h */
+/* __pgprot defined in asm-powerpc/page.h */
 #define PAGE_NONE      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
 
 #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_USER)
@@ -509,4 +520,5 @@ void pgtable_cache_init(void);
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* _PPC64_PGTABLE_H */
+#endif /* CONFIG_PPC64 */
+#endif /* _ASM_POWERPC_PGTABLE_H */
index 2e36e5a7f4f351b1dc8b4de02411ad6445857bb1..36cdc869e580146d573d5daf070f36b63028365b 100644 (file)
@@ -48,8 +48,6 @@ extern void pSeries_final_fixup(void);
 extern void pSeries_irq_bus_setup(struct pci_bus *bus);
 
 extern unsigned long pci_probe_only;
-extern unsigned long pci_assign_all_buses;
-extern int pci_read_irq_line(struct pci_dev *pci_dev);
 
 /* ---- EEH internal-use-only related routines ---- */
 #ifdef CONFIG_EEH
similarity index 80%
rename from include/asm-ppc64/spinlock.h
rename to include/asm-powerpc/spinlock.h
index 7d84fb5e39f1103d78852c7a9a3a2828f6406513..caa4b14e0e94785910d1ad188626c654b13f10dc 100644 (file)
  *
  * (the type definitions are in asm/spinlock_types.h)
  */
-#include <linux/config.h>
+#ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #include <asm/hvcall.h>
 #include <asm/iseries/hv_call.h>
+#endif
+#include <asm/asm-compat.h>
+#include <asm/synch.h>
 
 #define __raw_spin_is_locked(x)                ((x)->slock != 0)
 
+#ifdef CONFIG_PPC64
+/* use 0x800000yy when locked, where yy == CPU number */
+#define LOCK_TOKEN     (*(u32 *)(&get_paca()->lock_token))
+#else
+#define LOCK_TOKEN     1
+#endif
+
 /*
  * This returns the old value in the lock, so we succeeded
  * in getting the lock if the return value is 0.
  */
 static __inline__ unsigned long __spin_trylock(raw_spinlock_t *lock)
 {
-       unsigned long tmp, tmp2;
+       unsigned long tmp, token;
 
+       token = LOCK_TOKEN;
        __asm__ __volatile__(
-"      lwz             %1,%3(13)               # __spin_trylock\n\
-1:     lwarx           %0,0,%2\n\
+"1:    lwarx           %0,0,%2         # __spin_trylock\n\
        cmpwi           0,%0,0\n\
        bne-            2f\n\
        stwcx.          %1,0,%2\n\
        bne-            1b\n\
        isync\n\
-2:"    : "=&r" (tmp), "=&r" (tmp2)
-       : "r" (&lock->slock), "i" (offsetof(struct paca_struct, lock_token))
+2:"    : "=&r" (tmp)
+       : "r" (token), "r" (&lock->slock)
        : "cr0", "memory");
 
        return tmp;
@@ -113,11 +123,17 @@ static void __inline__ __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long
 
 static __inline__ void __raw_spin_unlock(raw_spinlock_t *lock)
 {
-       __asm__ __volatile__("lwsync    # __raw_spin_unlock": : :"memory");
+       __asm__ __volatile__(SYNC_ON_SMP"       # __raw_spin_unlock"
+                            : : :"memory");
        lock->slock = 0;
 }
 
+#ifdef CONFIG_PPC64
 extern void __raw_spin_unlock_wait(raw_spinlock_t *lock);
+#else
+#define __raw_spin_unlock_wait(lock) \
+       do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+#endif
 
 /*
  * Read-write spinlocks, allowing multiple readers
@@ -133,6 +149,14 @@ extern void __raw_spin_unlock_wait(raw_spinlock_t *lock);
 #define __raw_read_can_lock(rw)                ((rw)->lock >= 0)
 #define __raw_write_can_lock(rw)       (!(rw)->lock)
 
+#ifdef CONFIG_PPC64
+#define __DO_SIGN_EXTEND       "extsw  %0,%0\n"
+#define WRLOCK_TOKEN           LOCK_TOKEN      /* it's negative */
+#else
+#define __DO_SIGN_EXTEND
+#define WRLOCK_TOKEN           (-1)
+#endif
+
 /*
  * This returns the old value in the lock + 1,
  * so we got a read lock if the return value is > 0.
@@ -142,11 +166,12 @@ static long __inline__ __read_trylock(raw_rwlock_t *rw)
        long tmp;
 
        __asm__ __volatile__(
-"1:    lwarx           %0,0,%1         # read_trylock\n\
-       extsw           %0,%0\n\
-       addic.          %0,%0,1\n\
-       ble-            2f\n\
-       stwcx.          %0,0,%1\n\
+"1:    lwarx           %0,0,%1         # read_trylock\n"
+       __DO_SIGN_EXTEND
+"      addic.          %0,%0,1\n\
+       ble-            2f\n"
+       PPC405_ERR77(0,%1)
+"      stwcx.          %0,0,%1\n\
        bne-            1b\n\
        isync\n\
 2:"    : "=&r" (tmp)
@@ -162,18 +187,19 @@ static long __inline__ __read_trylock(raw_rwlock_t *rw)
  */
 static __inline__ long __write_trylock(raw_rwlock_t *rw)
 {
-       long tmp, tmp2;
+       long tmp, token;
 
+       token = WRLOCK_TOKEN;
        __asm__ __volatile__(
-"      lwz             %1,%3(13)       # write_trylock\n\
-1:     lwarx           %0,0,%2\n\
+"1:    lwarx           %0,0,%2 # write_trylock\n\
        cmpwi           0,%0,0\n\
-       bne-            2f\n\
-       stwcx.          %1,0,%2\n\
+       bne-            2f\n"
+       PPC405_ERR77(0,%1)
+"      stwcx.          %1,0,%2\n\
        bne-            1b\n\
        isync\n\
-2:"    : "=&r" (tmp), "=&r" (tmp2)
-       : "r" (&rw->lock), "i" (offsetof(struct paca_struct, lock_token))
+2:"    : "=&r" (tmp)
+       : "r" (token), "r" (&rw->lock)
        : "cr0", "memory");
 
        return tmp;
@@ -224,8 +250,9 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw)
        __asm__ __volatile__(
        "eieio                          # read_unlock\n\
 1:     lwarx           %0,0,%1\n\
-       addic           %0,%0,-1\n\
-       stwcx.          %0,0,%1\n\
+       addic           %0,%0,-1\n"
+       PPC405_ERR77(0,%1)
+"      stwcx.          %0,0,%1\n\
        bne-            1b"
        : "=&r"(tmp)
        : "r"(&rw->lock)
@@ -234,7 +261,8 @@ static void __inline__ __raw_read_unlock(raw_rwlock_t *rw)
 
 static __inline__ void __raw_write_unlock(raw_rwlock_t *rw)
 {
-       __asm__ __volatile__("lwsync    # write_unlock": : :"memory");
+       __asm__ __volatile__(SYNC_ON_SMP"       # write_unlock"
+                            : : :"memory");
        rw->lock = 0;
 }
 
index 2bfdf9c98459e9ee28d98ccb90c3e638f0bc69be..84ac6e258eef723750fd0b7351ee249f5b3bbbee 100644 (file)
@@ -545,6 +545,23 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
 #include <asm/mpc8260_pci9.h>
 #endif
 
+#ifdef CONFIG_NOT_COHERENT_CACHE
+
+#define dma_cache_inv(_start,_size) \
+       invalidate_dcache_range(_start, (_start + _size))
+#define dma_cache_wback(_start,_size) \
+       clean_dcache_range(_start, (_start + _size))
+#define dma_cache_wback_inv(_start,_size) \
+       flush_dcache_range(_start, (_start + _size))
+
+#else
+
+#define dma_cache_inv(_start,_size)            do { } while (0)
+#define dma_cache_wback(_start,_size)          do { } while (0)
+#define dma_cache_wback_inv(_start,_size)      do { } while (0)
+
+#endif
+
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
  * access
diff --git a/include/asm-ppc64/dma-mapping.h b/include/asm-ppc64/dma-mapping.h
deleted file mode 100644 (file)
index fb68fa2..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Copyright (C) 2004 IBM
- *
- * Implements the generic device dma API for ppc64. Handles
- * the pci and vio busses
- */
-
-#ifndef _ASM_DMA_MAPPING_H
-#define _ASM_DMA_MAPPING_H
-
-#include <linux/types.h>
-#include <linux/cache.h>
-/* need struct page definitions */
-#include <linux/mm.h>
-#include <asm/scatterlist.h>
-#include <asm/bug.h>
-
-#define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
-
-extern int dma_supported(struct device *dev, u64 mask);
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
-extern void *dma_alloc_coherent(struct device *dev, size_t size,
-               dma_addr_t *dma_handle, gfp_t flag);
-extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-               dma_addr_t dma_handle);
-extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
-               size_t size, enum dma_data_direction direction);
-extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
-               size_t size, enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
-               unsigned long offset, size_t size,
-               enum dma_data_direction direction);
-extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
-               size_t size, enum dma_data_direction direction);
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-               enum dma_data_direction direction);
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
-               int nhwentries, enum dma_data_direction 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(direction == DMA_NONE);
-       /* nothing to do */
-}
-
-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(direction == DMA_NONE);
-       /* nothing to do */
-}
-
-static inline void
-dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
-                   enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       /* nothing to do */
-}
-
-static inline void
-dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
-                      enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       /* nothing to do */
-}
-
-static inline int dma_mapping_error(dma_addr_t dma_addr)
-{
-       return (dma_addr == DMA_ERROR_CODE);
-}
-
-/* Now for the API extensions over the pci_ one */
-
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_is_consistent(d)   (1)
-
-static inline int
-dma_get_cache_alignment(void)
-{
-       /* no easy way to get cache size on all processors, so return
-        * the maximum possible, to be safe */
-       return (1 << L1_CACHE_SHIFT_MAX);
-}
-
-static inline void
-dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
-                             unsigned long offset, size_t size,
-                             enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       /* nothing to do */
-}
-
-static inline void
-dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
-                                unsigned long offset, size_t size,
-                                enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       /* nothing to do */
-}
-
-static inline void
-dma_cache_sync(void *vaddr, size_t size,
-              enum dma_data_direction direction)
-{
-       BUG_ON(direction == DMA_NONE);
-       /* nothing to do */
-}
-
-/*
- * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
- */
-struct dma_mapping_ops {
-       void *          (*alloc_coherent)(struct device *dev, size_t size,
-                               dma_addr_t *dma_handle, gfp_t flag);
-       void            (*free_coherent)(struct device *dev, size_t size,
-                               void *vaddr, dma_addr_t dma_handle);
-       dma_addr_t      (*map_single)(struct device *dev, void *ptr,
-                               size_t size, enum dma_data_direction direction);
-       void            (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
-                               size_t size, enum dma_data_direction direction);
-       int             (*map_sg)(struct device *dev, struct scatterlist *sg,
-                               int nents, enum dma_data_direction direction);
-       void            (*unmap_sg)(struct device *dev, struct scatterlist *sg,
-                               int nents, enum dma_data_direction direction);
-       int             (*dma_supported)(struct device *dev, u64 mask);
-       int             (*dac_dma_supported)(struct device *dev, u64 mask);
-};
-
-#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-ppc64/imalloc.h b/include/asm-ppc64/imalloc.h
deleted file mode 100644 (file)
index 42adf70..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _PPC64_IMALLOC_H
-#define _PPC64_IMALLOC_H
-
-/*
- * Define the address range of the imalloc VM area.
- */
-#define PHBS_IO_BASE     VMALLOC_END
-#define IMALLOC_BASE      (PHBS_IO_BASE + 0x80000000ul)        /* Reserve 2 gigs for PHBs */
-#define IMALLOC_END       (VMALLOC_START + PGTABLE_RANGE)
-
-
-/* imalloc region types */
-#define IM_REGION_UNUSED       0x1
-#define IM_REGION_SUBSET       0x2
-#define IM_REGION_EXISTS       0x4
-#define IM_REGION_OVERLAP      0x8
-#define IM_REGION_SUPERSET     0x10
-
-extern struct vm_struct * im_get_free_area(unsigned long size);
-extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
-                                     int region_type);
-extern void im_free(void *addr);
-
-extern unsigned long ioremap_bot;
-
-#endif /* _PPC64_IMALLOC_H */
index 24dc39651bc4780d5f1166e49d31c7bbfa328503..10f8b51cec8ba3e76dadcfd74a3955d7c7e350ba 100644 (file)
@@ -56,7 +56,7 @@
                       ".section __ex_table,\"a\"\n"            \
                       " .align 8\n"                            \
                       " .quad 1b,3b\n"                         \
-                      ".previous":"=&bDS" (ret__), "=a"(a), "=d"(b)\
+                      ".previous":"=&bDS" (ret__), "=a"(*(a)), "=d"(*(b))\
                       :"c"(msr), "i"(-EIO), "0"(0));           \
          ret__; })             
 
index 424d5e622b4331ba31b7cc83002a3f97aa5aec3f..6e27f42e3a57d12059800a088112b979aa7d5516 100644 (file)
@@ -10,8 +10,8 @@
 typedef struct _cciss_pci_info_struct
 {
        unsigned char   bus;
-       unsigned short  domain;
        unsigned char   dev_fn;
+       unsigned short  domain;
        __u32           board_id;
 } cciss_pci_info_struct; 
 
index b5d660089de42f8b91b420dd2cf15e1ba9d5f97d..2b54eac738ea236f3babec4fbb7b4053d2cba82a 100644 (file)
 /*
  * Define standard taskfile in/out register
  */
-#define IDE_TASKFILE_STD_OUT_FLAGS     0xFE
 #define IDE_TASKFILE_STD_IN_FLAGS      0xFE
-#define IDE_HOB_STD_OUT_FLAGS          0x3C
 #define IDE_HOB_STD_IN_FLAGS           0x3C
+#ifndef __KERNEL__
+#define IDE_TASKFILE_STD_OUT_FLAGS     0xFE
+#define IDE_HOB_STD_OUT_FLAGS          0x3C
+#endif
 
 typedef unsigned char task_ioreg_t;
 typedef unsigned long sata_ioreg_t;
index ac8b25fa6506588fef5e0640f53b48c0591ef701..a39c3c59789dafb60913744b8c143ac1fb5c2be1 100644 (file)
@@ -1089,9 +1089,11 @@ enum {
 
 /*
  * Subdrivers support.
+ *
+ * The gendriver.owner field should be set to the module owner of this driver.
+ * The gendriver.name field should be set to the name of this driver
  */
 typedef struct ide_driver_s {
-       struct module                   *owner;
        const char                      *version;
        u8                              media;
        unsigned supports_dsc_overlap   : 1;
@@ -1199,37 +1201,11 @@ extern u64 ide_get_error_location(ide_drive_t *, char *);
  */
 typedef enum {
        ide_wait,       /* insert rq at end of list, and wait for it */
-       ide_next,       /* insert rq immediately after current request */
        ide_preempt,    /* insert rq in front of current request */
        ide_head_wait,  /* insert rq in front of current request and wait for it */
        ide_end         /* insert rq at end of list, but don't wait for it */
 } ide_action_t;
 
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then the rq is queued at the end of the
- * request queue, and the function sleeps until it has been processed.
- * This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed.  This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed.  As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code.
- */
 extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
 
 /*
index 1013a42d10b15c1e82d9a7cc5d30658e55284b19..0986d19be0b7c810c122b7decbcd24dcd7a8827b 100644 (file)
@@ -940,7 +940,9 @@ unsigned long max_sane_readahead(unsigned long nr);
 
 /* Do stack extension */
 extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
+#ifdef CONFIG_IA64
 extern int expand_upwards(struct vm_area_struct *vma, unsigned long address);
+#endif
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
index e93a9ec99fc288cd919b32684aff054f2aceeb37..80b3dbacd193ea6ad6c6ce82a94b68d36a1aed78 100644 (file)
@@ -7,8 +7,6 @@
 
 #define IPT_SCTP_VALID_FLAGS           0x07
 
-#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
-
 
 struct ipt_sctp_flag_info {
        u_int8_t chunktype;
@@ -59,21 +57,21 @@ struct ipt_sctp_info {
 #define SCTP_CHUNKMAP_RESET(chunkmap)                          \
        do {                                                    \
                int i;                                          \
-               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
+               for (i = 0; i < ARRAY_SIZE(chunkmap); i++)      \
                        chunkmap[i] = 0;                        \
        } while (0)
 
 #define SCTP_CHUNKMAP_SET_ALL(chunkmap)                        \
        do {                                                    \
                int i;                                          \
-               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
+               for (i = 0; i < ARRAY_SIZE(chunkmap); i++)      \
                        chunkmap[i] = ~0;                       \
        } while (0)
 
 #define SCTP_CHUNKMAP_COPY(destmap, srcmap)                    \
        do {                                                    \
                int i;                                          \
-               for (i = 0; i < ELEMCOUNT(chunkmap); i++)       \
+               for (i = 0; i < ARRAY_SIZE(chunkmap); i++)      \
                        destmap[i] = srcmap[i];                 \
        } while (0)
 
@@ -81,7 +79,7 @@ struct ipt_sctp_info {
 ({                                                     \
        int i;                                          \
        int flag = 1;                                   \
-       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
+       for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {    \
                if (chunkmap[i]) {                      \
                        flag = 0;                       \
                        break;                          \
@@ -94,7 +92,7 @@ struct ipt_sctp_info {
 ({                                                     \
        int i;                                          \
        int flag = 1;                                   \
-       for (i = 0; i < ELEMCOUNT(chunkmap); i++) {     \
+       for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {    \
                if (chunkmap[i] != ~0) {                \
                        flag = 0;                       \
                                break;                  \
index 7b387faedb4d68e94a12c1c4ef5080e90fb3f790..1e737e269db99fbf01a5436910ae1aef99e9e075 100644 (file)
 #define PCI_DEVICE_ID_SI_961           0x0961
 #define PCI_DEVICE_ID_SI_962           0x0962
 #define PCI_DEVICE_ID_SI_963           0x0963
+#define PCI_DEVICE_ID_SI_965           0x0965
 #define PCI_DEVICE_ID_SI_5511          0x5511
 #define PCI_DEVICE_ID_SI_5513          0x5513
 #define PCI_DEVICE_ID_SI_5518          0x5518
 #define PCI_DEVICE_ID_VIA_3269_0       0x0269
 #define PCI_DEVICE_ID_VIA_K8T800PRO_0  0x0282
 #define PCI_DEVICE_ID_VIA_8363_0       0x0305
+#define PCI_DEVICE_ID_VIA_P4M800CE     0x0314
 #define PCI_DEVICE_ID_VIA_8371_0       0x0391
 #define PCI_DEVICE_ID_VIA_8501_0       0x0501
 #define PCI_DEVICE_ID_VIA_82C561       0x0561
 #define PCI_DEVICE_ID_VIA_8703_51_0    0x3148
 #define PCI_DEVICE_ID_VIA_8237_SATA    0x3149
 #define PCI_DEVICE_ID_VIA_XN266                0x3156
+#define PCI_DEVICE_ID_VIA_6410         0x3164
 #define PCI_DEVICE_ID_VIA_8754C_0      0x3168
 #define PCI_DEVICE_ID_VIA_8235         0x3177
 #define PCI_DEVICE_ID_VIA_8385_0       0x3188
index 0a8ea8b358162b00fcd4036f5a3b23ad6f668a7d..8c5d6001a923c5042b74dc1a0fc2bf6e30251f9b 100644 (file)
@@ -206,6 +206,7 @@ enum {
  *     @nfct: Associated connection, if any
  *     @ipvs_property: skbuff is owned by ipvs
  *     @nfctinfo: Relationship of this skb to the connection
+ *     @nfct_reasm: netfilter conntrack re-assembly pointer
  *     @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
  *     @tc_index: Traffic control index
  *     @tc_verd: traffic control verdict
@@ -264,16 +265,14 @@ struct sk_buff {
                                nohdr:1,
                                nfctinfo:3;
        __u8                    pkt_type:3,
-                               fclone:2;
+                               fclone:2,
+                               ipvs_property:1;
        __be16                  protocol;
 
        void                    (*destructor)(struct sk_buff *skb);
 #ifdef CONFIG_NETFILTER
        __u32                   nfmark;
        struct nf_conntrack     *nfct;
-#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
-       __u8                    ipvs_property:1;
-#endif
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
        struct sk_buff          *nfct_reasm;
 #endif
index 84876077027fb6c89643b76f9938085efdcfab86..0ff7ca68e5c53412e22c063eda26edc84381718b 100644 (file)
@@ -34,8 +34,7 @@
 #define UINPUT_BUFFER_SIZE     16
 #define UINPUT_NUM_REQUESTS    16
 
-/* state flags => bit index for {set|clear|test}_bit ops */
-#define UIST_CREATED           0
+enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED };
 
 struct uinput_request {
        int                     id;
@@ -52,11 +51,12 @@ struct uinput_request {
 
 struct uinput_device {
        struct input_dev        *dev;
-       unsigned long           state;
+       struct semaphore        sem;
+       enum uinput_state       state;
        wait_queue_head_t       waitq;
-       unsigned char           ready,
-                               head,
-                               tail;
+       unsigned char           ready;
+       unsigned char           head;
+       unsigned char           tail;
        struct input_event      buff[UINPUT_BUFFER_SIZE];
 
        struct uinput_request   *requests[UINPUT_NUM_REQUESTS];
@@ -91,6 +91,7 @@ struct uinput_ff_erase {
 #define UI_SET_SNDBIT          _IOW(UINPUT_IOCTL_BASE, 106, int)
 #define UI_SET_FFBIT           _IOW(UINPUT_IOCTL_BASE, 107, int)
 #define UI_SET_PHYS            _IOW(UINPUT_IOCTL_BASE, 108, char*)
+#define UI_SET_SWBIT           _IOW(UINPUT_IOCTL_BASE, 109, int)
 
 #define UI_BEGIN_FF_UPLOAD     _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
 #define UI_END_FF_UPLOAD       _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
index b93fd8c1d8847f6488667f60512ee3a9a70bb077..cde2f4f4f501775d968a343d75ec8a2b0859c7e5 100644 (file)
@@ -1042,7 +1042,7 @@ static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr)
        case IEEE80211_4ADDR_LEN:
                return ((struct ieee80211_hdr_4addr *)hdr)->payload;
        }
-
+       return NULL;
 }
 
 static inline int ieee80211_is_ofdm_rate(u8 rate)
index 6addb4d464d6c87b0b7d9ae2884c46e57c2e8737..0a2ad51cff8223dd1936e958a498d6dbd8644b2d 100644 (file)
@@ -237,6 +237,8 @@ extern struct ipv6_txoptions *      ipv6_renew_options(struct sock *sk, struct ipv6_t
                                                   int newtype,
                                                   struct ipv6_opt_hdr __user *newopt,
                                                   int newoptlen);
+struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
+                                         struct ipv6_txoptions *opt);
 
 extern int ip6_frag_nqueues;
 extern atomic_t ip6_frag_mem;
index 6c997b159600b89b6d6cb4b5a4059e8adf3b0e92..4f8def03428ce967d91f7a1fa738733d8a386758 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1501,7 +1501,7 @@ static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, un
  * PA-RISC uses this for its stack; IA64 for its Register Backing Store.
  * vma is the last one with address > vma->vm_end.  Have to extend vma.
  */
-#ifdef CONFIG_STACK_GROWSUP
+#ifndef CONFIG_IA64
 static inline
 #endif
 int expand_upwards(struct vm_area_struct *vma, unsigned long address)
index 079c2edff789e95ccc9fbcec96184c2eb2772e84..2841bfce29d6a5d52433d0812362eb994f1f2765 100644 (file)
@@ -116,8 +116,6 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
                        A /= X;
                        continue;
                case BPF_ALU|BPF_DIV|BPF_K:
-                       if (fentry->k == 0)
-                               return 0;
                        A /= fentry->k;
                        continue;
                case BPF_ALU|BPF_AND|BPF_X:
@@ -320,6 +318,10 @@ int sk_chk_filter(struct sock_filter *filter, int flen)
                        }
                }
 
+               /* check for division by zero   -Kris Katterjohn 2005-10-30 */
+               if (ftest->code == (BPF_ALU|BPF_DIV|BPF_K) && ftest->k == 0)
+                       return -EINVAL;
+
                /* check that memory operations use valid addresses. */
                if (ftest->k >= BPF_MEMWORDS) {
                        /* but it might not be a memory operation... */
index e0ace7cbb9960cc5d145304b7ce8bf8a8a5de2a2..8a6b2a9e458189bca3b86cc8ddc28f46ac8dd7b8 100644 (file)
@@ -46,6 +46,7 @@ atomic_t dccp_orphan_count = ATOMIC_INIT(0);
 static struct net_protocol dccp_protocol = {
        .handler        = dccp_v4_rcv,
        .err_handler    = dccp_v4_err,
+       .no_policy      = 1,
 };
 
 const char *dccp_packet_name(const int type)
index 66247f38b3716193637ab4c79020e22d9f65e1dd..705e3ce86df9534fc2c1e530d7c80320dd6e3e08 100644 (file)
@@ -2378,6 +2378,7 @@ static unsigned fib_flag_trans(int type, u32 mask, const struct fib_info *fi)
  */
 static int fib_route_seq_show(struct seq_file *seq, void *v)
 {
+       const struct fib_trie_iter *iter = seq->private;
        struct leaf *l = v;
        int i;
        char bf[128];
@@ -2389,6 +2390,8 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
                return 0;
        }
 
+       if (iter->trie == trie_local)
+               return 0;
        if (IS_TNODE(l))
                return 0;
 
index 9d3c8b5f327e8f4c546ae00cfd04e20870439a63..0bc00528d888d1d26ba9727f250bc1d2ad0ebfe0 100644 (file)
@@ -440,7 +440,7 @@ config IP_NF_MATCH_COMMENT
 config IP_NF_MATCH_CONNMARK
        tristate  'Connection mark match support'
        depends on IP_NF_IPTABLES
-       depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
+       depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
        help
          This option adds a `connmark' match, which allows you to match the
          connection mark value previously set for the session by `CONNMARK'. 
@@ -452,7 +452,7 @@ config IP_NF_MATCH_CONNMARK
 config IP_NF_MATCH_CONNBYTES
        tristate  'Connection byte/packet counter match support'
        depends on IP_NF_IPTABLES
-       depends on IP_NF_CT_ACCT || (NF_CT_ACCT && NF_CONNTRACK_IPV4)
+       depends on (IP_NF_CONNTRACK && IP_NF_CT_ACCT) || (NF_CT_ACCT && NF_CONNTRACK_IPV4)
        help
          This option adds a `connbytes' match, which allows you to match the
          number of bytes and/or packets for each direction within a connection.
@@ -767,7 +767,7 @@ config IP_NF_TARGET_TTL
 config IP_NF_TARGET_CONNMARK
        tristate  'CONNMARK target support'
        depends on IP_NF_MANGLE
-       depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
+       depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
        help
          This option adds a `CONNMARK' target, which allows one to manipulate
          the connection mark value.  Similar to the MARK target, but
@@ -779,8 +779,8 @@ config IP_NF_TARGET_CONNMARK
 
 config IP_NF_TARGET_CLUSTERIP
        tristate "CLUSTERIP target support (EXPERIMENTAL)"
-       depends on IP_NF_IPTABLES && EXPERIMENTAL
-       depends on IP_NF_CONNTRACK_MARK || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
+       depends on IP_NF_MANGLE && EXPERIMENTAL
+       depends on (IP_NF_CONNTRACK && IP_NF_CONNTRACK_MARK) || (NF_CONNTRACK_MARK && NF_CONNTRACK_IPV4)
        help
          The CLUSTERIP target allows you to build load-balancing clusters of
          network servers without having a dedicated load-balancing
index 56a09a4ac4105d69d548d0311dfbd50f7bbd8454..a16064ba0caf2bee3bcc87ffa111811d44927d60 100644 (file)
@@ -2627,7 +2627,7 @@ static void addrconf_verify(unsigned long foo)
        for (i=0; i < IN6_ADDR_HSIZE; i++) {
 
 restart:
-               write_lock(&addrconf_hash_lock);
+               read_lock(&addrconf_hash_lock);
                for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
                        unsigned long age;
 #ifdef CONFIG_IPV6_PRIVACY
@@ -2649,7 +2649,7 @@ restart:
                        if (age >= ifp->valid_lft) {
                                spin_unlock(&ifp->lock);
                                in6_ifa_hold(ifp);
-                               write_unlock(&addrconf_hash_lock);
+                               read_unlock(&addrconf_hash_lock);
                                ipv6_del_addr(ifp);
                                goto restart;
                        } else if (age >= ifp->prefered_lft) {
@@ -2668,7 +2668,7 @@ restart:
 
                                if (deprecate) {
                                        in6_ifa_hold(ifp);
-                                       write_unlock(&addrconf_hash_lock);
+                                       read_unlock(&addrconf_hash_lock);
 
                                        ipv6_ifa_notify(0, ifp);
                                        in6_ifa_put(ifp);
@@ -2686,7 +2686,7 @@ restart:
                                                in6_ifa_hold(ifp);
                                                in6_ifa_hold(ifpub);
                                                spin_unlock(&ifp->lock);
-                                               write_unlock(&addrconf_hash_lock);
+                                               read_unlock(&addrconf_hash_lock);
                                                ipv6_create_tempaddr(ifpub, ifp);
                                                in6_ifa_put(ifpub);
                                                in6_ifa_put(ifp);
@@ -2703,7 +2703,7 @@ restart:
                                spin_unlock(&ifp->lock);
                        }
                }
-               write_unlock(&addrconf_hash_lock);
+               read_unlock(&addrconf_hash_lock);
        }
 
        addr_chk_timer.expires = time_before(next, jiffies + HZ) ? jiffies + HZ : next;
index cc518405b3e1efc29b87aea3cadb4e0c6d60068f..c4a3a993acb7ba5945f422bfa27c7b97d45376e0 100644 (file)
@@ -437,7 +437,7 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
                                break;
                        case IPPROTO_AH:
                                nexthdr = ptr[0];
-                               len = (ptr[1] + 1) << 2;
+                               len = (ptr[1] + 2) << 2;
                                break;
                        default:
                                nexthdr = ptr[0];
index 922549581abc266100d6a3a28676665dd509f858..be6faf311387ce8d6f5adf1b7ec251b5b89752f2 100644 (file)
@@ -628,6 +628,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
        if (!tot_len)
                return NULL;
 
+       tot_len += sizeof(*opt2);
        opt2 = sock_kmalloc(sk, tot_len, GFP_ATOMIC);
        if (!opt2)
                return ERR_PTR(-ENOBUFS);
@@ -668,7 +669,26 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
 
        return opt2;
 out:
-       sock_kfree_s(sk, p, tot_len);
+       sock_kfree_s(sk, opt2, opt2->tot_len);
        return ERR_PTR(err);
 }
 
+struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
+                                         struct ipv6_txoptions *opt)
+{
+       /*
+        * ignore the dest before srcrt unless srcrt is being included.
+        * --yoshfuji
+        */
+       if (opt && opt->dst0opt && !opt->srcrt) {
+               if (opt_space != opt) {
+                       memcpy(opt_space, opt, sizeof(*opt_space));
+                       opt = opt_space;
+               }
+               opt->opt_nflen -= ipv6_optlen(opt->dst0opt);
+               opt->dst0opt = NULL;
+       }
+
+       return opt;
+}
+
index bbbe80cdaf72a75a463aff9551e60b31e2f69061..1cf02765fb5cae2ed7882149122dd3c9996197e4 100644 (file)
@@ -225,20 +225,16 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
                                         struct ip6_flowlabel * fl,
                                         struct ipv6_txoptions * fopt)
 {
-       struct ipv6_txoptions * fl_opt = fl ? fl->opt : NULL;
-
-       if (fopt == NULL || fopt->opt_flen == 0) {
-               if (!fl_opt || !fl_opt->dst0opt || fl_opt->srcrt)
-                       return fl_opt;
-       }
-
+       struct ipv6_txoptions * fl_opt = fl->opt;
+       
+       if (fopt == NULL || fopt->opt_flen == 0)
+               return fl_opt;
+       
        if (fl_opt != NULL) {
                opt_space->hopopt = fl_opt->hopopt;
-               opt_space->dst0opt = fl_opt->srcrt ? fl_opt->dst0opt : NULL;
+               opt_space->dst0opt = fl_opt->dst0opt;
                opt_space->srcrt = fl_opt->srcrt;
                opt_space->opt_nflen = fl_opt->opt_nflen;
-               if (fl_opt->dst0opt && !fl_opt->srcrt)
-                       opt_space->opt_nflen -= ipv6_optlen(fl_opt->dst0opt);
        } else {
                if (fopt->opt_nflen == 0)
                        return fopt;
index 8e9628f1c4c5b4bc4f1b858c339950072ad50c7c..a66900cda2afc79273b2722c9e6d755a9b8725f9 100644 (file)
@@ -748,7 +748,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        }
        if (opt == NULL)
                opt = np->opt;
-       opt = fl6_merge_options(&opt_space, flowlabel, opt);
+       if (flowlabel)
+               opt = fl6_merge_options(&opt_space, flowlabel, opt);
+       opt = ipv6_fixup_options(&opt_space, opt);
 
        fl.proto = proto;
        rawv6_probe_proto_opt(&fl, msg);
index e671153b47b250b9a7d10b2500dc15101c010fc7..5cc8731eb55b8585a75dfc97ea2226b565e75956 100644 (file)
@@ -771,7 +771,9 @@ do_udp_sendmsg:
        }
        if (opt == NULL)
                opt = np->opt;
-       opt = fl6_merge_options(&opt_space, flowlabel, opt);
+       if (flowlabel)
+               opt = fl6_merge_options(&opt_space, flowlabel, opt);
+       opt = ipv6_fixup_options(&opt_space, opt);
 
        fl->proto = IPPROTO_UDP;
        ipv6_addr_copy(&fl->fl6_dst, daddr);
index cdc8d283791c7d89388d911cf76c344e0ad04ba9..82fb07aa06a51306ce580a7c248f98b936dcabd2 100644 (file)
@@ -464,7 +464,7 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
                        const struct netem_skb_cb *cb
                                = (const struct netem_skb_cb *)skb->cb;
 
-                       if (PSCHED_TLESS(cb->time_to_send, ncb->time_to_send))
+                       if (!PSCHED_TLESS(ncb->time_to_send, cb->time_to_send))
                                break;
                }