Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 2 Nov 2006 16:51:26 +0000 (08:51 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 2 Nov 2006 16:51:26 +0000 (08:51 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6:
  jfs: Add splice support

213 files changed:
Documentation/DocBook/Makefile
Documentation/DocBook/filesystems.tmpl [new file with mode: 0644]
Documentation/DocBook/kernel-api.tmpl
Documentation/mips/time.README
Makefile
arch/cris/arch-v32/drivers/cryptocop.c
arch/i386/kernel/apm.c
arch/i386/kernel/io_apic.c
arch/ia64/kernel/mca_drv.c
arch/ia64/kernel/sal.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/smp.c
arch/mips/Kconfig
arch/mips/au1000/common/prom.c
arch/mips/au1000/common/setup.c
arch/mips/au1000/common/time.c
arch/mips/dec/time.c
arch/mips/emma2rh/common/irq_emma2rh.c
arch/mips/emma2rh/markeins/irq_markeins.c
arch/mips/emma2rh/markeins/platform.c
arch/mips/jmr3927/rbhma3100/irq.c
arch/mips/jmr3927/rbhma3100/setup.c
arch/mips/kernel/asm-offsets.c
arch/mips/kernel/entry.S
arch/mips/kernel/head.S
arch/mips/kernel/r4k_switch.S
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
arch/mips/kernel/smp-mt.c
arch/mips/kernel/smtc-asm.S
arch/mips/kernel/smtc.c
arch/mips/kernel/time.c
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/lib-64/dump_tlb.c
arch/mips/mips-boards/generic/memory.c
arch/mips/mips-boards/generic/pci.c
arch/mips/mips-boards/generic/time.c
arch/mips/mm/c-sb1.c
arch/mips/mm/pg-r4k.c
arch/mips/mm/tlbex.c
arch/mips/momentum/ocelot_g/ocelot_pld.h
arch/mips/momentum/ocelot_g/setup.c
arch/mips/oprofile/op_model_mipsxx.c
arch/mips/philips/pnx8550/common/time.c
arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
arch/mips/pmc-sierra/yosemite/smp.c
arch/mips/sgi-ip27/ip27-timer.c
arch/mips/sibyte/bcm1480/time.c
arch/mips/sibyte/sb1250/time.c
arch/mips/tx4927/common/smsc_fdc37m81x.c [new file with mode: 0644]
arch/mips/tx4927/common/tx4927_setup.c
arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/btext.c
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/perfmon_fsl_booke.c [deleted file]
arch/powerpc/kernel/pmc.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vio.c
arch/powerpc/lib/sstep.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/oprofile/Makefile
arch/powerpc/oprofile/common.c
arch/powerpc/oprofile/op_model_7450.c
arch/powerpc/oprofile/op_model_fsl_booke.c
arch/powerpc/oprofile/op_model_power4.c
arch/powerpc/oprofile/op_model_rs64.c
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/sysdev/dart.h
arch/powerpc/sysdev/dart_iommu.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/ppc/kernel/traps.c
arch/sh/boards/renesas/hs7751rvoip/setup.c
arch/sh/boards/renesas/sh7710voipgw/setup.c
arch/sh/boards/se/7300/irq.c
arch/sh/boards/se/73180/irq.c
arch/sh/boards/se/7343/irq.c
arch/sh/boards/se/770x/irq.c
arch/sh/boards/se/7751/irq.c
arch/sh/boards/sh03/setup.c
arch/sh/boards/snapgear/setup.c
arch/sh/boards/titan/setup.c
arch/sh/configs/r7780rp_defconfig
arch/sh/configs/titan_defconfig
arch/sh/drivers/dma/dma-sh.c
arch/sh/kernel/cpu/irq/ipr.c
arch/sh/kernel/cpu/irq/pint.c
arch/sh/kernel/syscalls.S
arch/sparc64/kernel/prom.c
arch/sparc64/kernel/traps.c
arch/um/Makefile
arch/um/Makefile-i386
arch/um/Makefile-x86_64
arch/um/drivers/ubd_kern.c
arch/um/include/mconsole_kern.h
arch/um/kernel/dyn.lds.S
arch/um/kernel/tt/tracer.c
arch/um/kernel/uml.lds.S
arch/um/os-Linux/sys-i386/tls.c
arch/um/os-Linux/tls.c
arch/um/sys-i386/unmap.c
arch/um/sys-x86_64/unmap.c
arch/x86_64/ia32/ia32_signal.c
block/cfq-iosched.c
block/ll_rw_blk.c
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata.h
drivers/ata/sata_nv.c
drivers/ata/sata_sis.c
drivers/bluetooth/bluecard_cs.c
drivers/ide/pci/generic.c
drivers/ieee1394/eth1394.c
drivers/isdn/gigaset/common.c
drivers/md/dm-crypt.c
drivers/message/i2o/exec-osm.c
drivers/net/Kconfig
drivers/net/arm/ep93xx_eth.c
drivers/net/au1000_eth.c
drivers/net/ehea/ehea_main.c
drivers/net/irda/stir4200.c
drivers/net/myri10ge/myri10ge.c
drivers/net/s2io.c
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/tokenring/proteon.c
drivers/net/tokenring/skisa.c
drivers/net/wan/Kconfig
drivers/net/wan/n2.c
drivers/scsi/dpt/dpti_i2o.h
drivers/scsi/imm.c
drivers/scsi/lpfc/lpfc_hbadisc.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/ppa.c
drivers/scsi/qla4xxx/Kconfig
drivers/serial/ioc4_serial.c
drivers/usb/net/usbnet.c
drivers/video/backlight/hp680_bl.c
drivers/video/offb.c
fs/block_dev.c
fs/ecryptfs/crypto.c
fs/ecryptfs/dentry.c
fs/ecryptfs/ecryptfs_kernel.h
fs/ecryptfs/file.c
fs/ecryptfs/inode.c
fs/ecryptfs/keystore.c
fs/ecryptfs/main.c
fs/ecryptfs/super.c
include/asm-i386/io_apic.h
include/asm-ia64/sal.h
include/asm-ia64/uaccess.h
include/asm-mips/asm.h
include/asm-mips/div64.h
include/asm-mips/mipsmtregs.h
include/asm-mips/pgalloc.h
include/asm-mips/pgtable-64.h
include/asm-mips/sibyte/sb1250.h
include/asm-mips/time.h
include/asm-mips/unistd.h
include/asm-powerpc/current.h
include/asm-powerpc/io.h
include/asm-powerpc/iommu.h
include/asm-powerpc/oprofile_impl.h
include/asm-powerpc/pmc.h
include/asm-powerpc/system.h
include/asm-powerpc/tce.h
include/asm-sh/irq.h
include/asm-sh/unistd.h
include/asm-sparc64/futex.h
include/asm-um/common.lds.S
include/linux/libata.h
include/linux/mtd/nand.h
include/linux/wait.h
kernel/module.c
kernel/taskstats.c
kernel/tsacct.c
net/appletalk/ddp.c
net/bridge/netfilter/ebtables.c
net/core/skbuff.c
net/dccp/ccids/ccid2.c
net/ipv4/cipso_ipv4.c
net/ipv4/ip_options.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/raw.c
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp_cong.c
net/ipv6/ip6_flowlabel.c
net/ipv6/netfilter/Kconfig
net/ipv6/netfilter/ip6_tables.c
net/ipv6/raw.c
net/ipv6/xfrm6_tunnel.c
net/netfilter/nf_conntrack_core.c
net/netlink/af_netlink.c
net/sched/sch_netem.c
net/sctp/associola.c
net/sctp/endpointola.c
net/sctp/input.c
net/sctp/protocol.c
net/sctp/socket.c
net/sunrpc/svcauth.c
net/sunrpc/svcsock.c
net/tipc/port.c
net/xfrm/xfrm_user.c
security/selinux/hooks.c
security/selinux/include/selinux_netlabel.h
security/selinux/ss/services.c

index 66e1cf733571ccc4122dcc745bf9c713ee6559b6..3bf5086574bc7a0cac90dfc6662ef59e76330167 100644 (file)
@@ -9,7 +9,7 @@
 DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
            kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
            procfs-guide.xml writing_usb_driver.xml \
-           kernel-api.xml journal-api.xml lsm.xml usb.xml \
+           kernel-api.xml filesystems.xml journal-api.xml lsm.xml usb.xml \
            gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
            genericirq.xml
 
diff --git a/Documentation/DocBook/filesystems.tmpl b/Documentation/DocBook/filesystems.tmpl
new file mode 100644 (file)
index 0000000..4785032
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+       "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="Linux-filesystems-API">
+ <bookinfo>
+  <title>Linux Filesystems API</title>
+
+  <legalnotice>
+   <para>
+     This documentation is free software; you can redistribute
+     it and/or modify it under the terms of the GNU General Public
+     License as published by the Free Software Foundation; either
+     version 2 of the License, or (at your option) any later
+     version.
+   </para>
+
+   <para>
+     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.
+   </para>
+
+   <para>
+     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
+   </para>
+
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="vfs">
+     <title>The Linux VFS</title>
+     <sect1><title>The Filesystem types</title>
+!Iinclude/linux/fs.h
+     </sect1>
+     <sect1><title>The Directory Cache</title>
+!Efs/dcache.c
+!Iinclude/linux/dcache.h
+     </sect1>
+     <sect1><title>Inode Handling</title>
+!Efs/inode.c
+!Efs/bad_inode.c
+     </sect1>
+     <sect1><title>Registration and Superblocks</title>
+!Efs/super.c
+     </sect1>
+     <sect1><title>File Locks</title>
+!Efs/locks.c
+!Ifs/locks.c
+     </sect1>
+     <sect1><title>Other Functions</title>
+!Efs/mpage.c
+!Efs/namei.c
+!Efs/buffer.c
+!Efs/bio.c
+!Efs/seq_file.c
+!Efs/filesystems.c
+!Efs/fs-writeback.c
+!Efs/block_dev.c
+     </sect1>
+  </chapter>
+
+  <chapter id="proc">
+     <title>The proc filesystem</title>
+
+     <sect1><title>sysctl interface</title>
+!Ekernel/sysctl.c
+     </sect1>
+
+     <sect1><title>proc filesystem interface</title>
+!Ifs/proc/base.c
+     </sect1>
+  </chapter>
+
+  <chapter id="sysfs">
+     <title>The Filesystem for Exporting Kernel Objects</title>
+!Efs/sysfs/file.c
+!Efs/sysfs/symlink.c
+!Efs/sysfs/bin.c
+  </chapter>
+
+  <chapter id="debugfs">
+     <title>The debugfs filesystem</title>
+
+     <sect1><title>debugfs interface</title>
+!Efs/debugfs/inode.c
+!Efs/debugfs/file.c
+     </sect1>
+  </chapter>
+
+</book>
index 2b5ac604948c8b4a80e46735d279117490a95409..a166675c4303150c7be6111f917b0f2bcd422998 100644 (file)
@@ -182,66 +182,6 @@ X!Ilib/string.c
      </sect1>
   </chapter>
 
-  <chapter id="vfs">
-     <title>The Linux VFS</title>
-     <sect1><title>The Filesystem types</title>
-!Iinclude/linux/fs.h
-     </sect1>
-     <sect1><title>The Directory Cache</title>
-!Efs/dcache.c
-!Iinclude/linux/dcache.h
-     </sect1>
-     <sect1><title>Inode Handling</title>
-!Efs/inode.c
-!Efs/bad_inode.c
-     </sect1>
-     <sect1><title>Registration and Superblocks</title>
-!Efs/super.c
-     </sect1>
-     <sect1><title>File Locks</title>
-!Efs/locks.c
-!Ifs/locks.c
-     </sect1>
-     <sect1><title>Other Functions</title>
-!Efs/mpage.c
-!Efs/namei.c
-!Efs/buffer.c
-!Efs/bio.c
-!Efs/seq_file.c
-!Efs/filesystems.c
-!Efs/fs-writeback.c
-!Efs/block_dev.c
-     </sect1>
-  </chapter>
-
-  <chapter id="proc">
-     <title>The proc filesystem</title>
-     <sect1><title>sysctl interface</title>
-!Ekernel/sysctl.c
-     </sect1>
-
-     <sect1><title>proc filesystem interface</title>
-!Ifs/proc/base.c
-     </sect1>
-  </chapter>
-
-  <chapter id="sysfs">
-     <title>The Filesystem for Exporting Kernel Objects</title>
-!Efs/sysfs/file.c
-!Efs/sysfs/symlink.c
-!Efs/sysfs/bin.c
-  </chapter>
-
-  <chapter id="debugfs">
-     <title>The debugfs filesystem</title>
-     <sect1><title>debugfs interface</title>
-!Efs/debugfs/inode.c
-!Efs/debugfs/file.c
-     </sect1>
-  </chapter>
-
   <chapter id="relayfs">
      <title>relay interface support</title>
 
index e1304b6bc48349d518472ce94e37b581ec03d521..a4ce603ed3b35876befd795576e9374f34f0b9b3 100644 (file)
@@ -38,19 +38,14 @@ The new time code provide the following services:
 
   a) Implements functions required by Linux common code:
        time_init
-       do_gettimeofday
-       do_settimeofday
 
   b) provides an abstraction of RTC and null RTC implementation as default.
        extern unsigned long (*rtc_get_time)(void);
        extern int (*rtc_set_time)(unsigned long);
 
-  c) a set of gettimeoffset functions for different CPUs and different
-     needs.
-
-  d) high-level and low-level timer interrupt routines where the timer 
-     interrupt source  may or may not be the CPU timer.  The high-level 
-     routine is dispatched through do_IRQ() while the low-level is 
+  c) high-level and low-level timer interrupt routines where the timer
+     interrupt source  may or may not be the CPU timer.  The high-level
+     routine is dispatched through do_IRQ() while the low-level is
      dispatched in assemably code (usually int-handler.S)
 
 
@@ -73,8 +68,7 @@ the following functions or values:
   c) (optional) board-specific RTC routines.
 
   d) (optional) mips_hpt_frequency - It must be definied if the board
-     is using CPU counter for timer interrupt or it is using fixed rate
-     gettimeoffset().
+     is using CPU counter for timer interrupt.
 
 
 PORTING GUIDE
@@ -89,16 +83,6 @@ Step 1: decide how you like to implement the time services.
      If the answer is no, you need a timer to provide the timer interrupt
      at 100 HZ speed.
 
-     You cannot use the fast gettimeoffset functions, i.e.,
-
-       unsigned long fixed_rate_gettimeoffset(void);
-       unsigned long calibrate_div32_gettimeoffset(void);
-       unsigned long calibrate_div64_gettimeoffset(void);
-
-    You can use null_gettimeoffset() will gives the same time resolution as
-    jiffy.  Or you can implement your own gettimeoffset (probably based on 
-    some ad hoc hardware on your machine.)
-
   c) The following sub steps assume your CPU has counter register.
      Do you plan to use the CPU counter register as the timer interrupt
      or use an exnternal timer?
@@ -123,8 +107,8 @@ Step 3: implement rtc routines, board_time_init() and plat_timer_setup()
   board_time_init() -
        a) (optional) set up RTC routines,
         b) (optional) calibrate and set the mips_hpt_frequency
-           (only needed if you intended to use fixed_rate_gettimeoffset
-            or use cpu counter as timer interrupt source)
+           (only needed if you intended to use cpu counter as timer interrupt
+            source)
 
   plat_timer_setup() -
        a) (optional) over-write any choices made above by time_init().
@@ -154,8 +138,8 @@ for some of the functions in time.c.
 For example, you may define your own timer interrupt routine, which does
 some of its own processing and then calls timer_interrupt().
 
-You can also over-ride any of the built-in functions (gettimeoffset,
-RTC routines and/or timer interrupt routine).
+You can also over-ride any of the built-in functions (RTC routines
+and/or timer interrupt routine).
 
 
 PORTING NOTES FOR SMP
@@ -187,10 +171,3 @@ You need to decide on your timer interrupt sources.
 
        You can also do the low-level version of those interrupt routines,
        following similar dispatching routes described above.
-
-Note about do_gettimeoffset():
-
-  It is very likely the CPU counter registers are not sync'ed up in a SMP box.
-  Therefore you cannot really use the many of the existing routines that
-  are based on CPU counter.  You should wirte your own gettimeoffset rouinte
-  if you want intra-jiffy resolution.
index 25b35992a02c7d66e537186ea68c469433aa43c1..95576199f3ca969ccdf6e72a3a7ea8edef1831aa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 19
-EXTRAVERSION =-rc3
+EXTRAVERSION =-rc4
 NAME=Avast! A bilge rat!
 
 # *DOCUMENTATION*
index ba096ebb0b157b4d92a425ca5a983c2612d3ac9c..2449637e6fc0ab1bad494dbec05de816f2c12d74 100644 (file)
@@ -2051,7 +2051,6 @@ static void cryptocop_job_queue_close(void)
        spin_lock_irqsave(&cryptocop_process_lock, process_flags);
 
        /* Empty the job queue. */
-       spin_lock_irqsave(&cryptocop_process_lock, process_flags);
        for (i = 0; i < cryptocop_prio_no_prios; i++){
                if (!list_empty(&(cryptocop_job_queues[i].jobs))){
                        list_for_each_safe(node, tmp, &(cryptocop_job_queues[i].jobs)) {
index 2af65858d3229b29cad60a7d25dc88a5a927bb5c..a60358fe9a49d828a69c3271459ef5f5949e2aca 100644 (file)
  *   (APM) BIOS Interface Specification, Revision 1.2, February 1996.
  *
  * [This document is available from Microsoft at:
- *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
+ *    http://www.microsoft.com/whdc/archive/amp_12.mspx]
  */
 
 #include <linux/module.h>
index 350192d6ab986f70314abb98e7e2a68a04d0b9e7..507983c513c34b60f97049eac72c8f4e2b41bea9 100644 (file)
@@ -91,6 +91,46 @@ static struct irq_pin_list {
        int apic, pin, next;
 } irq_2_pin[PIN_MAP_SIZE];
 
+struct io_apic {
+       unsigned int index;
+       unsigned int unused[3];
+       unsigned int data;
+};
+
+static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
+{
+       return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
+               + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK);
+}
+
+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+{
+       struct io_apic __iomem *io_apic = io_apic_base(apic);
+       writel(reg, &io_apic->index);
+       return readl(&io_apic->data);
+}
+
+static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+       struct io_apic __iomem *io_apic = io_apic_base(apic);
+       writel(reg, &io_apic->index);
+       writel(value, &io_apic->data);
+}
+
+/*
+ * Re-write a value: to be used for read-modify-write
+ * cycles where the read already set up the index register.
+ *
+ * Older SiS APIC requires we rewrite the index register
+ */
+static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
+{
+       volatile struct io_apic *io_apic = io_apic_base(apic);
+       if (sis_apic_bug)
+               writel(reg, &io_apic->index);
+       writel(value, &io_apic->data);
+}
+
 union entry_union {
        struct { u32 w1, w2; };
        struct IO_APIC_route_entry entry;
@@ -107,11 +147,33 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
        return eu.entry;
 }
 
+/*
+ * When we write a new IO APIC routing entry, we need to write the high
+ * word first! If the mask bit in the low word is clear, we will enable
+ * the interrupt, and we need to make sure the entry is fully populated
+ * before that happens.
+ */
 static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
 {
        unsigned long flags;
        union entry_union eu;
        eu.entry = e;
+       spin_lock_irqsave(&ioapic_lock, flags);
+       io_apic_write(apic, 0x11 + 2*pin, eu.w2);
+       io_apic_write(apic, 0x10 + 2*pin, eu.w1);
+       spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+/*
+ * When we mask an IO APIC routing entry, we need to write the low
+ * word first, in order to set the mask bit before we change the
+ * high bits!
+ */
+static void ioapic_mask_entry(int apic, int pin)
+{
+       unsigned long flags;
+       union entry_union eu = { .entry.mask = 1 };
+
        spin_lock_irqsave(&ioapic_lock, flags);
        io_apic_write(apic, 0x10 + 2*pin, eu.w1);
        io_apic_write(apic, 0x11 + 2*pin, eu.w2);
@@ -234,9 +296,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
        /*
         * Disable it in the IO-APIC irq-routing table:
         */
-       memset(&entry, 0, sizeof(entry));
-       entry.mask = 1;
-       ioapic_write_entry(apic, pin, entry);
+       ioapic_mask_entry(apic, pin);
 }
 
 static void clear_IO_APIC (void)
index a45009d2bc90149e5199a97c9eff86a8d552f5b0..afc1403799c9511505503d564c6bb30f18df0ea4 100644 (file)
@@ -434,6 +434,50 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci,
        return MCA_IS_GLOBAL;
 }
 
+/**
+ * get_target_identifier - Get the valid Cache or Bus check target identifier.
+ * @peidx:     pointer of index of processor error section
+ *
+ * Return value:
+ *     target address on Success / 0 on Failue
+ */
+static u64
+get_target_identifier(peidx_table_t *peidx)
+{
+       u64 target_address = 0;
+       sal_log_mod_error_info_t *smei;
+       pal_cache_check_info_t *pcci;
+       int i, level = 9;
+
+       /*
+        * Look through the cache checks for a valid target identifier
+        * If more than one valid target identifier, return the one
+        * with the lowest cache level.
+        */
+       for (i = 0; i < peidx_cache_check_num(peidx); i++) {
+               smei = (sal_log_mod_error_info_t *)peidx_cache_check(peidx, i);
+               if (smei->valid.target_identifier && smei->target_identifier) {
+                       pcci = (pal_cache_check_info_t *)&(smei->check_info);
+                       if (!target_address || (pcci->level < level)) {
+                               target_address = smei->target_identifier;
+                               level = pcci->level;
+                               continue;
+                       }
+               }
+       }
+       if (target_address)
+               return target_address;
+
+       /*
+        * Look at the bus check for a valid target identifier
+        */
+       smei = peidx_bus_check(peidx, 0);
+       if (smei && smei->valid.target_identifier)
+               return smei->target_identifier;
+
+       return 0;
+}
+
 /**
  * recover_from_read_error - Try to recover the errors which type are "read"s.
  * @slidx:     pointer of index of SAL error record
@@ -450,13 +494,14 @@ recover_from_read_error(slidx_table_t *slidx,
                        peidx_table_t *peidx, pal_bus_check_info_t *pbci,
                        struct ia64_sal_os_state *sos)
 {
-       sal_log_mod_error_info_t *smei;
+       u64 target_identifier;
        pal_min_state_area_t *pmsa;
        struct ia64_psr *psr1, *psr2;
        ia64_fptr_t *mca_hdlr_bh = (ia64_fptr_t*)mca_handler_bhhook;
 
        /* Is target address valid? */
-       if (!pbci->tv)
+       target_identifier = get_target_identifier(peidx);
+       if (!target_identifier)
                return fatal_mca("target address not valid");
 
        /*
@@ -487,32 +532,28 @@ recover_from_read_error(slidx_table_t *slidx,
        pmsa = sos->pal_min_state;
        if (psr1->cpl != 0 ||
           ((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) {
-               smei = peidx_bus_check(peidx, 0);
-               if (smei->valid.target_identifier) {
-                       /*
-                        *  setup for resume to bottom half of MCA,
-                        * "mca_handler_bhhook"
-                        */
-                       /* pass to bhhook as argument (gr8, ...) */
-                       pmsa->pmsa_gr[8-1] = smei->target_identifier;
-                       pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
-                       pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
-                       /* set interrupted return address (but no use) */
-                       pmsa->pmsa_br0 = pmsa->pmsa_iip;
-                       /* change resume address to bottom half */
-                       pmsa->pmsa_iip = mca_hdlr_bh->fp;
-                       pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp;
-                       /* set cpl with kernel mode */
-                       psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
-                       psr2->cpl = 0;
-                       psr2->ri  = 0;
-                       psr2->bn  = 1;
-                       psr2->i  = 0;
-
-                       return mca_recovered("user memory corruption. "
+               /*
+                *  setup for resume to bottom half of MCA,
+                * "mca_handler_bhhook"
+                */
+               /* pass to bhhook as argument (gr8, ...) */
+               pmsa->pmsa_gr[8-1] = target_identifier;
+               pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip;
+               pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr;
+               /* set interrupted return address (but no use) */
+               pmsa->pmsa_br0 = pmsa->pmsa_iip;
+               /* change resume address to bottom half */
+               pmsa->pmsa_iip = mca_hdlr_bh->fp;
+               pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp;
+               /* set cpl with kernel mode */
+               psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr;
+               psr2->cpl = 0;
+               psr2->ri  = 0;
+               psr2->bn  = 1;
+               psr2->i  = 0;
+
+               return mca_recovered("user memory corruption. "
                                "kill affected process - recovered.");
-               }
-
        }
 
        return fatal_mca("kernel context not recovered, iip 0x%lx\n",
index 642fdc7b969d5c4f6450f588e82e0f2a29064063..20bad78b5073d48ba454ee24131b01a81531861b 100644 (file)
@@ -223,12 +223,13 @@ static void __init sal_desc_ap_wakeup(void *p) { }
  */
 static int sal_cache_flush_drops_interrupts;
 
-static void __init
+void __init
 check_sal_cache_flush (void)
 {
        unsigned long flags;
        int cpu;
-       u64 vector;
+       u64 vector, cache_type = 3;
+       struct ia64_sal_retval isrv;
 
        cpu = get_cpu();
        local_irq_save(flags);
@@ -243,7 +244,10 @@ check_sal_cache_flush (void)
        while (!ia64_get_irr(IA64_TIMER_VECTOR))
                cpu_relax();
 
-       ia64_sal_cache_flush(3);
+       SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0);
+
+       if (isrv.status)
+               printk(KERN_ERR "SAL_CAL_FLUSH failed with %ld\n", isrv.status);
 
        if (ia64_get_irr(IA64_TIMER_VECTOR)) {
                vector = ia64_get_ivr();
@@ -331,7 +335,6 @@ ia64_sal_init (struct ia64_sal_systab *systab)
                p += SAL_DESC_SIZE(*p);
        }
 
-       check_sal_cache_flush();
 }
 
 int
index c4caa800349220d22b69dc25ac12e490d059c85d..d10404a4175630c6d18ccfe5aa5e265face6ec68 100644 (file)
@@ -457,6 +457,8 @@ setup_arch (char **cmdline_p)
        cpu_init();     /* initialize the bootstrap CPU */
        mmu_context_init();     /* initialize context_id bitmap */
 
+       check_sal_cache_flush();
+
 #ifdef CONFIG_ACPI
        acpi_boot_init();
 #endif
index 657ac99a451cf8d550e10d5fa52af12f130b3588..6ab95ceaf9d4f34aa32a382a9e32cb68bb98b23b 100644 (file)
@@ -108,7 +108,7 @@ cpu_die(void)
 }
 
 irqreturn_t
-handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
+handle_IPI (int irq, void *dev_id)
 {
        int this_cpu = get_cpu();
        unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
@@ -328,10 +328,14 @@ int
 smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait)
 {
        struct call_data_struct data;
-       int cpus = num_online_cpus()-1;
+       int cpus;
 
-       if (!cpus)
+       spin_lock(&call_lock);
+       cpus = num_online_cpus() - 1;
+       if (!cpus) {
+               spin_unlock(&call_lock);
                return 0;
+       }
 
        /* Can deadlock when called with interrupts disabled */
        WARN_ON(irqs_disabled());
@@ -343,8 +347,6 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai
        if (wait)
                atomic_set(&data.finished, 0);
 
-       spin_lock(&call_lock);
-
        call_data = &data;
        mb();   /* ensure store to call_data precedes setting of IPI_CALL_FUNC */
        send_IPI_allbutself(IPI_CALL_FUNC);
index 14af6cce2fa22a57d5c76fa72db3051786ab04d2..74ba7637811346c479ea3902016060afede53405 100644 (file)
@@ -408,7 +408,7 @@ config MOMENCO_OCELOT_C
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_RM7000
        select SYS_SUPPORTS_32BIT_KERNEL
-       select SYS_SUPPORTS_64BIT_KERNEL
+       select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
        select SYS_SUPPORTS_BIG_ENDIAN
        help
          The Ocelot is a MIPS-based Single Board Computer (SBC) made by
@@ -1690,6 +1690,7 @@ config NR_CPUS
        depends on SMP
        default "64" if SGI_IP27
        default "2"
+       default "8" if MIPS_MT_SMTC
        help
          This allows you to specify the maximum number of CPUs which this
          kernel will support.  The maximum supported value is 32 for 32-bit
index b4b010a2fe36d2b8947a680b903666de8b2715c2..6fce60af005dc7be1704d660d6d4ecc1fdcacd47 100644 (file)
@@ -47,7 +47,7 @@ extern int prom_argc;
 extern char **prom_argv, **prom_envp;
 
 
-char * prom_getcmdline(void)
+char * __init_or_module prom_getcmdline(void)
 {
        return &(arcs_cmdline[0]);
 }
index 377ae0d8ff0037300d30a392cf5629ea2bb1950f..919172db560cfa4d779e19fec1ae93b97aa80276 100644 (file)
@@ -43,7 +43,7 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/time.h>
 
-extern char * __init prom_getcmdline(void);
+extern char * prom_getcmdline(void);
 extern void __init board_setup(void);
 extern void au1000_restart(char *);
 extern void au1000_halt(void);
index 94f09194d63d636381cba295f41a031e3c4ac9d6..fa1c62f055156a509e2b6e5aeed75f0d7b67fa70 100644 (file)
@@ -53,9 +53,6 @@ static unsigned long r4k_cur;    /* What counter should be at next timer irq */
 int    no_au1xxx_32khz;
 extern int allow_au1k_wait; /* default off for CP0 Counter */
 
-/* Cycle counter value at the previous timer interrupt.. */
-static unsigned int timerhi = 0, timerlo = 0;
-
 #ifdef CONFIG_PM
 #if HZ < 100 || HZ > 1000
 #error "unsupported HZ value! Must be in [100,1000]"
@@ -82,7 +79,6 @@ unsigned long wtimer;
 void mips_timer_interrupt(void)
 {
        int irq = 63;
-       unsigned long count;
 
        irq_enter();
        kstat_this_cpu.irqs[irq]++;
@@ -91,10 +87,6 @@ void mips_timer_interrupt(void)
                goto null;
 
        do {
-               count = read_c0_count();
-               timerhi += (count < timerlo);   /* Wrap around */
-               timerlo = count;
-
                kstat_this_cpu.irqs[irq]++;
                do_timer(1);
 #ifndef CONFIG_SMP
@@ -231,7 +223,6 @@ wakeup_counter0_set(int ticks)
  */
 unsigned long cal_r4koff(void)
 {
-       unsigned long count;
        unsigned long cpu_speed;
        unsigned long flags;
        unsigned long counter;
@@ -258,7 +249,7 @@ unsigned long cal_r4koff(void)
 
 #if defined(CONFIG_AU1000_USE32K)
                {
-                       unsigned long start, end;
+                       unsigned long start, end, count;
 
                        start = au_readl(SYS_RTCREAD);
                        start += 2;
@@ -282,7 +273,6 @@ unsigned long cal_r4koff(void)
 #else
                cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) *
                        AU1000_SRC_CLK;
-               count = cpu_speed / 2;
 #endif
        }
        else {
@@ -291,98 +281,15 @@ unsigned long cal_r4koff(void)
                 * NOTE: some old silicon doesn't allow reading the PLL.
                 */
                cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
-               count = cpu_speed / 2;
                no_au1xxx_32khz = 1;
        }
-       mips_hpt_frequency = count;
+       mips_hpt_frequency = cpu_speed;
        // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16)
        set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
        spin_unlock_irqrestore(&time_lock, flags);
        return (cpu_speed / HZ);
 }
 
-/* This is for machines which generate the exact clock. */
-#define USECS_PER_JIFFY (1000000/HZ)
-#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff)
-
-static unsigned long
-div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
-{
-       unsigned long r0;
-       do_div64_32(r0, v1, v2, v3);
-       return r0;
-}
-
-static unsigned long do_fast_cp0_gettimeoffset(void)
-{
-       u32 count;
-       unsigned long res, tmp;
-       unsigned long r0;
-
-       /* Last jiffy when do_fast_gettimeoffset() was called. */
-       static unsigned long last_jiffies=0;
-       unsigned long quotient;
-
-       /*
-        * Cached "1/(clocks per usec)*2^32" value.
-        * It has to be recalculated once each jiffy.
-        */
-       static unsigned long cached_quotient=0;
-
-       tmp = jiffies;
-
-       quotient = cached_quotient;
-
-       if (tmp && last_jiffies != tmp) {
-               last_jiffies = tmp;
-               if (last_jiffies != 0) {
-                       r0 = div64_32(timerhi, timerlo, tmp);
-                       quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0);
-                       cached_quotient = quotient;
-               }
-       }
-
-       /* Get last timer tick in absolute kernel time */
-       count = read_c0_count();
-
-       /* .. relative to previous jiffy (32 bits is enough) */
-       count -= timerlo;
-
-       __asm__("multu\t%1,%2\n\t"
-               "mfhi\t%0"
-               : "=r" (res)
-               : "r" (count), "r" (quotient)
-               : "hi", "lo", GCC_REG_ACCUM);
-
-       /*
-        * Due to possible jiffies inconsistencies, we need to check
-        * the result so that we'll get a timer that is monotonic.
-        */
-       if (res >= USECS_PER_JIFFY)
-               res = USECS_PER_JIFFY-1;
-
-       return res;
-}
-
-#ifdef CONFIG_PM
-static unsigned long do_fast_pm_gettimeoffset(void)
-{
-       unsigned long pc0;
-       unsigned long offset;
-
-       pc0 = au_readl(SYS_TOYREAD);
-       au_sync();
-       offset = pc0 - last_pc0;
-       if (offset > 2*MATCH20_INC) {
-               printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n",
-                               (unsigned)offset, (unsigned)last_pc0,
-                               (unsigned)last_match20, (unsigned)pc0);
-       }
-       offset = (unsigned long)((offset * 305) / 10);
-       return offset;
-}
-#endif
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
        unsigned int est_freq;
@@ -420,7 +327,6 @@ void __init plat_timer_setup(struct irqaction *irq)
                unsigned int c0_status;
 
                printk("WARNING: no 32KHz clock found.\n");
-               do_gettimeoffset = do_fast_cp0_gettimeoffset;
 
                /* Ensure we get CPO_COUNTER interrupts.
                */
@@ -445,19 +351,11 @@ void __init plat_timer_setup(struct irqaction *irq)
                while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
                startup_match20_interrupt(counter0_irq);
 
-               do_gettimeoffset = do_fast_pm_gettimeoffset;
-
                /* We can use the real 'wait' instruction.
                */
                allow_au1k_wait = 1;
        }
 
-#else
-       /* We have to do this here instead of in timer_init because
-        * the generic code in arch/mips/kernel/time.c will write
-        * over our function pointer.
-        */
-       do_gettimeoffset = do_fast_cp0_gettimeoffset;
 #endif
 }
 
index 4cf0c06e2414b556d66cf5d8c212b4f28c523c0e..69e424e9ab6f61ffdd4af03bafbbb9d609cb9cd7 100644 (file)
@@ -160,11 +160,6 @@ static unsigned int dec_ioasic_hpt_read(void)
        return ioasic_read(IO_REG_FCTR);
 }
 
-static void dec_ioasic_hpt_init(unsigned int count)
-{
-       ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count);
-}
-
 
 void __init dec_time_init(void)
 {
@@ -174,11 +169,9 @@ void __init dec_time_init(void)
        mips_timer_state = dec_timer_state;
        mips_timer_ack = dec_timer_ack;
 
-       if (!cpu_has_counter && IOASIC) {
+       if (!cpu_has_counter && IOASIC)
                /* For pre-R4k systems we use the I/O ASIC's counter.  */
                mips_hpt_read = dec_ioasic_hpt_read;
-               mips_hpt_init = dec_ioasic_hpt_init;
-       }
 
        /* Set up the rate of periodic DS1287 interrupts.  */
        CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A);
index 7c930860c921e14f2a086556dda04ccc2e40a498..197ed4c2ba04d774dff5b10b3e89571c418680c6 100644 (file)
@@ -97,7 +97,7 @@ void emma2rh_irq_init(u32 irq_base)
                irq_desc[i].status = IRQ_DISABLED;
                irq_desc[i].action = NULL;
                irq_desc[i].depth = 1;
-               irq_desc[i].handler = &emma2rh_irq_controller;
+               irq_desc[i].chip = &emma2rh_irq_controller;
        }
 
        emma2rh_irq_base = irq_base;
index f23ae9fcffa0e63698c4ed23cca18fb9378b8cfc..0b36eb001e62770d920f0e8c30be0619e520ea36 100644 (file)
@@ -86,7 +86,7 @@ void emma2rh_sw_irq_init(u32 irq_base)
                irq_desc[i].status = IRQ_DISABLED;
                irq_desc[i].action = NULL;
                irq_desc[i].depth = 2;
-               irq_desc[i].handler = &emma2rh_sw_irq_controller;
+               irq_desc[i].chip = &emma2rh_sw_irq_controller;
        }
 
        emma2rh_sw_irq_base = irq_base;
@@ -166,7 +166,7 @@ void emma2rh_gpio_irq_init(u32 irq_base)
                irq_desc[i].status = IRQ_DISABLED;
                irq_desc[i].action = NULL;
                irq_desc[i].depth = 2;
-               irq_desc[i].handler = &emma2rh_gpio_irq_controller;
+               irq_desc[i].chip = &emma2rh_gpio_irq_controller;
        }
 
        emma2rh_gpio_irq_base = irq_base;
index 15cc61df36223ba8b4a543035b363c097702bfad..11567702b155460a84adcbf9b08bca3c6c280a97 100644 (file)
 #define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */
 
 static struct resource i2c_emma_resources_0[] = {
-       { NULL, EMMA2RH_IRQ_PIIC0, EMMA2RH_IRQ_PIIC0, IORESOURCE_IRQ },
-       { NULL, KSEG1ADDR(EMMA2RH_PIIC0_BASE), KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), 0 },
+       {
+               .name   = NULL,
+               .start  = EMMA2RH_IRQ_PIIC0,
+               .end    = EMMA2RH_IRQ_PIIC0,
+               .flags  = IORESOURCE_IRQ
+       }, {
+               .name   = NULL,
+               .start  = EMMA2RH_PIIC0_BASE,
+               .end    = EMMA2RH_PIIC0_BASE + 0x1000,
+               .flags  = 0
+       },
 };
 
 struct resource i2c_emma_resources_1[] = {
-       { NULL, EMMA2RH_IRQ_PIIC1, EMMA2RH_IRQ_PIIC1, IORESOURCE_IRQ },
-       { NULL, KSEG1ADDR(EMMA2RH_PIIC1_BASE), KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), 0 },
+       {
+               .name   = NULL,
+               .start  = EMMA2RH_IRQ_PIIC1,
+               .end    = EMMA2RH_IRQ_PIIC1,
+               .flags  = IORESOURCE_IRQ
+       }, {
+               .name   = NULL,
+               .start  = EMMA2RH_PIIC1_BASE,
+               .end    = EMMA2RH_PIIC1_BASE + 0x1000,
+               .flags  = 0
+       },
 };
 
 struct resource i2c_emma_resources_2[] = {
-       { NULL, EMMA2RH_IRQ_PIIC2, EMMA2RH_IRQ_PIIC2, IORESOURCE_IRQ },
-       { NULL, KSEG1ADDR(EMMA2RH_PIIC2_BASE), KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), 0 },
+       {
+               .name   = NULL,
+               .start  = EMMA2RH_IRQ_PIIC2,
+               .end    = EMMA2RH_IRQ_PIIC2,
+               .flags  = IORESOURCE_IRQ
+       }, {
+               .name   = NULL,
+               .start  = EMMA2RH_PIIC2_BASE,
+               .end    = EMMA2RH_PIIC2_BASE + 0x1000,
+               .flags  = 0
+       },
 };
 
 struct platform_device i2c_emma_devices[] = {
@@ -83,32 +110,29 @@ struct platform_device i2c_emma_devices[] = {
 #define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST
 
 static struct  plat_serial8250_port platform_serial_ports[] = {
-       [0] = {
-         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
-         .irq = EMMA2RH_IRQ_PFUR0,
-         .uartclk = EMMA2RH_SERIAL_CLOCK,
-         .regshift = 4,
-         .iotype = UPIO_MEM,
-         .flags = EMMA2RH_SERIAL_FLAGS,
-       },
-       [1] = {
-         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
-         .irq = EMMA2RH_IRQ_PFUR1,
-         .uartclk = EMMA2RH_SERIAL_CLOCK,
-         .regshift = 4,
-         .iotype = UPIO_MEM,
-         .flags = EMMA2RH_SERIAL_FLAGS,
-       },
-       [2] = {
-         .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
-         .irq = EMMA2RH_IRQ_PFUR2,
-         .uartclk = EMMA2RH_SERIAL_CLOCK,
-         .regshift = 4,
-         .iotype = UPIO_MEM,
-         .flags = EMMA2RH_SERIAL_FLAGS,
-       },
-       [3] = {
-        .flags = 0,
+       [0] = {
+               .membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3),
+               .irq = EMMA2RH_IRQ_PFUR0,
+               .uartclk = EMMA2RH_SERIAL_CLOCK,
+               .regshift = 4,
+               .iotype = UPIO_MEM,
+               .flags = EMMA2RH_SERIAL_FLAGS,
+       }, [1] = {
+               .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3),
+               .irq = EMMA2RH_IRQ_PFUR1,
+               .uartclk = EMMA2RH_SERIAL_CLOCK,
+               .regshift = 4,
+               .iotype = UPIO_MEM,
+               .flags = EMMA2RH_SERIAL_FLAGS,
+       }, [2] = {
+               .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3),
+               .irq = EMMA2RH_IRQ_PFUR2,
+               .uartclk = EMMA2RH_SERIAL_CLOCK,
+               .regshift = 4,
+               .iotype = UPIO_MEM,
+               .flags = EMMA2RH_SERIAL_FLAGS,
+       }, [3] = {
+               .flags = 0,
        },
 };
 
index 39a0243bed9ac10e13b0fea7dfe25c83f29fca74..de4a238c28bec5eb0c67bde8d937e0dddb0d5b96 100644 (file)
@@ -288,6 +288,8 @@ static void tx_branch_likely_bug_fixup(void)
 
 static void jmr3927_spurious(void)
 {
+       struct pt_regs * regs = get_irq_regs();
+
 #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
        tx_branch_likely_bug_fixup();
 #endif
@@ -297,6 +299,7 @@ static void jmr3927_spurious(void)
 
 asmlinkage void plat_irq_dispatch(void)
 {
+       struct pt_regs * regs = get_irq_regs();
        int irq;
 
 #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND
index 025434054ed09b947b43da4607a0fa0454a3e274..16e5dfe7aa8a445d79a86a9d6019c29db4d26f24 100644 (file)
@@ -170,12 +170,20 @@ static void jmr3927_machine_power_off(void)
        while (1);
 }
 
+static unsigned int jmr3927_hpt_read(void)
+{
+       /* We assume this function is called xtime_lock held. */
+       return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr;
+}
+
 #define USE_RTC_DS1742
 #ifdef USE_RTC_DS1742
 extern void rtc_ds1742_init(unsigned long base);
 #endif
 static void __init jmr3927_time_init(void)
 {
+       mips_hpt_read = jmr3927_hpt_read;
+       mips_hpt_frequency = JMR3927_TIMER_CLK;
 #ifdef USE_RTC_DS1742
        if (jmr3927_have_nvram()) {
                rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR);
@@ -183,12 +191,8 @@ static void __init jmr3927_time_init(void)
 #endif
 }
 
-unsigned long jmr3927_do_gettimeoffset(void);
-
 void __init plat_timer_setup(struct irqaction *irq)
 {
-       do_gettimeoffset = jmr3927_do_gettimeoffset;
-
        jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
        jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
        jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
@@ -200,34 +204,6 @@ void __init plat_timer_setup(struct irqaction *irq)
 
 #define USECS_PER_JIFFY (1000000/HZ)
 
-unsigned long jmr3927_do_gettimeoffset(void)
-{
-       unsigned long count;
-       unsigned long res = 0;
-
-       /* MUST read TRR before TISR. */
-       count = jmr3927_tmrptr->trr;
-
-       if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) {
-               /* timer interrupt is pending.  use Max value. */
-               res = USECS_PER_JIFFY - 1;
-       } else {
-               /* convert to usec */
-               /* res = count / (JMR3927_TIMER_CLK / 1000000); */
-               res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000);
-
-               /*
-                * Due to possible jiffies inconsistencies, we need to check
-                * the result so that we'll get a timer that is monotonic.
-                */
-               if (res >= USECS_PER_JIFFY)
-                       res = USECS_PER_JIFFY-1;
-       }
-
-       return res;
-}
-
-
 //#undef DO_WRITE_THROUGH
 #define DO_WRITE_THROUGH
 #define DO_ENABLE_CACHE
index e9ce5b3721af74d8324b45bdadf2f71ce97ac77b..ff88b06f89df9b922ab616b4826162d4e23889ad 100644 (file)
@@ -22,7 +22,7 @@
 #define offset(string, ptr, member) \
        __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
 #define constant(string, member) \
-       __asm__("\n@@@" string "%x0" : : "ri" (member))
+       __asm__("\n@@@" string "%X0" : : "ri" (member))
 #define size(string, size) \
        __asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
 #define linefeed text("")
index 417c08ac76eb52e393a617ab0a5871db07413475..f10b6a19f8bf7b672242dbf2dcf9bf1f495c7c13 100644 (file)
@@ -83,7 +83,10 @@ FEXPORT(syscall_exit)
 FEXPORT(restore_all)                   # restore full frame
 #ifdef CONFIG_MIPS_MT_SMTC
 /* Detect and execute deferred IPI "interrupts" */
+       LONG_L  s0, TI_REGS($28)
+       LONG_S  sp, TI_REGS($28)
        jal     deferred_smtc_ipi
+       LONG_S  s0, TI_REGS($28)
 /* Re-arm any temporarily masked interrupts not explicitly "acked" */
        mfc0    v0, CP0_TCSTATUS
        ori     v1, v0, TCSTATUS_IXMT
index 8c6db0fc72f0ab5cb5b326d11f9c29c737abe1e0..ddc1b71c9378745887fea0f103ab42ce9fd1d120 100644 (file)
@@ -189,7 +189,8 @@ NESTED(kernel_entry, 16, sp)                        # kernel entry point
 
        MTC0            zero, CP0_CONTEXT       # clear context register
        PTR_LA          $28, init_thread_union
-       PTR_ADDIU       sp, $28, _THREAD_SIZE - 32
+       PTR_LI          sp, _THREAD_SIZE - 32
+       PTR_ADDU        sp, $28
        set_saved_sp    sp, t0, t1
        PTR_SUBU        sp, 4 * SZREG           # init stack pointer
 
index d5c8b82fed7298c75b69a11623ff635106513b98..cc566cf122464f8672685766dd595bc8cc50cceb 100644 (file)
        move    $28, a2
        cpu_restore_nonscratch a1
 
+#if (_THREAD_SIZE - 32) < 0x10000
        PTR_ADDIU       t0, $28, _THREAD_SIZE - 32
+#else
+       PTR_LI          t0, _THREAD_SIZE - 32
+       PTR_ADDU        t0, $28
+#endif
        set_saved_sp    t0, t1, t2
 #ifdef CONFIG_MIPS_MT_SMTC
        /* Read-modify-writes of Status must be atomic on a VPE */
index 720fac3435d5aa9d49c1e2393fc476c7949c1168..a95f37de080eb563b600d0615d7e1cd62003ca07 100644 (file)
@@ -654,6 +654,8 @@ einval:     li      v0, -EINVAL
        sys     sys_set_robust_list     2
        sys     sys_get_robust_list     3       /* 4310 */
        sys     sys_ni_syscall          0
+       sys     sys_getcpu              3
+       sys     sys_epoll_pwait         6
        .endm
 
        /* We pre-compute the number of _instruction_ bytes needed to
index 3a34f62c8b1b3152b9fb3ac68911a47484eb3743..8fb0f60f657bfc469c94b35458e339563761c4a8 100644 (file)
@@ -469,3 +469,5 @@ sys_call_table:
        PTR     sys_set_robust_list
        PTR     sys_get_robust_list
        PTR     sys_ni_syscall                  /* 5270 */
+       PTR     sys_getcpu
+       PTR     sys_epoll_pwait
index 67b92a1d6c72268aa2ba12120011fd8754db4a71..0da5ca2040ff96f0487ca1ce66783e852b50f87b 100644 (file)
@@ -395,3 +395,5 @@ EXPORT(sysn32_call_table)
        PTR     compat_sys_set_robust_list
        PTR     compat_sys_get_robust_list
        PTR     sys_ni_syscall
+       PTR     sys_getcpu
+       PTR     sys_epoll_pwait
index 2875c4a3fa5801f8d5b87f1b895d91003b85f510..b9d00cae8b5f2f4c4db850f634ccbbc14370338e 100644 (file)
@@ -517,4 +517,6 @@ sys_call_table:
        PTR     compat_sys_set_robust_list
        PTR     compat_sys_get_robust_list      /* 4310 */
        PTR     sys_ni_syscall
+       PTR     sys_getcpu
+       PTR     sys_epoll_pwait
        .size   sys_call_table,.-sys_call_table
index 3b5f3b632622c852ee1e699f7af9bc7f90c610e0..2ac19a6cbf68d61d6c2b2f6e93055c8c250e0d08 100644 (file)
@@ -140,15 +140,90 @@ static struct irqaction irq_call = {
        .name           = "IPI_call"
 };
 
+static void __init smp_copy_vpe_config(void)
+{
+       write_vpe_c0_status(
+               (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
+
+       /* set config to be the same as vpe0, particularly kseg0 coherency alg */
+       write_vpe_c0_config( read_c0_config());
+
+       /* make sure there are no software interrupts pending */
+       write_vpe_c0_cause(0);
+
+       /* Propagate Config7 */
+       write_vpe_c0_config7(read_c0_config7());
+
+       write_vpe_c0_count(read_c0_count());
+}
+
+static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0,
+       unsigned int ncpu)
+{
+       if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT))
+               return ncpu;
+
+       /* Deactivate all but VPE 0 */
+       if (tc != 0) {
+               unsigned long tmp = read_vpe_c0_vpeconf0();
+
+               tmp &= ~VPECONF0_VPA;
+
+               /* master VPE */
+               tmp |= VPECONF0_MVP;
+               write_vpe_c0_vpeconf0(tmp);
+
+               /* Record this as available CPU */
+               cpu_set(tc, phys_cpu_present_map);
+               __cpu_number_map[tc]    = ++ncpu;
+               __cpu_logical_map[ncpu] = tc;
+       }
+
+       /* Disable multi-threading with TC's */
+       write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
+
+       if (tc != 0)
+               smp_copy_vpe_config();
+
+       return ncpu;
+}
+
+static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0)
+{
+       unsigned long tmp;
+
+       if (!tc)
+               return;
+
+       /* bind a TC to each VPE, May as well put all excess TC's
+          on the last VPE */
+       if (tc >= (((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1))
+               write_tc_c0_tcbind(read_tc_c0_tcbind() | ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT));
+       else {
+               write_tc_c0_tcbind(read_tc_c0_tcbind() | tc);
+
+               /* and set XTC */
+               write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (tc << VPECONF0_XTC_SHIFT));
+       }
+
+       tmp = read_tc_c0_tcstatus();
+
+       /* mark not allocated and not dynamically allocatable */
+       tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
+       tmp |= TCSTATUS_IXMT;           /* interrupt exempt */
+       write_tc_c0_tcstatus(tmp);
+
+       write_tc_c0_tchalt(TCHALT_H);
+}
+
 /*
  * Common setup before any secondaries are started
  * Make sure all CPU's are in a sensible state before we boot any of the
  * secondarys
  */
-void plat_smp_setup(void)
+void __init plat_smp_setup(void)
 {
-       unsigned long val;
-       int i, num;
+       unsigned int mvpconf0, ntc, tc, ncpu = 0;
 
 #ifdef CONFIG_MIPS_MT_FPAFF
        /* If we have an FPU, enroll ourselves in the FPU-full mask */
@@ -167,75 +242,16 @@ void plat_smp_setup(void)
        /* Put MVPE's into 'configuration state' */
        set_c0_mvpcontrol(MVPCONTROL_VPC);
 
-       val = read_c0_mvpconf0();
+       mvpconf0 = read_c0_mvpconf0();
+       ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT;
 
        /* we'll always have more TC's than VPE's, so loop setting everything
           to a sensible state */
-       for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) {
-               settc(i);
-
-               /* VPE's */
-               if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) {
-
-                       /* deactivate all but vpe0 */
-                       if (i != 0) {
-                               unsigned long tmp = read_vpe_c0_vpeconf0();
-
-                               tmp &= ~VPECONF0_VPA;
-
-                               /* master VPE */
-                               tmp |= VPECONF0_MVP;
-                               write_vpe_c0_vpeconf0(tmp);
-
-                               /* Record this as available CPU */
-                               cpu_set(i, phys_cpu_present_map);
-                               __cpu_number_map[i]     = ++num;
-                               __cpu_logical_map[num]  = i;
-                       }
-
-                       /* disable multi-threading with TC's */
-                       write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);
-
-                       if (i != 0) {
-                               write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
+       for (tc = 0; tc <= ntc; tc++) {
+               settc(tc);
 
-                               /* set config to be the same as vpe0, particularly kseg0 coherency alg */
-                               write_vpe_c0_config( read_c0_config());
-
-                               /* make sure there are no software interrupts pending */
-                               write_vpe_c0_cause(0);
-
-                               /* Propagate Config7 */
-                               write_vpe_c0_config7(read_c0_config7());
-                       }
-
-               }
-
-               /* TC's */
-
-               if (i != 0) {
-                       unsigned long tmp;
-
-                       /* bind a TC to each VPE, May as well put all excess TC's
-                          on the last VPE */
-                       if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) )
-                               write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) );
-                       else {
-                               write_tc_c0_tcbind( read_tc_c0_tcbind() | i);
-
-                               /* and set XTC */
-                               write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT));
-                       }
-
-                       tmp = read_tc_c0_tcstatus();
-
-                       /* mark not allocated and not dynamically allocatable */
-                       tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
-                       tmp |= TCSTATUS_IXMT;           /* interrupt exempt */
-                       write_tc_c0_tcstatus(tmp);
-
-                       write_tc_c0_tchalt(TCHALT_H);
-               }
+               smp_tc_init(tc, mvpconf0);
+               ncpu = smp_vpe_init(tc, mvpconf0, ncpu);
        }
 
        /* Release config state */
@@ -243,7 +259,7 @@ void plat_smp_setup(void)
 
        /* We'll wait until starting the secondaries before starting MVPE */
 
-       printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
+       printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu);
 }
 
 void __init plat_prepare_cpus(unsigned int max_cpus)
index 1cb9441f1474f76692319df943b8ee20b4bf994a..921207c4a83c115ac77dfeadfe6c25bc31fb9d58 100644 (file)
@@ -101,7 +101,9 @@ FEXPORT(__smtc_ipi_vector)
        lw      t0,PT_PADSLOT5(sp)
        /* Argument from sender passed in stack pad slot 4 */
        lw      a0,PT_PADSLOT4(sp)
-       PTR_LA  ra, _ret_from_irq
+       LONG_L  s0, TI_REGS($28)
+       LONG_S  sp, TI_REGS($28)
+       PTR_LA  ra, ret_from_irq
        jr      t0
 
 /*
@@ -119,7 +121,10 @@ LEAF(self_ipi)
        subu    t1,sp,PT_SIZE
        sw      ra,PT_EPC(t1)
        sw      a0,PT_PADSLOT4(t1)
+       LONG_L  s0, TI_REGS($28)
+       LONG_S  sp, TI_REGS($28)
        la      t2,ipi_decode
+       LONG_S  s0, TI_REGS($28)
        sw      t2,PT_PADSLOT5(t1)
        /* Save pre-disable value of TCStatus */
        sw      t0,PT_TCSTATUS(t1)
index cc1f7474f7d7097fe042cb25fee23746e38c4606..3b78caf112f5d5c361bdb82fb0c1f455fb9a9cf2 100644 (file)
@@ -476,6 +476,7 @@ void mipsmt_prepare_cpus(void)
                        write_vpe_c0_compare(0);
                        /* Propagate Config7 */
                        write_vpe_c0_config7(read_c0_config7());
+                       write_vpe_c0_count(read_c0_count());
                }
                /* enable multi-threading within VPE */
                write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE);
index debe86c2f6911fe2eff60b8090d35364d76982fe..e535f86efa2f3f4fc79b7784cdceae9bebea8d7c 100644 (file)
@@ -11,6 +11,7 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
+#include <linux/clocksource.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -67,15 +68,9 @@ int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time;
 int (*rtc_mips_set_mmss)(unsigned long);
 
 
-/* usecs per counter cycle, shifted to left by 32 bits */
-static unsigned int sll32_usecs_per_cycle;
-
 /* how many counter cycles in a jiffy */
 static unsigned long cycles_per_jiffy __read_mostly;
 
-/* Cycle counter value at the previous timer interrupt.. */
-static unsigned int timerhi, timerlo;
-
 /* expirelo is the count value for next CPU timer interrupt */
 static unsigned int expirelo;
 
@@ -93,7 +88,7 @@ static unsigned int null_hpt_read(void)
        return 0;
 }
 
-static void null_hpt_init(unsigned int count)
+static void __init null_hpt_init(void)
 {
        /* nothing */
 }
@@ -128,186 +123,18 @@ static unsigned int c0_hpt_read(void)
        return read_c0_count();
 }
 
-/* For use solely as a high precision timer.  */
-static void c0_hpt_init(unsigned int count)
-{
-       write_c0_count(read_c0_count() - count);
-}
-
 /* For use both as a high precision timer and an interrupt source.  */
-static void c0_hpt_timer_init(unsigned int count)
+static void __init c0_hpt_timer_init(void)
 {
-       count = read_c0_count() - count;
-       expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;
-       write_c0_count(expirelo - cycles_per_jiffy);
+       expirelo = read_c0_count() + cycles_per_jiffy;
        write_c0_compare(expirelo);
-       write_c0_count(count);
 }
 
 int (*mips_timer_state)(void);
 void (*mips_timer_ack)(void);
 unsigned int (*mips_hpt_read)(void);
-void (*mips_hpt_init)(unsigned int);
-
-/*
- * Gettimeoffset routines.  These routines returns the time duration
- * since last timer interrupt in usecs.
- *
- * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset.
- * Otherwise use calibrate_gettimeoffset()
- *
- * If the CPU does not have the counter register, you can either supply
- * your own gettimeoffset() routine, or use null_gettimeoffset(), which
- * gives the same resolution as HZ.
- */
-
-static unsigned long null_gettimeoffset(void)
-{
-       return 0;
-}
-
-
-/* The function pointer to one of the gettimeoffset funcs.  */
-unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset;
-
-
-static unsigned long fixed_rate_gettimeoffset(void)
-{
-       u32 count;
-       unsigned long res;
-
-       /* Get last timer tick in absolute kernel time */
-       count = mips_hpt_read();
-
-       /* .. relative to previous jiffy (32 bits is enough) */
-       count -= timerlo;
-
-       __asm__("multu  %1,%2"
-               : "=h" (res)
-               : "r" (count), "r" (sll32_usecs_per_cycle)
-               : "lo", GCC_REG_ACCUM);
-
-       /*
-        * Due to possible jiffies inconsistencies, we need to check
-        * the result so that we'll get a timer that is monotonic.
-        */
-       if (res >= USECS_PER_JIFFY)
-               res = USECS_PER_JIFFY - 1;
-
-       return res;
-}
-
-
-/*
- * Cached "1/(clocks per usec) * 2^32" value.
- * It has to be recalculated once each jiffy.
- */
-static unsigned long cached_quotient;
-
-/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */
-static unsigned long last_jiffies;
-
-/*
- * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej.
- */
-static unsigned long calibrate_div32_gettimeoffset(void)
-{
-       u32 count;
-       unsigned long res, tmp;
-       unsigned long quotient;
-
-       tmp = jiffies;
-
-       quotient = cached_quotient;
-
-       if (last_jiffies != tmp) {
-               last_jiffies = tmp;
-               if (last_jiffies != 0) {
-                       unsigned long r0;
-                       do_div64_32(r0, timerhi, timerlo, tmp);
-                       do_div64_32(quotient, USECS_PER_JIFFY,
-                                   USECS_PER_JIFFY_FRAC, r0);
-                       cached_quotient = quotient;
-               }
-       }
-
-       /* Get last timer tick in absolute kernel time */
-       count = mips_hpt_read();
-
-       /* .. relative to previous jiffy (32 bits is enough) */
-       count -= timerlo;
-
-       __asm__("multu  %1,%2"
-               : "=h" (res)
-               : "r" (count), "r" (quotient)
-               : "lo", GCC_REG_ACCUM);
-
-       /*
-        * Due to possible jiffies inconsistencies, we need to check
-        * the result so that we'll get a timer that is monotonic.
-        */
-       if (res >= USECS_PER_JIFFY)
-               res = USECS_PER_JIFFY - 1;
-
-       return res;
-}
-
-static unsigned long calibrate_div64_gettimeoffset(void)
-{
-       u32 count;
-       unsigned long res, tmp;
-       unsigned long quotient;
-
-       tmp = jiffies;
-
-       quotient = cached_quotient;
-
-       if (last_jiffies != tmp) {
-               last_jiffies = tmp;
-               if (last_jiffies) {
-                       unsigned long r0;
-                       __asm__(".set   push\n\t"
-                               ".set   mips3\n\t"
-                               "lwu    %0,%3\n\t"
-                               "dsll32 %1,%2,0\n\t"
-                               "or     %1,%1,%0\n\t"
-                               "ddivu  $0,%1,%4\n\t"
-                               "mflo   %1\n\t"
-                               "dsll32 %0,%5,0\n\t"
-                               "or     %0,%0,%6\n\t"
-                               "ddivu  $0,%0,%1\n\t"
-                               "mflo   %0\n\t"
-                               ".set   pop"
-                               : "=&r" (quotient), "=&r" (r0)
-                               : "r" (timerhi), "m" (timerlo),
-                                 "r" (tmp), "r" (USECS_PER_JIFFY),
-                                 "r" (USECS_PER_JIFFY_FRAC)
-                               : "hi", "lo", GCC_REG_ACCUM);
-                       cached_quotient = quotient;
-               }
-       }
-
-       /* Get last timer tick in absolute kernel time */
-       count = mips_hpt_read();
-
-       /* .. relative to previous jiffy (32 bits is enough) */
-       count -= timerlo;
-
-       __asm__("multu  %1,%2"
-               : "=h" (res)
-               : "r" (count), "r" (quotient)
-               : "lo", GCC_REG_ACCUM);
-
-       /*
-        * Due to possible jiffies inconsistencies, we need to check
-        * the result so that we'll get a timer that is monotonic.
-        */
-       if (res >= USECS_PER_JIFFY)
-               res = USECS_PER_JIFFY - 1;
-
-       return res;
-}
-
+void (*mips_hpt_init)(void) __initdata = null_hpt_init;
+unsigned int mips_hpt_mask = 0xffffffff;
 
 /* last time when xtime and rtc are sync'ed up */
 static long last_rtc_update;
@@ -334,18 +161,10 @@ void local_timer_interrupt(int irq, void *dev_id)
  */
 irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
-       unsigned long j;
-       unsigned int count;
-
        write_seqlock(&xtime_lock);
 
-       count = mips_hpt_read();
        mips_timer_ack();
 
-       /* Update timerhi/timerlo for intra-jiffy calibration. */
-       timerhi += count < timerlo;                     /* Wrap around */
-       timerlo = count;
-
        /*
         * call the generic timer interrupt handling
         */
@@ -368,47 +187,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
                }
        }
 
-       /*
-        * If jiffies has overflown in this timer_interrupt, we must
-        * update the timer[hi]/[lo] to make fast gettimeoffset funcs
-        * quotient calc still valid. -arca
-        *
-        * The first timer interrupt comes late as interrupts are
-        * enabled long after timers are initialized.  Therefore the
-        * high precision timer is fast, leading to wrong gettimeoffset()
-        * calculations.  We deal with it by setting it based on the
-        * number of its ticks between the second and the third interrupt.
-        * That is still somewhat imprecise, but it's a good estimate.
-        * --macro
-        */
-       j = jiffies;
-       if (j < 4) {
-               static unsigned int prev_count;
-               static int hpt_initialized;
-
-               switch (j) {
-               case 0:
-                       timerhi = timerlo = 0;
-                       mips_hpt_init(count);
-                       break;
-               case 2:
-                       prev_count = count;
-                       break;
-               case 3:
-                       if (!hpt_initialized) {
-                               unsigned int c3 = 3 * (count - prev_count);
-
-                               timerhi = 0;
-                               timerlo = c3;
-                               mips_hpt_init(count - c3);
-                               hpt_initialized = 1;
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-
        write_sequnlock(&xtime_lock);
 
        /*
@@ -476,12 +254,11 @@ asmlinkage void ll_local_timer_interrupt(int irq)
  * 1) board_time_init() -
  *     a) (optional) set up RTC routines,
  *      b) (optional) calibrate and set the mips_hpt_frequency
- *         (only needed if you intended to use fixed_rate_gettimeoffset
- *          or use cpu counter as timer interrupt source)
+ *         (only needed if you intended to use cpu counter as timer interrupt
+ *          source)
  * 2) setup xtime based on rtc_mips_get_time().
- * 3) choose a appropriate gettimeoffset routine.
- * 4) calculate a couple of cached variables for later usage
- * 5) plat_timer_setup() -
+ * 3) calculate a couple of cached variables for later usage
+ * 4) plat_timer_setup() -
  *     a) (optional) over-write any choices made above by time_init().
  *     b) machine specific code should setup the timer irqaction.
  *     c) enable the timer interrupt
@@ -533,13 +310,48 @@ static unsigned int __init calibrate_hpt(void)
        } while (--i);
        hpt_end = mips_hpt_read();
 
-       hpt_count = hpt_end - hpt_start;
+       hpt_count = (hpt_end - hpt_start) & mips_hpt_mask;
        hz = HZ;
        frequency = (u64)hpt_count * (u64)hz;
 
        return frequency >> log_2_loops;
 }
 
+static cycle_t read_mips_hpt(void)
+{
+       return (cycle_t)mips_hpt_read();
+}
+
+static struct clocksource clocksource_mips = {
+       .name           = "MIPS",
+       .read           = read_mips_hpt,
+       .is_continuous  = 1,
+};
+
+static void __init init_mips_clocksource(void)
+{
+       u64 temp;
+       u32 shift;
+
+       if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read)
+               return;
+
+       /* Calclate a somewhat reasonable rating value */
+       clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
+       /* Find a shift value */
+       for (shift = 32; shift > 0; shift--) {
+               temp = (u64) NSEC_PER_SEC << shift;
+               do_div(temp, mips_hpt_frequency);
+               if ((temp >> 32) == 0)
+                       break;
+       }
+       clocksource_mips.shift = shift;
+       clocksource_mips.mult = (u32)temp;
+       clocksource_mips.mask = mips_hpt_mask;
+
+       clocksource_register(&clocksource_mips);
+}
+
 void __init time_init(void)
 {
        if (board_time_init)
@@ -555,41 +367,21 @@ void __init time_init(void)
                                -xtime.tv_sec, -xtime.tv_nsec);
 
        /* Choose appropriate high precision timer routines.  */
-       if (!cpu_has_counter && !mips_hpt_read) {
+       if (!cpu_has_counter && !mips_hpt_read)
                /* No high precision timer -- sorry.  */
                mips_hpt_read = null_hpt_read;
-               mips_hpt_init = null_hpt_init;
-       } else if (!mips_hpt_frequency && !mips_timer_state) {
+       else if (!mips_hpt_frequency && !mips_timer_state) {
                /* A high precision timer of unknown frequency.  */
-               if (!mips_hpt_read) {
+               if (!mips_hpt_read)
                        /* No external high precision timer -- use R4k.  */
                        mips_hpt_read = c0_hpt_read;
-                       mips_hpt_init = c0_hpt_init;
-               }
-
-               if (cpu_has_mips32r1 || cpu_has_mips32r2 ||
-                   (current_cpu_data.isa_level == MIPS_CPU_ISA_I) ||
-                   (current_cpu_data.isa_level == MIPS_CPU_ISA_II))
-                       /*
-                        * We need to calibrate the counter but we don't have
-                        * 64-bit division.
-                        */
-                       do_gettimeoffset = calibrate_div32_gettimeoffset;
-               else
-                       /*
-                        * We need to calibrate the counter but we *do* have
-                        * 64-bit division.
-                        */
-                       do_gettimeoffset = calibrate_div64_gettimeoffset;
        } else {
                /* We know counter frequency.  Or we can get it.  */
                if (!mips_hpt_read) {
                        /* No external high precision timer -- use R4k.  */
                        mips_hpt_read = c0_hpt_read;
 
-                       if (mips_timer_state)
-                               mips_hpt_init = c0_hpt_init;
-                       else {
+                       if (!mips_timer_state) {
                                /* No external timer interrupt -- use R4k.  */
                                mips_hpt_init = c0_hpt_timer_init;
                                mips_timer_ack = c0_timer_ack;
@@ -598,16 +390,9 @@ void __init time_init(void)
                if (!mips_hpt_frequency)
                        mips_hpt_frequency = calibrate_hpt();
 
-               do_gettimeoffset = fixed_rate_gettimeoffset;
-
                /* Calculate cache parameters.  */
                cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ;
 
-               /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq  */
-               do_div64_32(sll32_usecs_per_cycle,
-                           1000000, mips_hpt_frequency / 2,
-                           mips_hpt_frequency);
-
                /* Report the high precision timer rate for a reference.  */
                printk("Using %u.%03u MHz high precision timer.\n",
                       ((mips_hpt_frequency + 500) / 1000) / 1000,
@@ -619,7 +404,7 @@ void __init time_init(void)
                mips_timer_ack = null_timer_ack;
 
        /* This sets up the high precision timer for the first interrupt.  */
-       mips_hpt_init(mips_hpt_read());
+       mips_hpt_init();
 
        /*
         * Call board specific timer interrupt setup.
@@ -633,6 +418,8 @@ void __init time_init(void)
         * is not invoked accidentally.
         */
        plat_timer_setup(&timer_irqaction);
+
+       init_mips_clocksource();
 }
 
 #define FEBRUARY               2
index cce8313ec27dcacc41247e863376efe50d986809..9fda1b8be3a7e53f52a0bbfb698869971117a4d3 100644 (file)
@@ -1111,7 +1111,7 @@ static struct shadow_registers {
 static void mips_srs_init(void)
 {
        shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
-       printk(KERN_INFO "%d MIPSR2 register sets available\n",
+       printk(KERN_INFO "%ld MIPSR2 register sets available\n",
               shadow_registers.sr_supported);
        shadow_registers.sr_allocated = 1;      /* Set 0 used by kernel */
 }
index 25ed3337ce3590cf0376e070f6433e3ef03340d1..79f0317d84ac6fa2fa99fcc02a916acac335f396 100644 (file)
@@ -50,6 +50,16 @@ SECTIONS
   /* writeable */
   .data : {                    /* Data */
     . = . + DATAOFFSET;                /* for CONFIG_MAPPED_KERNEL */
+    /*
+     * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which
+     * limits the maximum alignment to at most 32kB and results in the following
+     * warning:
+     *
+     *  CC      arch/mips/kernel/init_task.o
+     * arch/mips/kernel/init_task.c:30: warning: alignment of â€˜init_thread_union’
+     * is greater than maximum object file alignment.  Using 32768
+     */
+    . = ALIGN(_PAGE_SIZE);
     *(.data.init_task)
 
     *(.data)
index be8261be679b2d769d67e5b7a3be8340752563e8..594df1a05ecc62847724c3e6fb69596ea1d27307 100644 (file)
@@ -149,7 +149,7 @@ void dump_list_process(struct task_struct *t, void *address)
        printk("Addr                 == %08lx\n", addr);
        printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
 
-       page_dir = pgd_offset(t->mm, 0);
+       page_dir = pgd_offset(t->mm, 0UL);
        printk("page_dir == %016lx\n", (unsigned long) page_dir);
 
        pgd = pgd_offset(t->mm, addr);
@@ -184,13 +184,13 @@ void dump_list_current(void *address)
        dump_list_process(current, address);
 }
 
-unsigned int vtop(void *address)
+unsigned long vtop(void *address)
 {
        pgd_t   *pgd;
        pud_t   *pud;
        pmd_t   *pmd;
        pte_t   *pte;
-       unsigned int addr, paddr;
+       unsigned long addr, paddr;
 
        addr = (unsigned long) address;
        pgd = pgd_offset(current->mm, addr);
index be80c5dd4a0c2861dd058984f35d9787dd75cb57..eeed944e0f83eb9c0ba5c1b09ad3b760feaa040f 100644 (file)
@@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memory(void)
                if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
                        continue;
 
-               addr = boot_mem_map.map[i].addr;
+               addr = PAGE_ALIGN(boot_mem_map.map[i].addr);
                while (addr < boot_mem_map.map[i].addr
                              + boot_mem_map.map[i].size) {
                        ClearPageReserved(virt_to_page(__va(addr)));
index 9337f6c8873acff6a47aee7ee69baab65c986d28..3192a14698c89ff250aeebe4f7e03775eee772fd 100644 (file)
@@ -90,7 +90,7 @@ static struct pci_controller msc_controller = {
 void __init mips_pcibios_init(void)
 {
        struct pci_controller *controller;
-       unsigned long start, end, map, start1, end1, map1, map2, map3, mask;
+       resource_size_t start, end, map, start1, end1, map1, map2, map3, mask;
 
        switch (mips_revision_corid) {
        case MIPS_REVISION_CORID_QED_RM5261:
index c079e2ae02a1d0484884005f779f6d5e323815e0..d817c60c5ca50caeb08ff5390517083e707828a5 100644 (file)
@@ -208,7 +208,8 @@ static unsigned int __init estimate_cpu_frequency(void)
                count = 6000000;
 #endif
 #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA)
-       unsigned int flags;
+       unsigned long flags;
+       unsigned int start;
 
        local_irq_save(flags);
 
@@ -217,13 +218,13 @@ static unsigned int __init estimate_cpu_frequency(void)
        while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 
        /* Start r4k counter. */
-       write_c0_count(0);
+       start = read_c0_count();
 
        /* Read counter exactly on falling edge of update flag */
        while (CMOS_READ(RTC_REG_A) & RTC_UIP);
        while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
 
-       count = read_c0_count();
+       count = read_c0_count() - start;
 
        /* restore interrupts */
        local_irq_restore(flags);
index 5537558f19f795d467e327a5225e662ff03dd7b6..ea49a775bf2859f0afc1fbfda7d2bab626c3f1c6 100644 (file)
@@ -49,6 +49,15 @@ static unsigned short dcache_sets;
 static unsigned int icache_range_cutoff;
 static unsigned int dcache_range_cutoff;
 
+static inline void sb1_on_each_cpu(void (*func) (void *info), void *info,
+                                  int retry, int wait)
+{
+       preempt_disable();
+       smp_call_function(func, info, retry, wait);
+       func(info);
+       preempt_enable();
+}
+
 /*
  * The dcache is fully coherent to the system, with one
  * big caveat:  the instruction stream.  In other words,
@@ -226,7 +235,7 @@ static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr,
        args.vma = vma;
        args.addr = addr;
        args.pfn = pfn;
-       on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1);
+       sb1_on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1);
 }
 #else
 void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
@@ -249,7 +258,7 @@ void sb1___flush_cache_all_ipi(void *ignored)
 
 static void sb1___flush_cache_all(void)
 {
-       on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1);
+       sb1_on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1);
 }
 #else
 void sb1___flush_cache_all(void)
@@ -299,7 +308,7 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end)
 
        args.start = start;
        args.end = end;
-       on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1);
+       sb1_on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1);
 }
 #else
 void sb1_flush_icache_range(unsigned long start, unsigned long end)
@@ -326,7 +335,7 @@ static void sb1_flush_cache_sigtramp_ipi(void *info)
 
 static void sb1_flush_cache_sigtramp(unsigned long addr)
 {
-       on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
+       sb1_on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1);
 }
 #else
 void sb1_flush_cache_sigtramp(unsigned long addr)
@@ -444,7 +453,6 @@ static __init void probe_cache_sizes(void)
 void sb1_cache_init(void)
 {
        extern char except_vec2_sb1;
-       extern char handle_vec2_sb1;
 
        /* Special cache error handler for SB1 */
        set_uncached_handler (0x100, &except_vec2_sb1, 0x80);
index b7c749232ffef80bb50c131f2853965aa7e72396..d41fc5885e875f67ec9de7cf3fc2057b6c7c2419 100644 (file)
@@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(unsigned long offset)
        emit_instruction(mi);
 }
 
+static inline void build_addiu_a2(unsigned long offset)
+{
+       union mips_instruction mi;
+
+       BUG_ON(offset > 0x7fff);
+
+       mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+       mi.i_format.rs         = 6;             /* $a2 */
+       mi.i_format.rt         = 6;             /* $a2 */
+       mi.i_format.simmediate = offset;
+
+       emit_instruction(mi);
+}
+
 static inline void build_addiu_a1(unsigned long offset)
 {
        union mips_instruction mi;
@@ -333,6 +347,7 @@ static inline void build_jr_ra(void)
 void __init build_clear_page(void)
 {
        unsigned int loop_start;
+       unsigned long off;
 
        epc = (unsigned int *) &clear_page_array;
        instruction_pending = 0;
@@ -369,7 +384,12 @@ void __init build_clear_page(void)
                }
        }
 
-       build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0));
+        off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0);
+       if (off > 0x7fff) {
+               build_addiu_a2_a0(off >> 1);
+               build_addiu_a2(off >> 1);
+       } else
+               build_addiu_a2_a0(off);
 
        if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
                build_insn_word(0x3c01a000);    /* lui     $at, 0xa000  */
@@ -420,12 +440,18 @@ dest = label();
 void __init build_copy_page(void)
 {
        unsigned int loop_start;
+       unsigned long off;
 
        epc = (unsigned int *) &copy_page_array;
        store_offset = load_offset = 0;
        instruction_pending = 0;
 
-       build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0));
+       off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0);
+       if (off > 0x7fff) {
+               build_addiu_a2_a0(off >> 1);
+               build_addiu_a2(off >> 1);
+       } else
+               build_addiu_a2_a0(off);
 
        if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x())
                build_insn_word(0x3c01a000);    /* lui     $at, 0xa000  */
index 6f8b25cfa6f022b81b921b975b61c832f14f7f40..fec318a1c8c5ba3fb7c968d5288e973fb20d16ef 100644 (file)
@@ -102,7 +102,7 @@ enum opcode {
        insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
        insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
        insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
-       insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
+       insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
        insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
        insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
        insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
@@ -145,6 +145,7 @@ static __initdata struct insn insn_table[] = {
        { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
        { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
        { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE },
+       { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE },
        { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD },
        { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 },
        { insn_j, M(j_op,0,0,0,0,0), JIMM },
@@ -385,6 +386,7 @@ I_u2u1u3(_dsll);
 I_u2u1u3(_dsll32);
 I_u2u1u3(_dsra);
 I_u2u1u3(_dsrl);
+I_u2u1u3(_dsrl32);
 I_u3u1u2(_dsubu);
 I_0(_eret);
 I_u1(_j);
@@ -996,7 +998,12 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
 #endif
 
        l_vmalloc_done(l, *p);
-       i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */
+
+       if (PGDIR_SHIFT - 3 < 32)               /* get pgd offset in bytes */
+               i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3);
+       else
+               i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32);
+
        i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
        i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
        i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
@@ -1073,7 +1080,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
 
 static __init void build_adjust_context(u32 **p, unsigned int ctx)
 {
-       unsigned int shift = 4 - (PTE_T_LOG2 + 1);
+       unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12;
        unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
 
        switch (current_cpu_data.cputype) {
index fcb8275e219dc74d833fd041e07e7fd53b9e3d28..95e0534026d0756bfb99de5d4c2595538f01a05c 100644 (file)
@@ -23,8 +23,8 @@
 #define OCELOT_REG_INTSET (12)
 #define OCELOT_REG_INTCLR (13)
 
-#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y)
-#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x)
-
+#define __PLD_REG_TO_ADDR(reg) ((void *) OCELOT_CS0_ADDR + OCELOT_REG_##reg)
+#define OCELOT_PLD_WRITE(x, reg) writeb(x, __PLD_REG_TO_ADDR(reg))
+#define OCELOT_PLD_READ(reg) readb(__PLD_REG_TO_ADDR(reg))
 
 #endif /* __MOMENCO_OCELOT_PLD_H__ */
index 56ec47039c16b3cfe742d500d528baadb5c35aa3..d288f7b018426260a114fc240fa3083a7899b5fc 100644 (file)
@@ -57,6 +57,7 @@
 #include <asm/gt64240.h>
 #include <asm/irq.h>
 #include <asm/pci.h>
+#include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <linux/bootmem.h>
@@ -160,6 +161,10 @@ static void __init setup_l3cache(unsigned long size)
        printk("Done\n");
 }
 
+void __init plat_timer_setup(struct irqaction *irq)
+{
+}
+
 void __init plat_mem_setup(void)
 {
        void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
index dd0aec9c3ce1df31f45368087a0496edb006a937..1fb240c57bac356463346f45b5971fd7826b09ab 100644 (file)
 #define M_COUNTER_OVERFLOW             (1UL      << 31)
 
 #ifdef CONFIG_MIPS_MT_SMP
-#define WHAT   (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define WHAT           (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id()))
+#define vpe_id()       smp_processor_id()
 #else
-#define WHAT   0
+#define WHAT           0
+#define vpe_id()       smp_processor_id()
 #endif
 
 #define __define_perf_accessors(r, n, np)                              \
                                                                        \
 static inline unsigned int r_c0_ ## r ## n(void)                       \
 {                                                                      \
-       unsigned int cpu = smp_processor_id();                          \
+       unsigned int cpu = vpe_id();                                    \
                                                                        \
        switch (cpu) {                                                  \
        case 0:                                                         \
@@ -55,7 +57,7 @@ static inline unsigned int r_c0_ ## r ## n(void)                      \
                                                                        \
 static inline void w_c0_ ## r ## n(unsigned int value)                 \
 {                                                                      \
-       unsigned int cpu = smp_processor_id();                          \
+       unsigned int cpu = vpe_id();                                    \
                                                                        \
        switch (cpu) {                                                  \
        case 0:                                                         \
@@ -218,7 +220,7 @@ static inline int n_counters(void)
 {
        int counters = __n_counters();
 
-#ifndef CONFIG_SMP
+#ifdef CONFIG_MIPS_MT_SMP
        if (current_cpu_data.cputype == CPU_34K)
                return counters >> 1;
 #endif
index 0af655b1f3300367973128eea11b1626f8a65052..65c440e8480b088e46660c50fd46025444cb9430 100644 (file)
@@ -41,8 +41,8 @@ extern unsigned int mips_hpt_frequency;
  * 1) board_time_init() -
  *     a) (optional) set up RTC routines,
  *      b) (optional) calibrate and set the mips_hpt_frequency
- *         (only needed if you intended to use fixed_rate_gettimeoffset
- *          or use cpu counter as timer interrupt source)
+ *         (only needed if you intended to use cpu counter as timer interrupt
+ *          source)
  */
 
 void pnx8550_time_init(void)
index 416da22b3bf4cef6cd7c99e72ed085a28e7f4f4f..85b14c73c22617ae163836b01dd67e6dbbb2b962 100644 (file)
@@ -74,7 +74,7 @@ static int titan_i2c_poll(void)
 int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd,
                   int size, unsigned int *addr)
 {
-       int loop = 0, bytes, i;
+       int loop, bytes = 0, i;
        unsigned int *write_data, data, *read_data;
        unsigned long reg_val, val;
 
index 65fa3a23ea5e9fb2f022c80dd29c423970d5122e..3cc0436db6cfc303a9ee81987ed6564a5063f622 100644 (file)
@@ -3,9 +3,7 @@
 
 #include <asm/pmon.h>
 #include <asm/titan_dep.h>
-
-extern unsigned int (*mips_hpt_read)(void);
-extern void (*mips_hpt_init)(unsigned int);
+#include <asm/time.h>
 
 #define LAUNCHSTACK_SIZE 256
 
@@ -101,7 +99,7 @@ void prom_cpus_done(void)
  */
 void prom_init_secondary(void)
 {
-       mips_hpt_init(mips_hpt_read());
+       mips_hpt_init();
 
        set_c0_status(ST0_CO | ST0_IE | ST0_IM);
 }
index 4e870fc4469b8e2db1e78340e8297b68878114b0..c965705f34275ba81a6c44a7633c40b6367e5268 100644 (file)
@@ -134,13 +134,6 @@ again:
        irq_exit();
 }
 
-unsigned long ip27_do_gettimeoffset(void)
-{
-       unsigned long ct_cur1;
-       ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
-       return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
-}
-
 /* Includes for ioc3_init().  */
 #include <asm/sn/types.h>
 #include <asm/sn/sn0/addrs.h>
@@ -248,12 +241,17 @@ void __init plat_timer_setup(struct irqaction *irq)
        setup_irq(irqno, &rt_irqaction);
 }
 
+static unsigned int ip27_hpt_read(void)
+{
+       return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
+}
+
 void __init ip27_time_init(void)
 {
+       mips_hpt_read = ip27_hpt_read;
+       mips_hpt_frequency = CYCLES_PER_SEC;
        xtime.tv_sec = get_m48t35_time();
        xtime.tv_nsec = 0;
-
-       do_gettimeoffset = ip27_do_gettimeoffset;
 }
 
 void __init cpu_time_init(void)
index bf12af46132e07e48fee7ed0a0c8c4f5ce7bba2f..e136bde5248ec607c286dc3b4ece45440543f7a4 100644 (file)
 #define IMR_IP3_VAL    K_BCM1480_INT_MAP_I1
 #define IMR_IP4_VAL    K_BCM1480_INT_MAP_I2
 
+#ifdef CONFIG_SIMULATION
+#define BCM1480_HPT_VALUE      50000
+#else
+#define BCM1480_HPT_VALUE      1000000
+#endif
+
 extern int bcm1480_steal_irq(int irq);
 
 void bcm1480_time_init(void)
@@ -59,11 +65,6 @@ void bcm1480_time_init(void)
                BUG();
        }
 
-       if (!cpu) {
-               /* Use our own gettimeoffset() routine */
-               do_gettimeoffset = bcm1480_gettimeoffset;
-       }
-
        bcm1480_mask_irq(cpu, irq);
 
        /* Map the timer interrupt to ip[4] of this cpu */
@@ -74,11 +75,7 @@ void bcm1480_time_init(void)
        /* Disable the timer and set up the count */
        __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
        __raw_writeq(
-#ifndef CONFIG_SIMULATION
-               1000000/HZ
-#else
-               50000/HZ
-#endif
+               BCM1480_HPT_VALUE/HZ
                , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
 
        /* Set the timer running */
@@ -122,16 +119,16 @@ void bcm1480_timer_interrupt(void)
        }
 }
 
-/*
- * We use our own do_gettimeoffset() instead of the generic one,
- * because the generic one does not work for SMP case.
- * In addition, since we use general timer 0 for system time,
- * we can get accurate intra-jiffy offset without calibration.
- */
-unsigned long bcm1480_gettimeoffset(void)
+static unsigned int bcm1480_hpt_read(void)
 {
+       /* We assume this function is called xtime_lock held. */
        unsigned long count =
                __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+       return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
+}
 
-       return 1000000/HZ - count;
+void __init bcm1480_hpt_setup(void)
+{
+       mips_hpt_read = bcm1480_hpt_read;
+       mips_hpt_frequency = BCM1480_HPT_VALUE;
 }
index 0ccf1796dd78bd6684a31f7844b8a619cf60dfe6..bcb74f2c19484dfb4cecef6e6f7213c9f98e8e71 100644 (file)
 
 #define SB1250_HPT_NUM         3
 #define SB1250_HPT_VALUE       M_SCD_TIMER_CNT /* max value */
-#define SB1250_HPT_SHIFT       ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH)
 
 
 extern int sb1250_steal_irq(int irq);
 
 static unsigned int sb1250_hpt_read(void);
-static void sb1250_hpt_init(unsigned int);
-
-static unsigned int hpt_offset;
 
 void __init sb1250_hpt_setup(void)
 {
@@ -69,13 +65,9 @@ void __init sb1250_hpt_setup(void)
                __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
                             IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
 
-               /*
-                * we need to fill 32 bits, so just use the upper 23 bits and pretend
-                * the timer is going 512Mhz instead of 1Mhz
-                */
-               mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT;
-               mips_hpt_init = sb1250_hpt_init;
+               mips_hpt_frequency = V_SCD_TIMER_FREQ;
                mips_hpt_read = sb1250_hpt_read;
+               mips_hpt_mask = M_SCD_TIMER_INIT;
        }
 }
 
@@ -149,11 +141,7 @@ void sb1250_timer_interrupt(void)
 
 /*
  * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over
- * again. There's no easy way to set to a specific value so store init value
- * in hpt_offset and subtract each time.
- *
- * Note: Timer isn't full 32bits so shift it into the upper part making
- *       it appear to run at a higher frequency.
+ * again.
  */
 static unsigned int sb1250_hpt_read(void)
 {
@@ -161,13 +149,5 @@ static unsigned int sb1250_hpt_read(void)
 
        count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT))));
 
-       count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT;
-
-       return count - hpt_offset;
-}
-
-static void sb1250_hpt_init(unsigned int count)
-{
-       hpt_offset = count;
-       return;
+       return SB1250_HPT_VALUE - count;
 }
diff --git a/arch/mips/tx4927/common/smsc_fdc37m81x.c b/arch/mips/tx4927/common/smsc_fdc37m81x.c
new file mode 100644 (file)
index 0000000..33f517b
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Interface for smsc fdc48m81x Super IO chip
+ *
+ * Author: MontaVista Software, Inc. source@mvista.com
+ *
+ * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright 2004 (c) MontaVista Software, Inc.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/tx4927/smsc_fdc37m81x.h>
+
+#define DEBUG
+
+/* Common Registers */
+#define SMSC_FDC37M81X_CONFIG_INDEX  0x00
+#define SMSC_FDC37M81X_CONFIG_DATA   0x01
+#define SMSC_FDC37M81X_CONF          0x02
+#define SMSC_FDC37M81X_INDEX         0x03
+#define SMSC_FDC37M81X_DNUM          0x07
+#define SMSC_FDC37M81X_DID           0x20
+#define SMSC_FDC37M81X_DREV          0x21
+#define SMSC_FDC37M81X_PCNT          0x22
+#define SMSC_FDC37M81X_PMGT          0x23
+#define SMSC_FDC37M81X_OSC           0x24
+#define SMSC_FDC37M81X_CONFPA0       0x26
+#define SMSC_FDC37M81X_CONFPA1       0x27
+#define SMSC_FDC37M81X_TEST4         0x2B
+#define SMSC_FDC37M81X_TEST5         0x2C
+#define SMSC_FDC37M81X_TEST1         0x2D
+#define SMSC_FDC37M81X_TEST2         0x2E
+#define SMSC_FDC37M81X_TEST3         0x2F
+
+/* Logical device numbers */
+#define SMSC_FDC37M81X_FDD           0x00
+#define SMSC_FDC37M81X_SERIAL1       0x04
+#define SMSC_FDC37M81X_SERIAL2       0x05
+#define SMSC_FDC37M81X_KBD           0x07
+
+/* Logical device Config Registers */
+#define SMSC_FDC37M81X_ACTIVE        0x30
+#define SMSC_FDC37M81X_BASEADDR0     0x60
+#define SMSC_FDC37M81X_BASEADDR1     0x61
+#define SMSC_FDC37M81X_INT           0x70
+#define SMSC_FDC37M81X_INT2          0x72
+#define SMSC_FDC37M81X_MODE          0xF0
+
+/* Chip Config Values */
+#define SMSC_FDC37M81X_CONFIG_ENTER  0x55
+#define SMSC_FDC37M81X_CONFIG_EXIT   0xaa
+#define SMSC_FDC37M81X_CHIP_ID       0x4d
+
+static unsigned long g_smsc_fdc37m81x_base = 0;
+
+static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
+{
+       outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+
+       return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
+}
+
+static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
+{
+       outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+       outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
+}
+
+void smsc_fdc37m81x_config_beg(void)
+{
+       if (g_smsc_fdc37m81x_base) {
+               outb(SMSC_FDC37M81X_CONFIG_ENTER,
+                    g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+       }
+}
+
+void smsc_fdc37m81x_config_end(void)
+{
+       if (g_smsc_fdc37m81x_base)
+               outb(SMSC_FDC37M81X_CONFIG_EXIT,
+                    g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
+}
+
+u8 smsc_fdc37m81x_config_get(u8 reg)
+{
+       u8 val = 0;
+
+       if (g_smsc_fdc37m81x_base)
+               val = smsc_fdc37m81x_rd(reg);
+
+       return val;
+}
+
+void smsc_fdc37m81x_config_set(u8 reg, u8 val)
+{
+       if (g_smsc_fdc37m81x_base)
+               smsc_dc37m81x_wr(reg, val);
+}
+
+unsigned long __init smsc_fdc37m81x_init(unsigned long port)
+{
+       const int field = sizeof(unsigned long) * 2;
+       u8 chip_id;
+
+       if (g_smsc_fdc37m81x_base)
+               printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n",
+                      field, g_smsc_fdc37m81x_base);
+
+       g_smsc_fdc37m81x_base = port;
+
+       smsc_fdc37m81x_config_beg();
+
+       chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
+       if (chip_id == SMSC_FDC37M81X_CHIP_ID)
+               smsc_fdc37m81x_config_end();
+       else {
+               printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n",
+                      chip_id);
+               g_smsc_fdc37m81x_base = 0;
+       }
+
+       return g_smsc_fdc37m81x_base;
+}
+
+#ifdef DEBUG
+void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg)
+{
+       printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg,
+              smsc_fdc37m81x_rd(reg));
+}
+
+void smsc_fdc37m81x_config_dump(void)
+{
+       u8 orig;
+       char *fname = "smsc_fdc37m81x_config_dump()";
+
+       smsc_fdc37m81x_config_beg();
+
+       orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
+
+       printk("%s: common\n", fname);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+                                      SMSC_FDC37M81X_DNUM);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+                                      SMSC_FDC37M81X_DID);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+                                      SMSC_FDC37M81X_DREV);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+                                      SMSC_FDC37M81X_PCNT);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
+                                      SMSC_FDC37M81X_PMGT);
+
+       printk("%s: keyboard\n", fname);
+       smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+                                      SMSC_FDC37M81X_ACTIVE);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+                                      SMSC_FDC37M81X_INT);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+                                      SMSC_FDC37M81X_INT2);
+       smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
+                                      SMSC_FDC37M81X_LDCR_F0);
+
+       smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
+
+       smsc_fdc37m81x_config_end();
+}
+#endif
index 4658b2ae4833f81d46f8ee59aa6d7660d4723260..941c441729b0a17f24a92127deba002d702feb61 100644 (file)
@@ -112,8 +112,6 @@ void print_cp0(char *key, int num, char *name, u32 val)
        return;
 }
 
-indent: Standard input:25: Error:Unexpected end of file
-
 void
 dump_cp0(char *key)
 {
index b926e6a75c29b8ace85a6fea448eacf92dc4bd48..08b20cdfd7b3cc4013ac7fb41adb94022d716588 100644 (file)
@@ -36,14 +36,18 @@ void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)
 
 static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait);
 
-static void txx9_spi_interrupt(int irq, void *dev_id)
+static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id)
 {
        /* disable rx intr */
        tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE;
        wake_up(&txx9_spi_wait);
+
+       return IRQ_HANDLED;
 }
+
 static struct irqaction txx9_spi_action = {
-       txx9_spi_interrupt, 0, 0, "spi", NULL, NULL,
+       .handler        = txx9_spi_interrupt,
+       .name           = "spi",
 };
 
 void __init txx9_spi_irqinit(int irc_irq)
index 8b133afbdc2053e6aaa2a75a076092d03857d397..7af23c43fd4b502a6c7f32478b5010085281ff60 100644 (file)
@@ -38,7 +38,6 @@ obj-$(CONFIG_6xx)             += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
 obj-$(CONFIG_TAU)              += tau_6xx.o
 obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
 obj32-$(CONFIG_MODULES)                += module_32.o
-obj-$(CONFIG_E500)             += perfmon_fsl_booke.o
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 
index 995fcef156fd81c598b679dcec7fa8f4f241874f..93f21aaf7c8ef163a08483cc5f6d06c31d571c80 100644 (file)
@@ -182,7 +182,7 @@ int btext_initialize(struct device_node *np)
        prop = get_property(np, "linux,bootx-linebytes", NULL);
        if (prop == NULL)
                prop = get_property(np, "linebytes", NULL);
-       if (prop)
+       if (prop && *prop != 0xffffffffu)
                pitch = *prop;
        if (pitch == 1)
                pitch = 0x1000;
index 291e3629b5046e67caea8b9dbbbbbb70ca1eca15..e720729f3e5536c6d267b68677a3c1a2ba514432 100644 (file)
@@ -487,7 +487,7 @@ BEGIN_FTR_SECTION
        rlwimi  r13,r12,16,0x20
        mfcr    r12
        cmpwi   r13,0x2c
-       beq     .do_stab_bolted_pSeries
+       beq     do_stab_bolted_pSeries
        mtcrf   0x80,r12
        mfspr   r12,SPRN_SPRG2
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
@@ -600,7 +600,7 @@ system_call_pSeries:
        STD_EXCEPTION_PSERIES(., performance_monitor)
 
        .align  7
-_GLOBAL(do_stab_bolted_pSeries)
+do_stab_bolted_pSeries:
        mtcrf   0x80,r12
        mfspr   r12,SPRN_SPRG2
        EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
@@ -1046,7 +1046,7 @@ slb_miss_fault:
        li      r5,0
        std     r4,_DAR(r1)
        std     r5,_DSISR(r1)
-       b       .handle_page_fault
+       b       handle_page_fault
 
 unrecov_user_slb:
        EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
@@ -1174,12 +1174,13 @@ program_check_common:
        .globl fp_unavailable_common
 fp_unavailable_common:
        EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
-       bne     .load_up_fpu            /* if from user, just load it up */
+       bne     1f                      /* if from user, just load it up */
        bl      .save_nvgprs
        addi    r3,r1,STACK_FRAME_OVERHEAD
        ENABLE_INTS
        bl      .kernel_fp_unavailable_exception
        BUG_OPCODE
+1:     b       .load_up_fpu
 
        .align  7
        .globl altivec_unavailable_common
@@ -1279,10 +1280,10 @@ _GLOBAL(do_hash_page)
        std     r4,_DSISR(r1)
 
        andis.  r0,r4,0xa450            /* weird error? */
-       bne-    .handle_page_fault      /* if not, try to insert a HPTE */
+       bne-    handle_page_fault       /* if not, try to insert a HPTE */
 BEGIN_FTR_SECTION
        andis.  r0,r4,0x0020            /* Is it a segment table fault? */
-       bne-    .do_ste_alloc           /* If so handle it */
+       bne-    do_ste_alloc            /* If so handle it */
 END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
 
        /*
@@ -1324,7 +1325,7 @@ BEGIN_FW_FTR_SECTION
         * because ret_from_except_lite will check for and handle pending
         * interrupts if necessary.
         */
-       beq     .ret_from_except_lite
+       beq     13f
        /* For a hash failure, we don't bother re-enabling interrupts */
        ble-    12f
 
@@ -1346,14 +1347,14 @@ BEGIN_FW_FTR_SECTION
 END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
 
 /* Here we have a page fault that hash_page can't handle. */
-_GLOBAL(handle_page_fault)
+handle_page_fault:
        ENABLE_INTS
 11:    ld      r4,_DAR(r1)
        ld      r5,_DSISR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .do_page_fault
        cmpdi   r3,0
-       beq+    .ret_from_except_lite
+       beq+    13f
        bl      .save_nvgprs
        mr      r5,r3
        addi    r3,r1,STACK_FRAME_OVERHEAD
@@ -1370,12 +1371,14 @@ _GLOBAL(handle_page_fault)
        bl      .low_hash_fault
        b       .ret_from_except
 
+13:    b       .ret_from_except_lite
+
        /* here we have a segment miss */
-_GLOBAL(do_ste_alloc)
+do_ste_alloc:
        bl      .ste_allocate           /* try to insert stab entry */
        cmpdi   r3,0
-       beq+    fast_exception_return
-       b       .handle_page_fault
+       bne-    handle_page_fault
+       b       fast_exception_return
 
 /*
  * r13 points to the PACA, r9 contains the saved CR,
index f88a2a675d90f0d63f202e54c8ddafb4e476ebe1..ba6b7256084b31bb64ecd602782bc48ef3bdf545 100644 (file)
@@ -47,6 +47,17 @@ static int novmerge = 0;
 static int novmerge = 1;
 #endif
 
+static inline unsigned long iommu_num_pages(unsigned long vaddr,
+                                           unsigned long slen)
+{
+       unsigned long npages;
+
+       npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK);
+       npages >>= IOMMU_PAGE_SHIFT;
+
+       return npages;
+}
+
 static int __init setup_iommu(char *str)
 {
        if (!strcmp(str, "novmerge"))
@@ -178,10 +189,10 @@ static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page,
        }
 
        entry += tbl->it_offset;        /* Offset into real TCE table */
-       ret = entry << PAGE_SHIFT;      /* Set the return dma address */
+       ret = entry << IOMMU_PAGE_SHIFT;        /* Set the return dma address */
 
        /* Put the TCEs in the HW table */
-       ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK,
+       ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK,
                         direction);
 
 
@@ -203,7 +214,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
        unsigned long entry, free_entry;
        unsigned long i;
 
-       entry = dma_addr >> PAGE_SHIFT;
+       entry = dma_addr >> IOMMU_PAGE_SHIFT;
        free_entry = entry - tbl->it_offset;
 
        if (((free_entry + npages) > tbl->it_size) ||
@@ -270,7 +281,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
        /* Init first segment length for backout at failure */
        outs->dma_length = 0;
 
-       DBG("mapping %d elements:\n", nelems);
+       DBG("sg mapping %d elements:\n", nelems);
 
        spin_lock_irqsave(&(tbl->it_lock), flags);
 
@@ -285,9 +296,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                }
                /* Allocate iommu entries for that segment */
                vaddr = (unsigned long)page_address(s->page) + s->offset;
-               npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK);
-               npages >>= PAGE_SHIFT;
-               entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0);
+               npages = iommu_num_pages(vaddr, slen);
+               entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
 
                DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
 
@@ -301,14 +311,14 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 
                /* Convert entry to a dma_addr_t */
                entry += tbl->it_offset;
-               dma_addr = entry << PAGE_SHIFT;
-               dma_addr |= s->offset;
+               dma_addr = entry << IOMMU_PAGE_SHIFT;
+               dma_addr |= (s->offset & ~IOMMU_PAGE_MASK);
 
-               DBG("  - %lx pages, entry: %lx, dma_addr: %lx\n",
+               DBG("  - %lu pages, entry: %lx, dma_addr: %lx\n",
                            npages, entry, dma_addr);
 
                /* Insert into HW table */
-               ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction);
+               ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction);
 
                /* If we are in an open segment, try merging */
                if (segstart != s) {
@@ -323,7 +333,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                                DBG("    can't merge, new segment.\n");
                        } else {
                                outs->dma_length += s->length;
-                               DBG("    merged, new len: %lx\n", outs->dma_length);
+                               DBG("    merged, new len: %ux\n", outs->dma_length);
                        }
                }
 
@@ -367,9 +377,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                if (s->dma_length != 0) {
                        unsigned long vaddr, npages;
 
-                       vaddr = s->dma_address & PAGE_MASK;
-                       npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr)
-                               >> PAGE_SHIFT;
+                       vaddr = s->dma_address & IOMMU_PAGE_MASK;
+                       npages = iommu_num_pages(s->dma_address, s->dma_length);
                        __iommu_free(tbl, vaddr, npages);
                        s->dma_address = DMA_ERROR_CODE;
                        s->dma_length = 0;
@@ -398,8 +407,7 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
 
                if (sglist->dma_length == 0)
                        break;
-               npages = (PAGE_ALIGN(dma_handle + sglist->dma_length)
-                         - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT;
+               npages = iommu_num_pages(dma_handle,sglist->dma_length);
                __iommu_free(tbl, dma_handle, npages);
                sglist++;
        }
@@ -532,12 +540,11 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
        BUG_ON(direction == DMA_NONE);
 
        uaddr = (unsigned long)vaddr;
-       npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK);
-       npages >>= PAGE_SHIFT;
+       npages = iommu_num_pages(uaddr, size);
 
        if (tbl) {
                dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
-                                        mask >> PAGE_SHIFT, 0);
+                                        mask >> IOMMU_PAGE_SHIFT, 0);
                if (dma_handle == DMA_ERROR_CODE) {
                        if (printk_ratelimit())  {
                                printk(KERN_INFO "iommu_alloc failed, "
@@ -545,7 +552,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
                                                tbl, vaddr, npages);
                        }
                } else
-                       dma_handle |= (uaddr & ~PAGE_MASK);
+                       dma_handle |= (uaddr & ~IOMMU_PAGE_MASK);
        }
 
        return dma_handle;
@@ -554,11 +561,14 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
 void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
                size_t size, enum dma_data_direction direction)
 {
+       unsigned int npages;
+
        BUG_ON(direction == DMA_NONE);
 
-       if (tbl)
-               iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) -
-                                       (dma_handle & PAGE_MASK)) >> PAGE_SHIFT);
+       if (tbl) {
+               npages = iommu_num_pages(dma_handle, size);
+               iommu_free(tbl, dma_handle, npages);
+       }
 }
 
 /* Allocates a contiguous real buffer and creates mappings over it.
@@ -570,11 +580,11 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
 {
        void *ret = NULL;
        dma_addr_t mapping;
-       unsigned int npages, order;
+       unsigned int order;
+       unsigned int nio_pages, io_order;
        struct page *page;
 
        size = PAGE_ALIGN(size);
-       npages = size >> PAGE_SHIFT;
        order = get_order(size);
 
        /*
@@ -598,8 +608,10 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
        memset(ret, 0, size);
 
        /* Set up tces to cover the allocated range */
-       mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL,
-                             mask >> PAGE_SHIFT, order);
+       nio_pages = size >> IOMMU_PAGE_SHIFT;
+       io_order = get_iommu_order(size);
+       mapping = iommu_alloc(tbl, ret, nio_pages, DMA_BIDIRECTIONAL,
+                             mask >> IOMMU_PAGE_SHIFT, io_order);
        if (mapping == DMA_ERROR_CODE) {
                free_pages((unsigned long)ret, order);
                return NULL;
@@ -611,12 +623,13 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
 void iommu_free_coherent(struct iommu_table *tbl, size_t size,
                         void *vaddr, dma_addr_t dma_handle)
 {
-       unsigned int npages;
-
        if (tbl) {
+               unsigned int nio_pages;
+
+               size = PAGE_ALIGN(size);
+               nio_pages = size >> IOMMU_PAGE_SHIFT;
+               iommu_free(tbl, dma_handle, nio_pages);
                size = PAGE_ALIGN(size);
-               npages = size >> PAGE_SHIFT;
-               iommu_free(tbl, dma_handle, npages);
                free_pages((unsigned long)vaddr, get_order(size));
        }
 }
diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c
deleted file mode 100644 (file)
index e0dcf2b..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/* arch/powerpc/kernel/perfmon_fsl_booke.c
- * Freescale Book-E Performance Monitor code
- *
- * Author: Andy Fleming
- * Copyright (c) 2004 Freescale Semiconductor, Inc
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version
- *  2 of the License, or (at your option) any later version.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/prctl.h>
-
-#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/reg.h>
-#include <asm/xmon.h>
-#include <asm/pmc.h>
-
-static inline u32 get_pmlca(int ctr);
-static inline void set_pmlca(int ctr, u32 pmlca);
-
-static inline u32 get_pmlca(int ctr)
-{
-       u32 pmlca;
-
-       switch (ctr) {
-               case 0:
-                       pmlca = mfpmr(PMRN_PMLCA0);
-                       break;
-               case 1:
-                       pmlca = mfpmr(PMRN_PMLCA1);
-                       break;
-               case 2:
-                       pmlca = mfpmr(PMRN_PMLCA2);
-                       break;
-               case 3:
-                       pmlca = mfpmr(PMRN_PMLCA3);
-                       break;
-               default:
-                       panic("Bad ctr number\n");
-       }
-
-       return pmlca;
-}
-
-static inline void set_pmlca(int ctr, u32 pmlca)
-{
-       switch (ctr) {
-               case 0:
-                       mtpmr(PMRN_PMLCA0, pmlca);
-                       break;
-               case 1:
-                       mtpmr(PMRN_PMLCA1, pmlca);
-                       break;
-               case 2:
-                       mtpmr(PMRN_PMLCA2, pmlca);
-                       break;
-               case 3:
-                       mtpmr(PMRN_PMLCA3, pmlca);
-                       break;
-               default:
-                       panic("Bad ctr number\n");
-       }
-}
-
-void init_pmc_stop(int ctr)
-{
-       u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
-                       PMLCA_FCM1 | PMLCA_FCM0);
-       u32 pmlcb = 0;
-
-       switch (ctr) {
-               case 0:
-                       mtpmr(PMRN_PMLCA0, pmlca);
-                       mtpmr(PMRN_PMLCB0, pmlcb);
-                       break;
-               case 1:
-                       mtpmr(PMRN_PMLCA1, pmlca);
-                       mtpmr(PMRN_PMLCB1, pmlcb);
-                       break;
-               case 2:
-                       mtpmr(PMRN_PMLCA2, pmlca);
-                       mtpmr(PMRN_PMLCB2, pmlcb);
-                       break;
-               case 3:
-                       mtpmr(PMRN_PMLCA3, pmlca);
-                       mtpmr(PMRN_PMLCB3, pmlcb);
-                       break;
-               default:
-                       panic("Bad ctr number!\n");
-       }
-}
-
-void set_pmc_event(int ctr, int event)
-{
-       u32 pmlca;
-
-       pmlca = get_pmlca(ctr);
-
-       pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
-               ((event << PMLCA_EVENT_SHIFT) &
-                PMLCA_EVENT_MASK);
-
-       set_pmlca(ctr, pmlca);
-}
-
-void set_pmc_user_kernel(int ctr, int user, int kernel)
-{
-       u32 pmlca;
-
-       pmlca = get_pmlca(ctr);
-
-       if(user)
-               pmlca &= ~PMLCA_FCU;
-       else
-               pmlca |= PMLCA_FCU;
-
-       if(kernel)
-               pmlca &= ~PMLCA_FCS;
-       else
-               pmlca |= PMLCA_FCS;
-
-       set_pmlca(ctr, pmlca);
-}
-
-void set_pmc_marked(int ctr, int mark0, int mark1)
-{
-       u32 pmlca = get_pmlca(ctr);
-
-       if(mark0)
-               pmlca &= ~PMLCA_FCM0;
-       else
-               pmlca |= PMLCA_FCM0;
-
-       if(mark1)
-               pmlca &= ~PMLCA_FCM1;
-       else
-               pmlca |= PMLCA_FCM1;
-
-       set_pmlca(ctr, pmlca);
-}
-
-void pmc_start_ctr(int ctr, int enable)
-{
-       u32 pmlca = get_pmlca(ctr);
-
-       pmlca &= ~PMLCA_FC;
-
-       if (enable)
-               pmlca |= PMLCA_CE;
-       else
-               pmlca &= ~PMLCA_CE;
-
-       set_pmlca(ctr, pmlca);
-}
-
-void pmc_start_ctrs(int enable)
-{
-       u32 pmgc0 = mfpmr(PMRN_PMGC0);
-
-       pmgc0 &= ~PMGC0_FAC;
-       pmgc0 |= PMGC0_FCECE;
-
-       if (enable)
-               pmgc0 |= PMGC0_PMIE;
-       else
-               pmgc0 &= ~PMGC0_PMIE;
-
-       mtpmr(PMRN_PMGC0, pmgc0);
-}
-
-void pmc_stop_ctrs(void)
-{
-       u32 pmgc0 = mfpmr(PMRN_PMGC0);
-
-       pmgc0 |= PMGC0_FAC;
-
-       pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
-
-       mtpmr(PMRN_PMGC0, pmgc0);
-}
-
-void dump_pmcs(void)
-{
-       printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
-       printk("pmc\t\tpmlca\t\tpmlcb\n");
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
-                       mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
-                       mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
-                       mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
-                       mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
-}
-
-EXPORT_SYMBOL(init_pmc_stop);
-EXPORT_SYMBOL(set_pmc_event);
-EXPORT_SYMBOL(set_pmc_user_kernel);
-EXPORT_SYMBOL(set_pmc_marked);
-EXPORT_SYMBOL(pmc_start_ctr);
-EXPORT_SYMBOL(pmc_start_ctrs);
-EXPORT_SYMBOL(pmc_stop_ctrs);
-EXPORT_SYMBOL(dump_pmcs);
index a0a2efadeabf8fbbed432e506360d14f85c1770f..3d8f6f44641eb1e90aeea85a4246ca9c09e62045 100644 (file)
@@ -71,7 +71,7 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq)
        }
 
        pmc_owner_caller = __builtin_return_address(0);
-       perf_irq = new_perf_irq ? : dummy_perf;
+       perf_irq = new_perf_irq ? new_perf_irq : dummy_perf;
 
  out:
        spin_unlock(&pmc_owner_lock);
index 5ed4c2ceb5caa8632c11f229193afe0596893650..c66b4771ef445e264194bbc8ac039ce9297b31e2 100644 (file)
@@ -843,7 +843,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
 
 void alignment_exception(struct pt_regs *regs)
 {
-       int fixed = 0;
+       int sig, code, fixed = 0;
 
        /* we don't implement logging of alignment exceptions */
        if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
@@ -857,14 +857,16 @@ void alignment_exception(struct pt_regs *regs)
 
        /* Operand address was bad */
        if (fixed == -EFAULT) {
-               if (user_mode(regs))
-                       _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-               else
-                       /* Search exception table */
-                       bad_page_fault(regs, regs->dar, SIGSEGV);
-               return;
+               sig = SIGSEGV;
+               code = SEGV_ACCERR;
+       } else {
+               sig = SIGBUS;
+               code = BUS_ADRALN;
        }
-       _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+       if (user_mode(regs))
+               _exception(sig, regs, code, regs->dar);
+       else
+               bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)
index cb87e71eec665666d762a7a0ec951a9bac137351..ed007878d1bf977f311f941d0c3351c96968da63 100644 (file)
@@ -92,9 +92,9 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
                                &tbl->it_index, &offset, &size);
 
                /* TCE table size - measured in tce entries */
-               tbl->it_size = size >> PAGE_SHIFT;
+               tbl->it_size = size >> IOMMU_PAGE_SHIFT;
                /* offset for VIO should always be 0 */
-               tbl->it_offset = offset >> PAGE_SHIFT;
+               tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
                tbl->it_busno = 0;
                tbl->it_type = TCE_VB;
 
index 9590ba780b987c64afbe47da426b77c5964342e0..7e8ded051b5b3fcc505c2ea8449422c6f42b6e61 100644 (file)
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/kernel.h>
+#include <linux/kprobes.h>
 #include <linux/ptrace.h>
 #include <asm/sstep.h>
 #include <asm/processor.h>
@@ -25,7 +26,7 @@ extern char system_call_common[];
 /*
  * Determine whether a conditional branch instruction would branch.
  */
-static int branch_taken(unsigned int instr, struct pt_regs *regs)
+static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs)
 {
        unsigned int bo = (instr >> 21) & 0x1f;
        unsigned int bi;
@@ -51,7 +52,7 @@ static int branch_taken(unsigned int instr, struct pt_regs *regs)
  * or -1 if the instruction is one that should not be stepped,
  * such as an rfid, or a mtmsrd that would clear MSR_RI.
  */
-int emulate_step(struct pt_regs *regs, unsigned int instr)
+int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
 {
        unsigned int opcode, rd;
        unsigned long int imm;
index 5615acc295279366e7ac448011cf41db92369ab4..fd68b74c07c3c4e5c457371c1dd54c52767cec8a 100644 (file)
@@ -480,9 +480,6 @@ static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas)
 
        mm->context.high_htlb_areas |= newareas;
 
-       /* update the paca copy of the context struct */
-       get_paca()->context = mm->context;
-
        /* the context change must make it to memory before the flush,
         * so that further SLB misses do the right thing. */
        mb();
index 3145d610b5b0b18f265e787da65f87c8c0e1889e..0b5df9c96ae0a4d1560724e4ddf9d7ca2d1b1f37 100644 (file)
@@ -13,4 +13,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
 oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
 oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
 oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
-oprofile-$(CONFIG_PPC32) += op_model_7450.o
+oprofile-$(CONFIG_6xx) += op_model_7450.o
index fd0bbbe7a4de480fe5de9ff22f944270edace114..63bbef3b63f18be04701394cb17b255d1c42b20c 100644 (file)
@@ -34,6 +34,11 @@ static void op_handle_interrupt(struct pt_regs *regs)
        model->handle_interrupt(regs, ctr);
 }
 
+static void op_powerpc_cpu_setup(void *dummy)
+{
+       model->cpu_setup(ctr);
+}
+
 static int op_powerpc_setup(void)
 {
        int err;
@@ -47,7 +52,7 @@ static int op_powerpc_setup(void)
        model->reg_setup(ctr, &sys, model->num_counters);
 
        /* Configure the registers on all cpus.  */
-       on_each_cpu(model->cpu_setup, NULL, 0, 1);
+       on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1);
 
        return 0;
 }
@@ -142,7 +147,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
                case PPC_OPROFILE_POWER4:
                        model = &op_model_power4;
                        break;
-#else
+#endif
+#ifdef CONFIG_6xx
                case PPC_OPROFILE_G4:
                        model = &op_model_7450;
                        break;
index d8ee3aea83f890e9dc80349ecf8420bd562a7ee9..f481c0ed5e675eec7bac1656e4edeadc1cec49ef 100644 (file)
@@ -81,7 +81,7 @@ static void pmc_stop_ctrs(void)
 
 /* Configures the counters on this CPU based on the global
  * settings */
-static void fsl7450_cpu_setup(void *unused)
+static void fsl7450_cpu_setup(struct op_counter_config *ctr)
 {
        /* freeze all counters */
        pmc_stop_ctrs();
index e29dede31423e0275b4aaa6818bf53b2aa831c11..0b3c31f5209ef4377e6be0bd48030d321734c07e 100644 (file)
@@ -32,42 +32,152 @@ static unsigned long reset_value[OP_MAX_COUNTER];
 static int num_counters;
 static int oprofile_running;
 
-static inline unsigned int ctr_read(unsigned int i)
+static void init_pmc_stop(int ctr)
 {
-       switch(i) {
-               case 0:
-                       return mfpmr(PMRN_PMC0);
-               case 1:
-                       return mfpmr(PMRN_PMC1);
-               case 2:
-                       return mfpmr(PMRN_PMC2);
-               case 3:
-                       return mfpmr(PMRN_PMC3);
-               default:
-                       return 0;
-       }
-}
+       u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
+                       PMLCA_FCM1 | PMLCA_FCM0);
+       u32 pmlcb = 0;
 
-static inline void ctr_write(unsigned int i, unsigned int val)
-{
-       switch(i) {
+       switch (ctr) {
                case 0:
-                       mtpmr(PMRN_PMC0, val);
+                       mtpmr(PMRN_PMLCA0, pmlca);
+                       mtpmr(PMRN_PMLCB0, pmlcb);
                        break;
                case 1:
-                       mtpmr(PMRN_PMC1, val);
+                       mtpmr(PMRN_PMLCA1, pmlca);
+                       mtpmr(PMRN_PMLCB1, pmlcb);
                        break;
                case 2:
-                       mtpmr(PMRN_PMC2, val);
+                       mtpmr(PMRN_PMLCA2, pmlca);
+                       mtpmr(PMRN_PMLCB2, pmlcb);
                        break;
                case 3:
-                       mtpmr(PMRN_PMC3, val);
+                       mtpmr(PMRN_PMLCA3, pmlca);
+                       mtpmr(PMRN_PMLCB3, pmlcb);
                        break;
                default:
-                       break;
+                       panic("Bad ctr number!\n");
        }
 }
 
+static void set_pmc_event(int ctr, int event)
+{
+       u32 pmlca;
+
+       pmlca = get_pmlca(ctr);
+
+       pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
+               ((event << PMLCA_EVENT_SHIFT) &
+                PMLCA_EVENT_MASK);
+
+       set_pmlca(ctr, pmlca);
+}
+
+static void set_pmc_user_kernel(int ctr, int user, int kernel)
+{
+       u32 pmlca;
+
+       pmlca = get_pmlca(ctr);
+
+       if(user)
+               pmlca &= ~PMLCA_FCU;
+       else
+               pmlca |= PMLCA_FCU;
+
+       if(kernel)
+               pmlca &= ~PMLCA_FCS;
+       else
+               pmlca |= PMLCA_FCS;
+
+       set_pmlca(ctr, pmlca);
+}
+
+static void set_pmc_marked(int ctr, int mark0, int mark1)
+{
+       u32 pmlca = get_pmlca(ctr);
+
+       if(mark0)
+               pmlca &= ~PMLCA_FCM0;
+       else
+               pmlca |= PMLCA_FCM0;
+
+       if(mark1)
+               pmlca &= ~PMLCA_FCM1;
+       else
+               pmlca |= PMLCA_FCM1;
+
+       set_pmlca(ctr, pmlca);
+}
+
+static void pmc_start_ctr(int ctr, int enable)
+{
+       u32 pmlca = get_pmlca(ctr);
+
+       pmlca &= ~PMLCA_FC;
+
+       if (enable)
+               pmlca |= PMLCA_CE;
+       else
+               pmlca &= ~PMLCA_CE;
+
+       set_pmlca(ctr, pmlca);
+}
+
+static void pmc_start_ctrs(int enable)
+{
+       u32 pmgc0 = mfpmr(PMRN_PMGC0);
+
+       pmgc0 &= ~PMGC0_FAC;
+       pmgc0 |= PMGC0_FCECE;
+
+       if (enable)
+               pmgc0 |= PMGC0_PMIE;
+       else
+               pmgc0 &= ~PMGC0_PMIE;
+
+       mtpmr(PMRN_PMGC0, pmgc0);
+}
+
+static void pmc_stop_ctrs(void)
+{
+       u32 pmgc0 = mfpmr(PMRN_PMGC0);
+
+       pmgc0 |= PMGC0_FAC;
+
+       pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
+
+       mtpmr(PMRN_PMGC0, pmgc0);
+}
+
+static void dump_pmcs(void)
+{
+       printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
+       printk("pmc\t\tpmlca\t\tpmlcb\n");
+       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
+                       mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
+       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
+                       mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
+       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
+                       mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
+       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
+                       mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
+}
+
+static void fsl_booke_cpu_setup(struct op_counter_config *ctr)
+{
+       int i;
+
+       /* freeze all counters */
+       pmc_stop_ctrs();
+
+       for (i = 0;i < num_counters;i++) {
+               init_pmc_stop(i);
+
+               set_pmc_event(i, ctr[i].event);
+
+               set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
+       }
+}
 
 static void fsl_booke_reg_setup(struct op_counter_config *ctr,
                             struct op_system_config *sys,
@@ -77,23 +187,14 @@ static void fsl_booke_reg_setup(struct op_counter_config *ctr,
 
        num_counters = num_ctrs;
 
-       /* freeze all counters */
-       pmc_stop_ctrs();
-
        /* Our counters count up, and "count" refers to
         * how much before the next interrupt, and we interrupt
         * on overflow.  So we calculate the starting value
         * which will give us "count" until overflow.
         * Then we set the events on the enabled counters */
-       for (i = 0; i < num_counters; ++i) {
+       for (i = 0; i < num_counters; ++i)
                reset_value[i] = 0x80000000UL - ctr[i].count;
 
-               init_pmc_stop(i);
-
-               set_pmc_event(i, ctr[i].event);
-
-               set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
-       }
 }
 
 static void fsl_booke_start(struct op_counter_config *ctr)
@@ -105,8 +206,8 @@ static void fsl_booke_start(struct op_counter_config *ctr)
        for (i = 0; i < num_counters; ++i) {
                if (ctr[i].enabled) {
                        ctr_write(i, reset_value[i]);
-                       /* Set Each enabled counterd to only
-                        * count when the Mark bit is not set */
+                       /* Set each enabled counter to only
+                        * count when the Mark bit is *not* set */
                        set_pmc_marked(i, 1, 0);
                        pmc_start_ctr(i, 1);
                } else {
@@ -177,6 +278,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
 
 struct op_powerpc_model op_model_fsl_booke = {
        .reg_setup              = fsl_booke_reg_setup,
+       .cpu_setup              = fsl_booke_cpu_setup,
        .start                  = fsl_booke_start,
        .stop                   = fsl_booke_stop,
        .handle_interrupt       = fsl_booke_handle_interrupt,
index 6a927effcc7799c0e6f37b1e56cb636256a43397..356709d515b9707ab3c44276dcf12e279cfb99a6 100644 (file)
@@ -82,7 +82,7 @@ static inline int mmcra_must_set_sample(void)
        return 0;
 }
 
-static void power4_cpu_setup(void *unused)
+static void power4_cpu_setup(struct op_counter_config *ctr)
 {
        unsigned int mmcr0 = mmcr0_val;
        unsigned long mmcra = mmcra_val;
index 042f8f4867adc1bb62e133f9a7d982266836de23..19c5ee089bc99550b2bc06eedb27086e56f70fab 100644 (file)
@@ -102,7 +102,7 @@ static void rs64_reg_setup(struct op_counter_config *ctr,
        /* XXX setup user and kernel profiling */
 }
 
-static void rs64_cpu_setup(void *unused)
+static void rs64_cpu_setup(struct op_counter_config *ctr)
 {
        unsigned int mmcr0;
 
index f4cbbcf8773a77a17b7c54380034c27fd1096931..218817d13c5cd9943b5bdea6d76ce1f993286117 100644 (file)
@@ -43,9 +43,6 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
        u64 rc;
        u64 tce, rpn;
 
-       index <<= TCE_PAGE_FACTOR;
-       npages <<= TCE_PAGE_FACTOR;
-
        while (npages--) {
                rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
                tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
@@ -75,9 +72,6 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
 {
        u64 rc;
 
-       npages <<= TCE_PAGE_FACTOR;
-       index <<= TCE_PAGE_FACTOR;
-
        while (npages--) {
                rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
                if (rc)
@@ -136,10 +130,9 @@ void iommu_table_getparms_iSeries(unsigned long busno,
                panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
 
        /* itc_size is in pages worth of table, it_size is in # of entries */
-       tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) /
-                       TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR;
+       tbl->it_size = (parms->itc_size * TCE_PAGE_SIZE) / TCE_ENTRY_SIZE;
        tbl->it_busno = parms->itc_busno;
-       tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR;
+       tbl->it_offset = parms->itc_offset;
        tbl->it_index = parms->itc_index;
        tbl->it_blocksize = 1;
        tbl->it_type = virtbus ? TCE_VB : TCE_PCI;
index d24ba547e53f162a9a95e47a474ddbfb17be4530..556c279a789d4046d7c72647b271e2bffad7327a 100644 (file)
@@ -57,9 +57,6 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index,
        u64 *tcep;
        u64 rpn;
 
-       index <<= TCE_PAGE_FACTOR;
-       npages <<= TCE_PAGE_FACTOR;
-
        proto_tce = TCE_PCI_READ; // Read allowed
 
        if (direction != DMA_TO_DEVICE)
@@ -82,9 +79,6 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
 {
        u64 *tcep;
 
-       npages <<= TCE_PAGE_FACTOR;
-       index <<= TCE_PAGE_FACTOR;
-
        tcep = ((u64 *)tbl->it_base) + index;
 
        while (npages--)
@@ -95,7 +89,6 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
 {
        u64 *tcep;
 
-       index <<= TCE_PAGE_FACTOR;
        tcep = ((u64 *)tbl->it_base) + index;
 
        return *tcep;
@@ -109,9 +102,6 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
        u64 proto_tce, tce;
        u64 rpn;
 
-       tcenum <<= TCE_PAGE_FACTOR;
-       npages <<= TCE_PAGE_FACTOR;
-
        rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
        proto_tce = TCE_PCI_READ;
        if (direction != DMA_TO_DEVICE)
@@ -146,7 +136,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
        u64 rpn;
        long l, limit;
 
-       if (TCE_PAGE_FACTOR == 0 && npages == 1)
+       if (npages == 1)
                return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
                                           direction);
 
@@ -164,9 +154,6 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                __get_cpu_var(tce_page) = tcep;
        }
 
-       tcenum <<= TCE_PAGE_FACTOR;
-       npages <<= TCE_PAGE_FACTOR;
-
        rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
        proto_tce = TCE_PCI_READ;
        if (direction != DMA_TO_DEVICE)
@@ -207,9 +194,6 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
 {
        u64 rc;
 
-       tcenum <<= TCE_PAGE_FACTOR;
-       npages <<= TCE_PAGE_FACTOR;
-
        while (npages--) {
                rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
 
@@ -229,9 +213,6 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
 {
        u64 rc;
 
-       tcenum <<= TCE_PAGE_FACTOR;
-       npages <<= TCE_PAGE_FACTOR;
-
        rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
 
        if (rc && printk_ratelimit()) {
@@ -248,7 +229,6 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum)
        u64 rc;
        unsigned long tce_ret;
 
-       tcenum <<= TCE_PAGE_FACTOR;
        rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret);
 
        if (rc && printk_ratelimit()) {
@@ -289,7 +269,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
        tbl->it_busno = phb->bus->number;
 
        /* Units of tce entries */
-       tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
+       tbl->it_offset = phb->dma_window_base_cur >> IOMMU_PAGE_SHIFT;
 
        /* Test if we are going over 2GB of DMA space */
        if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
@@ -300,7 +280,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
        phb->dma_window_base_cur += phb->dma_window_size;
 
        /* Set the tce table size - measured in entries */
-       tbl->it_size = phb->dma_window_size >> PAGE_SHIFT;
+       tbl->it_size = phb->dma_window_size >> IOMMU_PAGE_SHIFT;
 
        tbl->it_index = 0;
        tbl->it_blocksize = 16;
@@ -325,8 +305,8 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
        tbl->it_base   = 0;
        tbl->it_blocksize  = 16;
        tbl->it_type = TCE_PCI;
-       tbl->it_offset = offset >> PAGE_SHIFT;
-       tbl->it_size = size >> PAGE_SHIFT;
+       tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
+       tbl->it_size = size >> IOMMU_PAGE_SHIFT;
 }
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -522,8 +502,6 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
        const void *dma_window = NULL;
        struct pci_dn *pci;
 
-       DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
-
        /* dev setup for LPAR is a little tricky, since the device tree might
         * contain the dma-window properties per-device and not neccesarily
         * for the bus. So we need to search upwards in the tree until we
@@ -532,6 +510,9 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
         */
        dn = pci_device_to_OF_node(dev);
 
+       DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n",
+            dev, pci_name(dev), dn->full_name);
+
        for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
             pdn = pdn->parent) {
                dma_window = get_property(pdn, "ibm,dma-window", NULL);
index 1c8817c4835ee780dcf5f0e0cc285cd4f790d86f..ff202edb0591d2fb55afabd99004ba3a3e38ec80 100644 (file)
@@ -72,7 +72,6 @@
 
 #define DART_PAGE_SHIFT                12
 #define DART_PAGE_SIZE         (1 << DART_PAGE_SHIFT)
-#define DART_PAGE_FACTOR       (PAGE_SHIFT - DART_PAGE_SHIFT)
 
 
 #endif /* _POWERPC_SYSDEV_DART_H */
index 03b4477dd7f0a88e4e6ac0797a9a3c4d29cda7bf..572b7846cc77226870784995534d98ea794bd979 100644 (file)
@@ -156,9 +156,6 @@ static void dart_build(struct iommu_table *tbl, long index,
 
        DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr);
 
-       index <<= DART_PAGE_FACTOR;
-       npages <<= DART_PAGE_FACTOR;
-
        dp = ((unsigned int*)tbl->it_base) + index;
 
        /* On U3, all memory is contigous, so we can move this
@@ -199,9 +196,6 @@ static void dart_free(struct iommu_table *tbl, long index, long npages)
 
        DBG("dart: free at: %lx, %lx\n", index, npages);
 
-       index <<= DART_PAGE_FACTOR;
-       npages <<= DART_PAGE_FACTOR;
-
        dp  = ((unsigned int *)tbl->it_base) + index;
 
        while (npages--)
@@ -281,7 +275,7 @@ static void iommu_table_dart_setup(void)
        iommu_table_dart.it_busno = 0;
        iommu_table_dart.it_offset = 0;
        /* it_size is in number of entries */
-       iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR;
+       iommu_table_dart.it_size = dart_tablesize / sizeof(u32);
 
        /* Initialize the common IOMMU code */
        iommu_table_dart.it_base = (unsigned long)dart_vbase;
index 2bae632d3ad78f2063cdfe2cd2349ebe1075182f..e4223226a7a87aff07d112f38c4517d9726f262b 100644 (file)
@@ -122,8 +122,7 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
                                mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
                }
 
-               out_be32(&qe_immr->cp.cecdr,
-                        immrbar_virt_to_phys((void *)cmd_input));
+               out_be32(&qe_immr->cp.cecdr, cmd_input);
                out_be32(&qe_immr->cp.cecr,
                         (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
                          mcn_protocol << mcn_shift));
index aafc8e8893d1ebc0ac969b097f77d9f976d616ee..9661a91183b35a18f79636e2f196d6a8d3f3eaa0 100644 (file)
@@ -708,7 +708,7 @@ void single_step_exception(struct pt_regs *regs)
 
 void alignment_exception(struct pt_regs *regs)
 {
-       int fixed;
+       int sig, code, fixed = 0;
 
        fixed = fix_alignment(regs);
        if (fixed == 1) {
@@ -717,14 +717,16 @@ void alignment_exception(struct pt_regs *regs)
                return;
        }
        if (fixed == -EFAULT) {
-               /* fixed == -EFAULT means the operand address was bad */
-               if (user_mode(regs))
-                       _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
-               else
-                       bad_page_fault(regs, regs->dar, SIGSEGV);
-               return;
+               sig = SIGSEGV;
+               code = SEGV_ACCERR;
+       } else {
+               sig = SIGBUS;
+               code = BUS_ADRALN;
        }
-       _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+       if (user_mode(regs))
+               _exception(sig, regs, code, regs->dar);
+       else
+               bad_page_fault(regs, regs->dar, sig);
 }
 
 void StackOverflow(struct pt_regs *regs)
index 1d997ffd7931d859053cbd30ed16efddd5524c79..f7d0e304d899737e9292d66d31e27a1e1cc948a2 100644 (file)
 #include <asm/io.h>
 #include <asm/machvec.h>
 
-static void __init hs7751rvoip_init_irq(void)
-{
+static struct ipr_data hs77501rvoip_ipr_map[] = {
 #if defined(CONFIG_HS7751RVOIP_CODEC)
-       make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-       make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+       { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
 #endif
+};
+
+static void __init hs7751rvoip_init_irq(void)
+{
+       make_ipr_irq(hs77501rvoip_ipr_map, ARRAY_SIZE(hs77501rvoip_ipr_map));
 
        init_hs7751rvoip_IRQ();
 }
index e57e7afab8c660392d269d5490b3503b5b7bb784..180810b121076090acb5e215cb26898859c14d01 100644 (file)
 #include <asm/io.h>
 #include <asm/irq.h>
 
+static struct ipr_data sh7710voipgw_ipr_map[] = {
+       { TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY },
+       { WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY },
+
+       /* SCIF0 */
+       { SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+       { SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+       { SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+       { SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+
+       /* DMAC-1 */
+       { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+
+       /* DMAC-2 */
+       { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+       { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+
+       /* IPSEC */
+       { IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY },
+
+       /* EDMAC */
+       { EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, EDMAC0_PRIORITY },
+       { EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, EDMAC1_PRIORITY },
+       { EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, EDMAC2_PRIORITY },
+
+       /* SIOF0 */
+       { SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+       { SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+       { SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+       { SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+
+       /* SIOF1 */
+       { SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+       { SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+       { SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+       { SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY },
+
+       /* SLIC IRQ's */
+       { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
+       { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -37,65 +82,7 @@ static void __init sh7710voipgw_init_irq(void)
         */
        ctrl_outw(0x2aa, INTC_ICR1);
 
-       /* Now make IPR interrupts */
-       make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR,
-                       TIMER2_IPR_POS, TIMER2_PRIORITY);
-       make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY);
-
-       /* SCIF0 */
-       make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-                       SCIF0_PRIORITY);
-       make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-                       SCIF0_PRIORITY);
-       make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-                       SCIF0_PRIORITY);
-       make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
-                       SCIF0_PRIORITY);
-
-       /* DMAC-1 */
-       make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-       make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-       make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-       make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-
-       /* DMAC-2 */
-       make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-       make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-
-       /* IPSEC */
-       make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY);
-
-       /* EDMAC */
-       make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS,
-                       EDMAC0_PRIORITY);
-       make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS,
-                       EDMAC1_PRIORITY);
-       make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS,
-                       EDMAC2_PRIORITY);
-
-       /* SIOF0 */
-       make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-                       SIOF0_PRIORITY);
-       make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-                       SIOF0_PRIORITY);
-       make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-                       SIOF0_PRIORITY);
-       make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
-                       SIOF0_PRIORITY);
-
-       /* SIOF1 */
-       make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-                       SIOF1_PRIORITY);
-       make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-                       SIOF1_PRIORITY);
-       make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-                       SIOF1_PRIORITY);
-       make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
-                       SIOF1_PRIORITY);
-
-       /* SLIC IRQ's */
-       make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
-       make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
+       make_ipr_irq(sh7710voipgw_ipr_map, ARRAY_SIZE(sh7710voipgw_ipr_map));
 }
 
 /*
index ad1034f98a293ba4dfeb0259369538458e299f83..1279d776d60fb0a3ce3e82cf070e218ac04b665c 100644 (file)
 #include <asm/io.h>
 #include <asm/se7300.h>
 
+static struct ipr_data se7300_ipr_map[] = {
+       /* PC_IRQ[0-3] -> IRQ0 (32) */
+       { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ },
+       /* A_IRQ[0-3] -> IRQ1 (33) */
+       { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ },
+       { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+       { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -23,14 +34,7 @@ init_7300se_IRQ(void)
        ctrl_outw(0xa000, INTC_ICR1);           /* IRQ mode; IRQ0,1 enable.    */
        ctrl_outw(0x0000, PORT_PFCR);           /* use F for IRQ[3:0] and SIU. */
 
-       /* PC_IRQ[0-3] -> IRQ0 (32) */
-       make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ);
-       /* A_IRQ[0-3] -> IRQ1 (33) */
-       make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ);
-       make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
-       make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
+       make_ipr_irq(se7300_ipr_map, ARRAY_SIZE(se7300_ipr_map));
 
        ctrl_outw(0x2000, PA_MRSHPC + 0x0c);    /* mrshpc irq enable */
 }
index 2c62b8ea350ee8e3d214ed9de51b31d920035f7a..e7200c56bb45bb3c1e5ab3c3058aa1ff68e5226d 100644 (file)
@@ -87,13 +87,38 @@ shmse_irq_demux(int irq)
        return irq;
 }
 
+static struct ipr_data se73180_siof0_ipr_map[] = {
+       { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+};
+static struct ipr_data se73180_vpu_ipr_map[] = {
+       { VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 },
+};
+static struct ipr_data se73180_other_ipr_map[] = {
+       { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+       { IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+       { IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+       { IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+       { IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+       { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+       { SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY },
+
+       /* VIO interrupt */
+       { CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+       { BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+       { VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+
+       { LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
 void __init
 init_73180se_IRQ(void)
 {
-       make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
+       make_ipr_irq(se73180_siof0_ipr_map, ARRAY_SIZE(se73180_siof0_ipr_map));
 
        ctrl_outw(0x2000, 0xb03fffec);  /* mrshpc irq enable */
        ctrl_outw(0x2000, 0xb07fffec);  /* mrshpc irq enable */
@@ -101,27 +126,11 @@ init_73180se_IRQ(void)
        ctrl_outw(2 << ((7 - 5) * 2), INTC_ICR1);       /* low-level irq */
        make_intreq_irq(10);
 
-       make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
+       make_ipr_irq(se73180_vpu_ipr_map, ARRAY_SIZE(se73180_vpu_ipr_map));
 
        ctrl_outb(0x0f, INTC_IMCR5);    /* enable SCIF IRQ */
 
-       make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-       make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-       make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-                    IIC0_PRIORITY);
-       make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-                    IIC0_PRIORITY);
-       make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-       make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
-       make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
-
-       /* VIO interrupt */
-       make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-       make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-       make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
+       make_ipr_irq(se73180_other_ipr_map, ARRAY_SIZE(se73180_other_ipr_map));
 
-       make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
        ctrl_outw(0x2000, PA_MRSHPC + 0x0c);    /* mrshpc irq enable */
 }
index 288b62f59419990c8e50ab42a261308831278d24..360153ecc55b53dd3249d2cea9be96e39d9b2f99 100644 (file)
@@ -102,6 +102,51 @@ shmse_irq_demux(int irq)
 static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade",
                                NULL, NULL};
 
+static struct ipr_data se7343_irq5_ipr_map[] = {
+       { IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY },
+};
+static struct ipr_data se7343_siof0_vpu_ipr_map[] = {
+       { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+       { VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 },
+};
+static struct ipr_data se7343_other_ipr_map[] = {
+       { DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+       { DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY },
+
+       /* I2C block */
+       { IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+       { IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+       { IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+       { IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY },
+
+       { IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+       { IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+       { IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+       { IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY },
+
+       /* SIOF */
+       { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY },
+
+       /* SIU */
+       { SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY },
+
+       /* VIO interrupt */
+       { CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+       { BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+       { VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
+
+       /*MFI interrupt*/
+
+       { MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY },
+
+       /* LCD controller */
+       { LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY },
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -138,54 +183,17 @@ init_7343se_IRQ(void)
        /* Setup all external interrupts to be active low */
        ctrl_outw(0xaaaa, INTC_ICR1);
 
-       make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY);
+       make_ipr_irq(se7343_irq5_ipr_map, ARRAY_SIZE(se7343_irq5_ipr_map));
+
        setup_irq(IRQ5_IRQ, &irq5);
        /* Set port control to use IRQ5 */
        *(u16 *)0xA4050108 &= ~0xc;
 
-       make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
-       make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
+       make_ipr_irq(se7343_siof0_vpu_ipr_map, ARRAY_SIZE(se7343_siof0_vpu_ipr_map));
 
        ctrl_outb(0x0f, INTC_IMCR5);    /* enable SCIF IRQ */
 
-       make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-       make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
-
-       /* I2C block */
-       make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-       make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-                    IIC0_PRIORITY);
-       make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
-                    IIC0_PRIORITY);
-       make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
-
-       make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
-       make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
-                    IIC1_PRIORITY);
-       make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
-                    IIC1_PRIORITY);
-       make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
-
-       /* SIOF */
-       make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
+       make_ipr_irq(se7343_other_ipr_map, ARRAY_SIZE(se7343_other_ipr_map));
 
-       /* SIU */
-       make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
-
-       /* VIO interrupt */
-       make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-       make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-       make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
-
-       /*MFI interrupt*/
-
-       make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY);
-
-       /* LCD controller */
-       make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
        ctrl_outw(0x2000, PA_MRSHPC + 0x0c);    /* mrshpc irq enable */
 }
index cff6700bbafd4f98878e462c9121a3057bd87acf..fcd7cd7fa05f1d8f623f8981a616078edcda8ae9 100644 (file)
 #include <asm/io.h>
 #include <asm/se.h>
 
+static struct ipr_data se770x_ipr_map[] = {
+#if defined(CONFIG_CPU_SUBTYPE_SH7705)
+       /* This is default value */
+       { 0xf-0x2, BCR_ILCRA, 2, 0x2 },
+       { 0xf-0xa, BCR_ILCRA, 1, 0xa },
+       { 0xf-0x5, BCR_ILCRB, 0, 0x5 },
+       { 0xf-0x8, BCR_ILCRC, 1, 0x8 },
+       { 0xf-0xc, BCR_ILCRC, 0, 0xc },
+       { 0xf-0xe, BCR_ILCRD, 3, 0xe },
+       { 0xf-0x3, BCR_ILCRD, 1, 0x3 }, /* LAN */
+       { 0xf-0xd, BCR_ILCRE, 2, 0xd },
+       { 0xf-0x9, BCR_ILCRE, 1, 0x9 },
+       { 0xf-0x1, BCR_ILCRE, 0, 0x1 },
+       { 0xf-0xf, BCR_ILCRF, 3, 0xf },
+       { 0xf-0xb, BCR_ILCRF, 1, 0xb },
+       { 0xf-0x7, BCR_ILCRG, 3, 0x7 },
+       { 0xf-0x6, BCR_ILCRG, 2, 0x6 },
+       { 0xf-0x4, BCR_ILCRG, 1, 0x4 },
+#else
+       { 14, BCR_ILCRA, 2, 0x0f-14 },
+       { 12, BCR_ILCRA, 1, 0x0f-12 },
+       {  8, BCR_ILCRB, 1, 0x0f- 8 },
+       {  6, BCR_ILCRC, 3, 0x0f- 6 },
+       {  5, BCR_ILCRC, 2, 0x0f- 5 },
+       {  4, BCR_ILCRC, 1, 0x0f- 4 },
+       {  3, BCR_ILCRC, 0, 0x0f- 3 },
+       {  1, BCR_ILCRD, 3, 0x0f- 1 },
+
+       { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */
+
+       {  0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */
+       { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */
+       {  9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */
+       {  7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */
+
+       /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+       /* NOTE: #2 and #13 are not used on PC */
+       { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */
+       {  2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */
+#endif
+};
+
 /*
  * Initialize IRQ setting
  */
@@ -38,42 +80,6 @@ void __init init_se_IRQ(void)
        ctrl_outw(0, BCR_ILCRE);
        ctrl_outw(0, BCR_ILCRF);
        ctrl_outw(0, BCR_ILCRG);
-       /* This is default value */
-       make_ipr_irq(0xf-0x2, BCR_ILCRA, 2, 0x2);
-       make_ipr_irq(0xf-0xa, BCR_ILCRA, 1, 0xa);
-       make_ipr_irq(0xf-0x5, BCR_ILCRB, 0, 0x5);
-       make_ipr_irq(0xf-0x8, BCR_ILCRC, 1, 0x8);
-       make_ipr_irq(0xf-0xc, BCR_ILCRC, 0, 0xc);
-       make_ipr_irq(0xf-0xe, BCR_ILCRD, 3, 0xe);
-       make_ipr_irq(0xf-0x3, BCR_ILCRD, 1, 0x3); /* LAN */
-       make_ipr_irq(0xf-0xd, BCR_ILCRE, 2, 0xd);
-       make_ipr_irq(0xf-0x9, BCR_ILCRE, 1, 0x9);
-       make_ipr_irq(0xf-0x1, BCR_ILCRE, 0, 0x1);
-       make_ipr_irq(0xf-0xf, BCR_ILCRF, 3, 0xf);
-       make_ipr_irq(0xf-0xb, BCR_ILCRF, 1, 0xb);
-       make_ipr_irq(0xf-0x7, BCR_ILCRG, 3, 0x7);
-       make_ipr_irq(0xf-0x6, BCR_ILCRG, 2, 0x6);
-       make_ipr_irq(0xf-0x4, BCR_ILCRG, 1, 0x4);
-#else
-        make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
-        make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
-        make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
-        make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
-        make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
-        make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
-        make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
-        make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
-
-        make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
-
-        make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
-        make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
-        make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
-        make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
-
-        /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
-        /* NOTE: #2 and #13 are not used on PC */
-        make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
-        make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
 #endif
+       make_ipr_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map));
 }
index c607b0a48479d87b14ebff2d81263f8ae650cca1..e4c63a48296cbf6d0ea6956f197ac6c58141399e 100644 (file)
 #include <asm/irq.h>
 #include <asm/se7751.h>
 
-/*
- * Initialize IRQ setting
- */
-void __init init_7751se_IRQ(void)
-{
-
+static struct ipr_data se7751_ipr_map[] = {
   /* Leave old Solution Engine code in for reference. */
 #if defined(CONFIG_SH_SOLUTION_ENGINE)
-        /*
-         * Super I/O (Just mimic PC):
-         *  1: keyboard
-         *  3: serial 0
-         *  4: serial 1
-         *  5: printer
-         *  6: floppy
-         *  8: rtc
-         * 12: mouse
-         * 14: ide0
-         */
-        make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14);
-        make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12);
-        make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8);
-        make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6);
-        make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5);
-        make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4);
-        make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3);
-        make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1);
-
-        make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */
-
-        make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */
-        make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */
-        make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */
-        make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */
-
-        /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
-        /* NOTE: #2 and #13 are not used on PC */
-        make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */
-        make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */
-
+       /*
+        * Super I/O (Just mimic PC):
+        *  1: keyboard
+        *  3: serial 0
+        *  4: serial 1
+        *  5: printer
+        *  6: floppy
+        *  8: rtc
+        * 12: mouse
+        * 14: ide0
+        */
+       { 14, BCR_ILCRA, 2, 0x0f-14 },
+       { 12, BCR_ILCRA, 1, 0x0f-12 },
+       {  8, BCR_ILCRB, 1, 0x0f- 8 },
+       {  6, BCR_ILCRC, 3, 0x0f- 6 },
+       {  5, BCR_ILCRC, 2, 0x0f- 5 },
+       {  4, BCR_ILCRC, 1, 0x0f- 4 },
+       {  3, BCR_ILCRC, 0, 0x0f- 3 },
+       {  1, BCR_ILCRD, 3, 0x0f- 1 },
+
+       { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */
+
+       {  0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */
+       { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */
+       {  9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */
+       {  7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */
+
+       /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */
+       /* NOTE: #2 and #13 are not used on PC */
+       { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */
+       {  2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */
 #elif defined(CONFIG_SH_7751_SOLUTION_ENGINE)
-
-        make_ipr_irq(13, BCR_ILCRD, 3, 2);
-
-        /* Add additional calls to make_ipr_irq() as drivers are added
-         * and tested.
-         */
+       { 13, BCR_ILCRD, 3, 2 },
+       /* Add additional entries here as drivers are added and tested. */
 #endif
+};
 
+/*
+ * Initialize IRQ setting
+ */
+void __init init_7751se_IRQ(void)
+{
+       make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map));
 }
index 137e2ba9243e82a85f222e455f852f357df3a5d9..5ad1e19771be79cdcd924d0dda701a54253a8f65 100644 (file)
 #include <asm/sh03/sh03.h>
 #include <asm/addrspace.h>
 
+static struct ipr_data sh03_ipr_map[] = {
+       { IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY },
+       { IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY },
+       { IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY },
+       { IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY },
+};
+
 static void __init init_sh03_IRQ(void)
 {
        ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
-
-       make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
-       make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
-       make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
-       make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+       make_ipr_irq(sh03_ipr_map, ARRAY_SIZE(sh03_ipr_map));
 }
 
 extern void *cf_io_base;
index 540d0bf16446e6edf6f3375e99661d5712ded7ce..650fb36459472e1866cee0aa5064b3b6f3488341 100644 (file)
@@ -68,6 +68,13 @@ module_init(eraseconfig_init);
  * IRL3 = crypto
  */
 
+static struct ipr_data snapgear_ipr_map[] = {
+       make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
+       make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
+       make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
+       make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+};
+
 static void __init init_snapgear_IRQ(void)
 {
        /* enable individual interrupt mode for externals */
@@ -75,10 +82,7 @@ static void __init init_snapgear_IRQ(void)
 
        printk("Setup SnapGear IRQ/IPR ...\n");
 
-       make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY);
-       make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY);
-       make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY);
-       make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
+       make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map));
 }
 
 /*
index 52b66d8b8d2a429495416ddbdcde3839c631d8e2..a6046d93758b80430d25d422c6374bb755061a63 100644 (file)
@@ -9,15 +9,19 @@
 
 extern void __init pcibios_init_platform(void);
 
+static struct ipr_data titan_ipr_map[] = {
+       { TITAN_IRQ_WAN,        IRL0_IPR_ADDR,  IRL0_IPR_POS,   IRL0_PRIORITY },
+       { TITAN_IRQ_LAN,        IRL1_IPR_ADDR,  IRL1_IPR_POS,   IRL1_PRIORITY },
+       { TITAN_IRQ_MPCIA,      IRL2_IPR_ADDR,  IRL2_IPR_POS,   IRL2_PRIORITY },
+       { TITAN_IRQ_USB,        IRL3_IPR_ADDR,  IRL3_IPR_POS,   IRL3_PRIORITY },
+};
+
 static void __init init_titan_irq(void)
 {
        /* enable individual interrupt mode for externals */
        ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
 
-       make_ipr_irq( TITAN_IRQ_WAN,   IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); /* PCIRQ0 */
-       make_ipr_irq( TITAN_IRQ_LAN,   IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); /* PCIRQ1 */
-       make_ipr_irq( TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); /* PCIRQ2 */
-       make_ipr_irq( TITAN_IRQ_USB,   IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); /* PCIRQ3 */
+       make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map));
 }
 
 struct sh_machine_vector mv_titan __initmv = {
index 2470364948e75aa007d53597204194bbe6900171..34e2046c3213db5e69ac9492ef687401fd70813a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 11:32:47 2006
+# Linux kernel version: 2.6.19-rc3
+# Tue Oct 31 12:32:06 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -178,7 +179,7 @@ CONFIG_MMU=y
 CONFIG_PAGE_OFFSET=0x80000000
 CONFIG_MEMORY_START=0x08000000
 CONFIG_MEMORY_SIZE=0x08000000
-CONFIG_32BIT=y
+# CONFIG_32BIT is not set
 CONFIG_VSYSCALL=y
 CONFIG_HUGETLB_PAGE_SIZE_64K=y
 # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
@@ -229,9 +230,7 @@ CONFIG_SH_PCLK_FREQ=32000000
 #
 # DMA support
 #
-CONFIG_SH_DMA=y
-CONFIG_NR_ONCHIP_DMA_CHANNELS=6
-# CONFIG_NR_DMA_CHANNELS_BOOL is not set
+# CONFIG_SH_DMA is not set
 
 #
 # Companion Chips
@@ -259,7 +258,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x00800000
 # CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/hda1"
+CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/sda1"
 
 #
 # Bus options
@@ -336,6 +335,7 @@ CONFIG_IP_PNP_DHCP=y
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -440,77 +440,29 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
 #
 # ATA/ATAPI/MFM/RLL support
 #
-CONFIG_IDE=m
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-CONFIG_BLK_DEV_IDE_SATA=y
-CONFIG_BLK_DEV_IDEDISK=m
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-CONFIG_BLK_DEV_IDESCSI=m
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=m
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_AEC62XX=m
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-CONFIG_BLK_DEV_PDC202XX_NEW=m
-# CONFIG_BLK_DEV_SVWKS is not set
-CONFIG_BLK_DEV_SIIMAGE=m
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
+# CONFIG_IDE is not set
 
 #
 # SCSI device support
 #
 # CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=m
+CONFIG_SCSI=y
 # CONFIG_SCSI_NETLINK is not set
 CONFIG_SCSI_PROC_FS=y
 
 #
 # SCSI support type (disk, tape, CD-ROM)
 #
-CONFIG_BLK_DEV_SD=m
+CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
@@ -561,6 +513,7 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -570,7 +523,55 @@ CONFIG_CHR_DEV_SG=m
 #
 # Serial ATA (prod) and Parallel ATA (experimental) drivers
 #
-# CONFIG_ATA is not set
+CONFIG_ATA=y
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_SATA_SIL=y
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
 
 #
 # Multi-device support (RAID and LVM)
@@ -840,7 +841,6 @@ CONFIG_HW_RANDOM=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -856,6 +856,7 @@ CONFIG_HW_RANDOM=y
 #
 # Dallas's 1-wire bus
 #
+# CONFIG_W1 is not set
 
 #
 # Hardware Monitoring support
@@ -867,15 +868,10 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
-#
-# Misc devices
-#
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -959,7 +955,29 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 # Real Time Clock
 #
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
 # DMA Engine support
@@ -984,6 +1002,7 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
@@ -991,6 +1010,7 @@ CONFIG_FS_MBCACHE=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
@@ -1027,7 +1047,8 @@ CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
@@ -1159,6 +1180,7 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_LIST is not set
 CONFIG_FRAME_POINTER=y
 CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1178,9 +1200,9 @@ CONFIG_FORCED_INLINING=y
 #
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
 # CONFIG_CRYPTO_NULL is not set
 # CONFIG_CRYPTO_MD4 is not set
@@ -1191,7 +1213,7 @@ CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
 CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
index 5e817546113893289a6ccfdf3d1da879690ed8e6..41049cf14b791100cfe2c8e2013f30d7044e0597 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.18
-# Tue Oct  3 12:59:14 2006
+# Linux kernel version: 2.6.19-rc3
+# Mon Oct 30 18:04:49 2006
 #
 CONFIG_SUPERH=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
@@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_GENERIC_TIME is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -23,7 +24,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 # General setup
 #
 CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 # CONFIG_IPC_NS is not set
@@ -236,8 +237,8 @@ CONFIG_HZ_250=y
 CONFIG_HZ=250
 # CONFIG_KEXEC is not set
 # CONFIG_SMP is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
 # CONFIG_PREEMPT is not set
 
 #
@@ -247,7 +248,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000
 CONFIG_BOOT_LINK_OFFSET=0x009e0000
 # CONFIG_UBC_WAKEUP is not set
 CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf"
+CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw"
 
 #
 # Bus options
@@ -334,6 +335,7 @@ CONFIG_INET_XFRM_TUNNEL=y
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_XFRM_MODE_TRANSPORT=y
 CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
 CONFIG_INET_DIAG=m
 CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
@@ -355,9 +357,10 @@ CONFIG_INET6_XFRM_TUNNEL=y
 CONFIG_INET6_TUNNEL=y
 CONFIG_INET6_XFRM_MODE_TRANSPORT=y
 CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
 # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
 CONFIG_IPV6_TUNNEL=y
-# CONFIG_IPV6_SUBTREES is not set
 # CONFIG_IPV6_MULTIPLE_TABLES is not set
 # CONFIG_NETWORK_SECMARK is not set
 CONFIG_NETFILTER=y
@@ -713,6 +716,12 @@ CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 CONFIG_ATA_OVER_ETH=m
 
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
 #
 # ATA/ATAPI/MFM/RLL support
 #
@@ -778,9 +787,9 @@ CONFIG_CHR_DEV_SG=m
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
 # CONFIG_SCSI_LPFC is not set
 # CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
@@ -1095,7 +1104,6 @@ CONFIG_HW_RANDOM=y
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -1123,15 +1131,10 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_VT1211 is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
-#
-# Misc devices
-#
-
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
-CONFIG_VIDEO_V4L2=y
 
 #
 # Digital Video Broadcasting Devices
@@ -1177,9 +1180,9 @@ CONFIG_USB_DEVICEFS=y
 # USB Host Controller Drivers
 #
 CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_SPLIT_ISO=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 # CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1235,7 +1238,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ATI_REMOTE2 is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
 # CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
 
 #
 # USB Imaging devices
@@ -1246,11 +1248,20 @@ CONFIG_USB_STORAGE=y
 #
 # USB Network Adapters
 #
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_GL620A is not set
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+CONFIG_USB_NET_ZAURUS=m
 CONFIG_USB_MON=y
 
 #
@@ -1285,6 +1296,7 @@ CONFIG_USB_SERIAL_ARK3116=m
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
 # CONFIG_USB_SERIAL_MOS7840 is not set
 # CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
@@ -1316,6 +1328,7 @@ CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_APPLEDISPLAY is not set
 # CONFIG_USB_SISUSBVGA is not set
 # CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_TEST is not set
 
 #
@@ -1357,7 +1370,26 @@ CONFIG_USB_SERIAL_PL2303=m
 #
 # Real Time Clock
 #
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=m
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=m
+CONFIG_RTC_INTF_PROC=m
+CONFIG_RTC_INTF_DEV=m
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+CONFIG_RTC_DRV_SH=m
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
 
 #
 # DMA Engine support
@@ -1380,8 +1412,12 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT4DEV_FS=m
+# CONFIG_EXT4DEV_FS_XATTR is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=m
+# CONFIG_JBD2_DEBUG is not set
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -1393,9 +1429,10 @@ CONFIG_XFS_FS=m
 # CONFIG_XFS_SECURITY is not set
 # CONFIG_XFS_POSIX_ACL is not set
 # CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_ROMFS_FS=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
@@ -1480,7 +1517,12 @@ CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+CONFIG_CIFS_WEAK_PW_HASH=y
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1583,9 +1625,10 @@ CONFIG_LOG_BUF_SHIFT=16
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_FORCED_INLINING is not set
+# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_SH_STANDARD_BIOS is not set
-CONFIG_EARLY_SCIF_CONSOLE=y
+# CONFIG_EARLY_SCIF_CONSOLE is not set
 # CONFIG_EARLY_PRINTK is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
@@ -1605,7 +1648,7 @@ CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_BLKCIPHER=y
 CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_MD4=m
@@ -1615,7 +1658,7 @@ CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_BLOWFISH=m
index d8ece20bb2cf078fd913facab2fdc4def5d1f384..66078601335009804e06213b82bef57a324b4765 100644 (file)
 #include <asm/io.h>
 #include "dma-sh.h"
 
-static inline unsigned int get_dmte_irq(unsigned int chan)
-{
-       unsigned int irq = 0;
 
+
+#ifdef CONFIG_CPU_SH4
+static struct ipr_data dmae_ipr_map[] = {
+       { DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+};
+#endif
+static struct ipr_data dmte_ipr_map[] = {
        /*
         * Normally we could just do DMTE0_IRQ + chan outright, though in the
         * case of the 7751R, the DMTE IRQs for channels > 4 start right above
         * the SCIF
         */
-       if (chan < 4) {
-               irq = DMTE0_IRQ + chan;
-       } else {
-#ifdef DMTE4_IRQ
-               irq = DMTE4_IRQ + chan - 4;
-#endif
-       }
+       { DMTE0_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE0_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE0_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE0_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+       { DMTE4_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY },
+};
 
+static inline unsigned int get_dmte_irq(unsigned int chan)
+{
+       unsigned int irq = 0;
+       if (chan < ARRAY_SIZE(dmte_ipr_map))
+               irq = dmte_ipr_map[chan].irq;
        return irq;
 }
 
@@ -258,17 +269,16 @@ static int __init sh_dmac_init(void)
        int i;
 
 #ifdef CONFIG_CPU_SH4
-       make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
+       make_ipr_irq(dmae_ipr_map, ARRAY_SIZE(dmae_ipr_map));
        i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
        if (unlikely(i < 0))
                return i;
 #endif
 
-       for (i = 0; i < info->nr_channels; i++) {
-               int irq = get_dmte_irq(i);
-
-               make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
-       }
+       i = info->nr_channels;
+       if (i > ARRAY_SIZE(dmte_ipr_map))
+               i = ARRAY_SIZE(dmte_ipr_map);
+       make_ipr_irq(dmte_ipr_map, i);
 
        /*
         * Initialize DMAOR, and clean up any error flags that may have
index f7997312ef988e4016aa72411494eae994c34af6..a0089563cbfcfef2d7618a45c97e401185e0d86c 100644 (file)
 #include <asm/io.h>
 #include <asm/machvec.h>
 
-struct ipr_data {
-       unsigned int addr;      /* Address of Interrupt Priority Register */
-       int shift;              /* Shifts of the 16-bit data */
-       int priority;           /* The priority */
-};
 
 static void disable_ipr_irq(unsigned int irq)
 {
        struct ipr_data *p = get_irq_chip_data(irq);
+       int shift = p->shift*4;
        /* Set the priority in IPR to 0 */
-       ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
+       ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr);
 }
 
 static void enable_ipr_irq(unsigned int irq)
 {
        struct ipr_data *p = get_irq_chip_data(irq);
+       int shift = p->shift*4;
        /* Set priority in IPR back to original value */
-       ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
+       ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr);
 }
 
 static struct irq_chip ipr_irq_chip = {
@@ -50,67 +47,57 @@ static struct irq_chip ipr_irq_chip = {
        .mask_ack       = disable_ipr_irq,
 };
 
-void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
+void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs)
 {
-       struct ipr_data ipr_data;
-
-       disable_irq_nosync(irq);
-
-       ipr_data.addr = addr;
-       ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */
-       ipr_data.priority = priority;
+       int i;
 
-       set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
+       for (i = 0; i < nr_irqs; i++) {
+               unsigned int irq = table[i].irq;
+               disable_irq_nosync(irq);
+               set_irq_chip_and_handler_name(irq, &ipr_irq_chip,
                                      handle_level_irq, "level");
-       set_irq_chip_data(irq, &ipr_data);
-
-       enable_ipr_irq(irq);
+               set_irq_chip_data(irq, &table[i]);
+               enable_ipr_irq(irq);
+       }
 }
+EXPORT_SYMBOL(make_ipr_irq);
 
-/* XXX: This needs to die a horrible death.. */
-void __init init_IRQ(void)
-{
+static struct ipr_data sys_ipr_map[] = {
 #ifndef CONFIG_CPU_SUBTYPE_SH7780
-       make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
-       make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
+       { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY },
+       { TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY },
 #ifdef RTC_IRQ
-       make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
+       { RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY },
 #endif
-
 #ifdef SCI_ERI_IRQ
-       make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-       make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
-       make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY);
+       { SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
+       { SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
+       { SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY },
 #endif
-
 #ifdef SCIF1_ERI_IRQ
-       make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-       make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-       make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
-       make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY);
+       { SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+       { SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+       { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
+       { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY },
 #endif
-
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
-       make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY);
-       make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
-       make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
+       { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY },
+       { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY },
+       { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY },
 #endif
-
 #ifdef SCIF_ERI_IRQ
-       make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-       make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-       make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
-       make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+       { SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+       { SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+       { SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
+       { SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY },
 #endif
-
 #ifdef IRDA_ERI_IRQ
-       make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-       make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-       make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
-       make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+       { IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+       { IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+       { IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
+       { IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY },
 #endif
-
 #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
     defined(CONFIG_CPU_SUBTYPE_SH7706) || \
     defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
@@ -124,14 +111,19 @@ void __init init_IRQ(void)
         * You should set corresponding bits of PFC to "00"
         * to enable these interrupts.
         */
-       make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY);
-       make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
-       make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
-       make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY);
-       make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY);
-       make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY);
+       { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY },
+       { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY },
+       { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY },
+       { IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY },
+       { IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY },
+       { IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY },
 #endif
 #endif
+};
+
+void __init init_IRQ(void)
+{
+       make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map));
 
 #ifdef CONFIG_CPU_HAS_PINT_IRQ
        init_IRQ_pint();
@@ -153,5 +145,3 @@ int ipr_irq_demux(int irq)
        return irq;
 }
 #endif
-
-EXPORT_SYMBOL(make_ipr_irq);
index 17f47b373d6ed2cb0ea49bfb8f05f0f5a799e9d8..f60007783a2117d275bb5a0adf82b60b80de7291 100644 (file)
@@ -84,12 +84,16 @@ void make_pint_irq(unsigned int irq)
        disable_pint_irq(irq);
 }
 
+static struct ipr_data pint_ipr_map[] = {
+       { PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY },
+       { PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY },
+};
+
 void __init init_IRQ_pint(void)
 {
        int i;
 
-       make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY);
-       make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY);
+       make_ipr_irq(pint_ipr_map, ARRAY_SIZE(pint_ipr_map));
 
        enable_irq(PINT0_IRQ);
        enable_irq(PINT8_IRQ);
index 768334e950753f31f4f86f78f3cd7dfa9a7d293a..ca81976e9e3485fb01f0a45d811f5e9a0bab702a 100644 (file)
@@ -351,3 +351,6 @@ ENTRY(sys_call_table)
        .long sys_sync_file_range
        .long sys_tee                   /* 315 */
        .long sys_vmsplice
+       .long sys_move_pages
+       .long sys_getcpu
+       .long sys_epoll_pwait
index c60efb3cb22e037feec3b3017e0d8aef80f8d883..0917c24c4f08fe993967b64ae35ff89466185731 100644 (file)
@@ -793,7 +793,7 @@ static unsigned int schizo_irq_build(struct device_node *dp,
        return virt_irq;
 }
 
-static void schizo_irq_trans_init(struct device_node *dp)
+static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo)
 {
        struct linux_prom64_registers *regs;
        struct schizo_irq_data *irq_data;
@@ -807,11 +807,24 @@ static void schizo_irq_trans_init(struct device_node *dp)
        dp->irq_trans->data = irq_data;
 
        irq_data->pbm_regs = regs[0].phys_addr;
-       irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
+       if (is_tomatillo)
+               irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL;
+       else
+               irq_data->sync_reg = 0UL;
        irq_data->portid = of_getintprop_default(dp, "portid", 0);
        irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
 }
 
+static void schizo_irq_trans_init(struct device_node *dp)
+{
+       __schizo_irq_trans_init(dp, 0);
+}
+
+static void tomatillo_irq_trans_init(struct device_node *dp)
+{
+       __schizo_irq_trans_init(dp, 1);
+}
+
 static unsigned int pci_sun4v_irq_build(struct device_node *dp,
                                        unsigned int devino,
                                        void *_data)
@@ -1050,8 +1063,8 @@ static struct irq_trans pci_irq_trans_table[] = {
        { "pci108e,8001", schizo_irq_trans_init },
        { "SUNW,schizo+", schizo_irq_trans_init },
        { "pci108e,8002", schizo_irq_trans_init },
-       { "SUNW,tomatillo", schizo_irq_trans_init },
-       { "pci108e,a801", schizo_irq_trans_init },
+       { "SUNW,tomatillo", tomatillo_irq_trans_init },
+       { "pci108e,a801", tomatillo_irq_trans_init },
        { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
 };
 #endif
index 68420e2dad0eb2c28857ce854563165fe62570fc..fe1796c939c395618e945b18b017c75d8717f5ed 100644 (file)
@@ -87,6 +87,7 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
                       i + 1,
                       p->trapstack[i].tstate, p->trapstack[i].tpc,
                       p->trapstack[i].tnpc, p->trapstack[i].tt);
+               print_symbol("TRAPLOG: TPC<%s>\n", p->trapstack[i].tpc);
        }
 }
 
@@ -1134,6 +1135,9 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in
        printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n",
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
               regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate);
+       printk("%s" "ERROR(%d): ",
+              (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id());
+       print_symbol("TPC<%s>\n", regs->tpc);
        printk("%s" "ERROR(%d): M_SYND(%lx),  E_SYND(%lx)%s%s\n",
               (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
               (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
@@ -1741,6 +1745,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
                       smp_processor_id(),
                       (type & 0x1) ? 'I' : 'D',
                       regs->tpc);
+               print_symbol(KERN_EMERG "TPC<%s>\n", regs->tpc);
                panic("Irrecoverable Cheetah+ parity error.");
        }
 
@@ -1748,6 +1753,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs)
               smp_processor_id(),
               (type & 0x1) ? 'I' : 'D',
               regs->tpc);
+       print_symbol(KERN_WARNING "TPC<%s>\n", regs->tpc);
 }
 
 struct sun4v_error_entry {
@@ -1946,6 +1952,7 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl)
 
        printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n",
               regs->tpc, tl);
+       print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc);
        printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] "
               "pte[%lx] error[%lx]\n",
               sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx,
@@ -1966,6 +1973,7 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl)
 
        printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n",
               regs->tpc, tl);
+       print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc);
        printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] "
               "pte[%lx] error[%lx]\n",
               sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx,
index c8016a98483b9ea935732f9c55307b40391b56d8..5d5ed726faa0489d212f5e654ab0a5ecec714330 100644 (file)
@@ -64,9 +64,14 @@ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
 
 AFLAGS += $(ARCH_INCLUDE)
 
-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-       $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64
+USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
+       $(patsubst -I%,,$(CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
+       -D_FILE_OFFSET_BITS=64
+
+include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
+
+#This will adjust *FLAGS accordingly to the platform.
+include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
@@ -74,15 +79,11 @@ USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
 # errnos.
 # These apply to kernelspace only.
 
-CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
-       -Dmktime=kernel_mktime
+KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
+       -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES)
+CFLAGS += $(KERNEL_DEFINES)
 CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
-include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
-
-#This will adjust *FLAGS accordingly to the platform.
-include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
-
 # These are needed for clean and mrproper, since in that case .config is not
 # included; the values here are meaningless
 
index b65ca115ef7778553473a157998ada3c54869051..c9f1c5b24c9a34f723d0521111eb7e777d165302 100644 (file)
@@ -16,7 +16,6 @@ OBJCOPYFLAGS                  := -O binary -R .note -R .comment -S
 ifeq ("$(origin SUBARCH)", "command line")
 ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
 CFLAGS                 += $(call cc-option,-m32)
-USER_CFLAGS            += $(call cc-option,-m32)
 AFLAGS                 += $(call cc-option,-m32)
 LINK-y                 += $(call cc-option,-m32)
 UML_OBJCOPYFLAGS       += -F $(ELF_FORMAT)
@@ -25,7 +24,7 @@ export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS
 endif
 endif
 
-CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
+ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH)
 
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
 include $(srctree)/arch/i386/Makefile.cpu
@@ -38,4 +37,3 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
 cflags-y += -ffreestanding
 
 CFLAGS += $(cflags-y)
-USER_CFLAGS += $(cflags-y)
index d278682dd799dc51e47cad1341c62f34bae58e19..69ecea63fdae35f56a32115e417efb64ac822741 100644 (file)
@@ -8,8 +8,8 @@ _extra_flags_ = -fno-builtin -m64
 
 #We #undef __x86_64__ for kernelspace, not for userspace where
 #it's needed for headers to work!
-CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_)
-USER_CFLAGS += $(_extra_flags_)
+ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__
+CFLAGS += $(_extra_flags_)
 
 CHECKFLAGS  += -m64
 AFLAGS += -m64
index bc458f57921b0f232d0f078bc5014424281e8617..49c047b75cc556cbda484a5c6166d23d5b137f7c 100644 (file)
@@ -106,10 +106,15 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
 
 #define DRIVER_NAME "uml-blkdev"
 
+/* Can be taken in interrupt context, and is passed to the block layer to lock
+ * the request queue. Kernel side code knows that. */
 static DEFINE_SPINLOCK(ubd_io_lock);
-static DEFINE_SPINLOCK(ubd_lock);
 
-static void (*do_ubd)(void);
+static DEFINE_MUTEX(ubd_lock);
+
+/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and
+ * probably it doesn't make sense even for that. */
+static int do_ubd;
 
 static int ubd_open(struct inode * inode, struct file * filp);
 static int ubd_release(struct inode * inode, struct file * file);
@@ -117,7 +122,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
                     unsigned int cmd, unsigned long arg);
 static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
-#define MAX_DEV (8)
+#define MAX_DEV (16)
 
 static struct block_device_operations ubd_blops = {
         .owner         = THIS_MODULE,
@@ -150,8 +155,9 @@ static struct gendisk *fake_gendisk[MAX_DEV];
 static struct openflags global_openflags = OPEN_FLAGS;
 
 struct cow {
-       /* This is the backing file, actually */
+       /* backing file name */
        char *file;
+       /* backing file fd */
        int fd;
        unsigned long *bitmap;
        unsigned long bitmap_len;
@@ -160,14 +166,16 @@ struct cow {
 };
 
 struct ubd {
+       /* name (and fd, below) of the file opened for writing, either the
+        * backing or the cow file. */
        char *file;
        int count;
        int fd;
        __u64 size;
        struct openflags boot_openflags;
        struct openflags openflags;
-       int shared;
-       int no_cow;
+       unsigned shared:1;
+       unsigned no_cow:1;
        struct cow cow;
        struct platform_device pdev;
 };
@@ -192,18 +200,7 @@ struct ubd {
         .cow =                 DEFAULT_COW, \
 }
 
-struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
-
-static int ubd0_init(void)
-{
-       struct ubd *dev = &ubd_dev[0];
-
-       if(dev->file == NULL)
-               dev->file = "root_fs";
-       return(0);
-}
-
-__initcall(ubd0_init);
+struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
 
 /* Only changed by fake_ide_setup which is a setup */
 static int fake_ide = 0;
@@ -277,7 +274,7 @@ static int parse_unit(char **ptr)
                        return(-1);
                *ptr = end;
        }
-       else if (('a' <= *str) && (*str <= 'h')) {
+       else if (('a' <= *str) && (*str <= 'z')) {
                n = *str - 'a';
                str++;
                *ptr = str;
@@ -285,9 +282,13 @@ static int parse_unit(char **ptr)
        return(n);
 }
 
+/* If *index_out == -1 at exit, the passed option was a general one;
+ * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it
+ * should not be freed on exit.
+ */
 static int ubd_setup_common(char *str, int *index_out)
 {
-       struct ubd *dev;
+       struct ubd *ubd_dev;
        struct openflags flags = global_openflags;
        char *backing_file;
        int n, err, i;
@@ -311,7 +312,7 @@ static int ubd_setup_common(char *str, int *index_out)
                }
 
                err = 1;
-               spin_lock(&ubd_lock);
+               mutex_lock(&ubd_lock);
                if(fake_major != MAJOR_NR){
                        printk(KERN_ERR "Can't assign a fake major twice\n");
                        goto out1;
@@ -323,7 +324,7 @@ static int ubd_setup_common(char *str, int *index_out)
                       major);
                err = 0;
        out1:
-               spin_unlock(&ubd_lock);
+               mutex_unlock(&ubd_lock);
                return(err);
        }
 
@@ -340,10 +341,10 @@ static int ubd_setup_common(char *str, int *index_out)
        }
 
        err = 1;
-       spin_lock(&ubd_lock);
+       mutex_lock(&ubd_lock);
 
-       dev = &ubd_dev[n];
-       if(dev->file != NULL){
+       ubd_dev = &ubd_devs[n];
+       if(ubd_dev->file != NULL){
                printk(KERN_ERR "ubd_setup : device already configured\n");
                goto out;
        }
@@ -360,10 +361,10 @@ static int ubd_setup_common(char *str, int *index_out)
                        flags.s = 1;
                        break;
                case 'd':
-                       dev->no_cow = 1;
+                       ubd_dev->no_cow = 1;
                        break;
                case 'c':
-                       dev->shared = 1;
+                       ubd_dev->shared = 1;
                        break;
                case '=':
                        str++;
@@ -390,7 +391,7 @@ break_loop:
        }
 
        if(backing_file){
-               if(dev->no_cow)
+               if(ubd_dev->no_cow)
                        printk(KERN_ERR "Can't specify both 'd' and a "
                               "cow file\n");
                else {
@@ -398,11 +399,11 @@ break_loop:
                        backing_file++;
                }
        }
-       dev->file = str;
-       dev->cow.file = backing_file;
-       dev->boot_openflags = flags;
+       ubd_dev->file = str;
+       ubd_dev->cow.file = backing_file;
+       ubd_dev->boot_openflags = flags;
 out:
-       spin_unlock(&ubd_lock);
+       mutex_unlock(&ubd_lock);
        return(err);
 }
 
@@ -472,8 +473,9 @@ int thread_fd = -1;
 
 /* Changed by ubd_handler, which is serialized because interrupts only
  * happen on CPU 0.
+ * XXX: currently unused.
  */
-int intr_count = 0;
+static int intr_count = 0;
 
 /* call ubd_finish if you need to serialize */
 static void __ubd_finish(struct request *req, int error)
@@ -493,6 +495,8 @@ static void __ubd_finish(struct request *req, int error)
        end_request(req, 1);
 }
 
+/* Callable only from interrupt context - otherwise you need to do
+ * spin_lock_irq()/spin_lock_irqsave() */
 static inline void ubd_finish(struct request *req, int error)
 {
        spin_lock(&ubd_io_lock);
@@ -500,14 +504,15 @@ static inline void ubd_finish(struct request *req, int error)
        spin_unlock(&ubd_io_lock);
 }
 
-/* Called without ubd_io_lock held */
+/* XXX - move this inside ubd_intr. */
+/* Called without ubd_io_lock held, and only in interrupt context. */
 static void ubd_handler(void)
 {
        struct io_thread_req req;
        struct request *rq = elv_next_request(ubd_queue);
        int n;
 
-       do_ubd = NULL;
+       do_ubd = 0;
        intr_count++;
        n = os_read_file(thread_fd, &req, sizeof(req));
        if(n != sizeof(req)){
@@ -521,7 +526,9 @@ static void ubd_handler(void)
 
        ubd_finish(rq, req.error);
        reactivate_fd(thread_fd, UBD_IRQ);      
+       spin_lock(&ubd_io_lock);
        do_ubd_request(ubd_queue);
+       spin_unlock(&ubd_io_lock);
 }
 
 static irqreturn_t ubd_intr(int irq, void *dev)
@@ -541,87 +548,90 @@ void kill_io_thread(void)
 
 __uml_exitcall(kill_io_thread);
 
-static int ubd_file_size(struct ubd *dev, __u64 *size_out)
+static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
 {
        char *file;
 
-       file = dev->cow.file ? dev->cow.file : dev->file;
+       file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
        return(os_file_size(file, size_out));
 }
 
-static void ubd_close(struct ubd *dev)
+static void ubd_close_dev(struct ubd *ubd_dev)
 {
-       os_close_file(dev->fd);
-       if(dev->cow.file == NULL)
+       os_close_file(ubd_dev->fd);
+       if(ubd_dev->cow.file == NULL)
                return;
 
-       os_close_file(dev->cow.fd);
-       vfree(dev->cow.bitmap);
-       dev->cow.bitmap = NULL;
+       os_close_file(ubd_dev->cow.fd);
+       vfree(ubd_dev->cow.bitmap);
+       ubd_dev->cow.bitmap = NULL;
 }
 
-static int ubd_open_dev(struct ubd *dev)
+static int ubd_open_dev(struct ubd *ubd_dev)
 {
        struct openflags flags;
        char **back_ptr;
        int err, create_cow, *create_ptr;
+       int fd;
 
-       dev->openflags = dev->boot_openflags;
+       ubd_dev->openflags = ubd_dev->boot_openflags;
        create_cow = 0;
-       create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
-       back_ptr = dev->no_cow ? NULL : &dev->cow.file;
-       dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared,
-                               back_ptr, &dev->cow.bitmap_offset,
-                               &dev->cow.bitmap_len, &dev->cow.data_offset,
+       create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
+       back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
+
+       fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
+                               back_ptr, &ubd_dev->cow.bitmap_offset,
+                               &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
                                create_ptr);
 
-       if((dev->fd == -ENOENT) && create_cow){
-               dev->fd = create_cow_file(dev->file, dev->cow.file,
-                                         dev->openflags, 1 << 9, PAGE_SIZE,
-                                         &dev->cow.bitmap_offset,
-                                         &dev->cow.bitmap_len,
-                                         &dev->cow.data_offset);
-               if(dev->fd >= 0){
+       if((fd == -ENOENT) && create_cow){
+               fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
+                                         ubd_dev->openflags, 1 << 9, PAGE_SIZE,
+                                         &ubd_dev->cow.bitmap_offset,
+                                         &ubd_dev->cow.bitmap_len,
+                                         &ubd_dev->cow.data_offset);
+               if(fd >= 0){
                        printk(KERN_INFO "Creating \"%s\" as COW file for "
-                              "\"%s\"\n", dev->file, dev->cow.file);
+                              "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
                }
        }
 
-       if(dev->fd < 0){
-               printk("Failed to open '%s', errno = %d\n", dev->file,
-                      -dev->fd);
-               return(dev->fd);
+       if(fd < 0){
+               printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
+                      -fd);
+               return fd;
        }
+       ubd_dev->fd = fd;
 
-       if(dev->cow.file != NULL){
+       if(ubd_dev->cow.file != NULL){
                err = -ENOMEM;
-               dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
-               if(dev->cow.bitmap == NULL){
+               ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len);
+               if(ubd_dev->cow.bitmap == NULL){
                        printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
                        goto error;
                }
                flush_tlb_kernel_vm();
 
-               err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
-                                     dev->cow.bitmap_offset,
-                                     dev->cow.bitmap_len);
+               err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
+                                     ubd_dev->cow.bitmap_offset,
+                                     ubd_dev->cow.bitmap_len);
                if(err < 0)
                        goto error;
 
-               flags = dev->openflags;
+               flags = ubd_dev->openflags;
                flags.w = 0;
-               err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL,
+               err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
                                    NULL, NULL, NULL, NULL);
                if(err < 0) goto error;
-               dev->cow.fd = err;
+               ubd_dev->cow.fd = err;
        }
        return(0);
  error:
-       os_close_file(dev->fd);
+       os_close_file(ubd_dev->fd);
        return(err);
 }
 
-static int ubd_new_disk(int major, u64 size, int unit,
+static int ubd_disk_register(int major, u64 size, int unit,
                        struct gendisk **disk_out)
                        
 {
@@ -642,13 +652,13 @@ static int ubd_new_disk(int major, u64 size, int unit,
 
        /* sysfs register (not for ide fake devices) */
        if (major == MAJOR_NR) {
-               ubd_dev[unit].pdev.id   = unit;
-               ubd_dev[unit].pdev.name = DRIVER_NAME;
-               platform_device_register(&ubd_dev[unit].pdev);
-               disk->driverfs_dev = &ubd_dev[unit].pdev.dev;
+               ubd_devs[unit].pdev.id   = unit;
+               ubd_devs[unit].pdev.name = DRIVER_NAME;
+               platform_device_register(&ubd_devs[unit].pdev);
+               disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
        }
 
-       disk->private_data = &ubd_dev[unit];
+       disk->private_data = &ubd_devs[unit];
        disk->queue = ubd_queue;
        add_disk(disk);
 
@@ -660,25 +670,25 @@ static int ubd_new_disk(int major, u64 size, int unit,
 
 static int ubd_add(int n)
 {
-       struct ubd *dev = &ubd_dev[n];
+       struct ubd *ubd_dev = &ubd_devs[n];
        int err;
 
        err = -ENODEV;
-       if(dev->file == NULL)
+       if(ubd_dev->file == NULL)
                goto out;
 
-       err = ubd_file_size(dev, &dev->size);
+       err = ubd_file_size(ubd_dev, &ubd_dev->size);
        if(err < 0)
                goto out;
 
-       dev->size = ROUND_BLOCK(dev->size);
+       ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
 
-       err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
+       err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
        if(err)
                goto out;
 
        if(fake_major != MAJOR_NR)
-               ubd_new_disk(fake_major, dev->size, n,
+               ubd_disk_register(fake_major, ubd_dev->size, n,
                             &fake_gendisk[n]);
 
        /* perhaps this should also be under the "if (fake_major)" above */
@@ -693,32 +703,41 @@ out:
 
 static int ubd_config(char *str)
 {
-       int n, err;
+       int n, ret;
 
        str = kstrdup(str, GFP_KERNEL);
-       if(str == NULL){
+       if (str == NULL) {
                printk(KERN_ERR "ubd_config failed to strdup string\n");
-               return(1);
+               ret = 1;
+               goto out;
        }
-       err = ubd_setup_common(str, &n);
-       if(err){
-               kfree(str);
-               return(-1);
+       ret = ubd_setup_common(str, &n);
+       if (ret) {
+               ret = -1;
+               goto err_free;
+       }
+       if (n == -1) {
+               ret = 0;
+               goto err_free;
        }
-       if(n == -1) return(0);
 
-       spin_lock(&ubd_lock);
-       err = ubd_add(n);
-       if(err)
-               ubd_dev[n].file = NULL;
-       spin_unlock(&ubd_lock);
+       mutex_lock(&ubd_lock);
+       ret = ubd_add(n);
+       if (ret)
+               ubd_devs[n].file = NULL;
+       mutex_unlock(&ubd_lock);
 
-       return(err);
+out:
+       return ret;
+
+err_free:
+       kfree(str);
+       goto out;
 }
 
 static int ubd_get_config(char *name, char *str, int size, char **error_out)
 {
-       struct ubd *dev;
+       struct ubd *ubd_dev;
        int n, len = 0;
 
        n = parse_unit(&name);
@@ -727,24 +746,24 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
                return(-1);
        }
 
-       dev = &ubd_dev[n];
-       spin_lock(&ubd_lock);
+       ubd_dev = &ubd_devs[n];
+       mutex_lock(&ubd_lock);
 
-       if(dev->file == NULL){
+       if(ubd_dev->file == NULL){
                CONFIG_CHUNK(str, size, len, "", 1);
                goto out;
        }
 
-       CONFIG_CHUNK(str, size, len, dev->file, 0);
+       CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
 
-       if(dev->cow.file != NULL){
+       if(ubd_dev->cow.file != NULL){
                CONFIG_CHUNK(str, size, len, ",", 0);
-               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
+               CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
        }
        else CONFIG_CHUNK(str, size, len, "", 1);
 
  out:
-       spin_unlock(&ubd_lock);
+       mutex_unlock(&ubd_lock);
        return(len);
 }
 
@@ -760,22 +779,22 @@ static int ubd_id(char **str, int *start_out, int *end_out)
 
 static int ubd_remove(int n)
 {
-       struct ubd *dev;
+       struct ubd *ubd_dev;
        int err = -ENODEV;
 
-       spin_lock(&ubd_lock);
+       mutex_lock(&ubd_lock);
 
        if(ubd_gendisk[n] == NULL)
                goto out;
 
-       dev = &ubd_dev[n];
+       ubd_dev = &ubd_devs[n];
 
-       if(dev->file == NULL)
+       if(ubd_dev->file == NULL)
                goto out;
 
        /* you cannot remove a open disk */
        err = -EBUSY;
-       if(dev->count > 0)
+       if(ubd_dev->count > 0)
                goto out;
 
        del_gendisk(ubd_gendisk[n]);
@@ -788,14 +807,15 @@ static int ubd_remove(int n)
                fake_gendisk[n] = NULL;
        }
 
-       platform_device_unregister(&dev->pdev);
-       *dev = ((struct ubd) DEFAULT_UBD);
+       platform_device_unregister(&ubd_dev->pdev);
+       *ubd_dev = ((struct ubd) DEFAULT_UBD);
        err = 0;
 out:
-       spin_unlock(&ubd_lock);
+       mutex_unlock(&ubd_lock);
        return err;
 }
 
+/* All these are called by mconsole in process context and without ubd-specific locks. */
 static struct mc_device ubd_mc = {
        .name           = "ubd",
        .config         = ubd_config,
@@ -804,7 +824,7 @@ static struct mc_device ubd_mc = {
        .remove         = ubd_remove,
 };
 
-static int ubd_mc_init(void)
+static int __init ubd_mc_init(void)
 {
        mconsole_register_dev(&ubd_mc);
        return 0;
@@ -812,13 +832,24 @@ static int ubd_mc_init(void)
 
 __initcall(ubd_mc_init);
 
+static int __init ubd0_init(void)
+{
+       struct ubd *ubd_dev = &ubd_devs[0];
+
+       if(ubd_dev->file == NULL)
+               ubd_dev->file = "root_fs";
+       return(0);
+}
+
+__initcall(ubd0_init);
+
 static struct platform_driver ubd_driver = {
        .driver = {
                .name  = DRIVER_NAME,
        },
 };
 
-int ubd_init(void)
+static int __init ubd_init(void)
 {
         int i;
 
@@ -846,7 +877,7 @@ int ubd_init(void)
 
 late_initcall(ubd_init);
 
-int ubd_driver_init(void){
+static int __init ubd_driver_init(void){
        unsigned long stack;
        int err;
 
@@ -867,7 +898,7 @@ int ubd_driver_init(void){
                return(0);
        }
        err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
-                            IRQF_DISABLED, "ubd", ubd_dev);
+                            IRQF_DISABLED, "ubd", ubd_devs);
        if(err != 0)
                printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
        return 0;
@@ -878,24 +909,24 @@ device_initcall(ubd_driver_init);
 static int ubd_open(struct inode *inode, struct file *filp)
 {
        struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ubd *dev = disk->private_data;
+       struct ubd *ubd_dev = disk->private_data;
        int err = 0;
 
-       if(dev->count == 0){
-               err = ubd_open_dev(dev);
+       if(ubd_dev->count == 0){
+               err = ubd_open_dev(ubd_dev);
                if(err){
                        printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
-                              disk->disk_name, dev->file, -err);
+                              disk->disk_name, ubd_dev->file, -err);
                        goto out;
                }
        }
-       dev->count++;
-       set_disk_ro(disk, !dev->openflags.w);
+       ubd_dev->count++;
+       set_disk_ro(disk, !ubd_dev->openflags.w);
 
        /* This should no more be needed. And it didn't work anyway to exclude
         * read-write remounting of filesystems.*/
-       /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
-               if(--dev->count == 0) ubd_close(dev);
+       /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){
+               if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
                err = -EROFS;
        }*/
  out:
@@ -905,10 +936,10 @@ static int ubd_open(struct inode *inode, struct file *filp)
 static int ubd_release(struct inode * inode, struct file * file)
 {
        struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct ubd *dev = disk->private_data;
+       struct ubd *ubd_dev = disk->private_data;
 
-       if(--dev->count == 0)
-               ubd_close(dev);
+       if(--ubd_dev->count == 0)
+               ubd_close_dev(ubd_dev);
        return(0);
 }
 
@@ -976,12 +1007,12 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
 static int prepare_request(struct request *req, struct io_thread_req *io_req)
 {
        struct gendisk *disk = req->rq_disk;
-       struct ubd *dev = disk->private_data;
+       struct ubd *ubd_dev = disk->private_data;
        __u64 offset;
        int len;
 
        /* This should be impossible now */
-       if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
+       if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
                printk("Write attempted on readonly ubd device %s\n",
                       disk->disk_name);
                end_request(req, 0);
@@ -991,8 +1022,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
        offset = ((__u64) req->sector) << 9;
        len = req->current_nr_sectors << 9;
 
-       io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
-       io_req->fds[1] = dev->fd;
+       io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd;
+       io_req->fds[1] = ubd_dev->fd;
        io_req->cow_offset = -1;
        io_req->offset = offset;
        io_req->length = len;
@@ -1001,13 +1032,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
 
        io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
        io_req->offsets[0] = 0;
-       io_req->offsets[1] = dev->cow.data_offset;
+       io_req->offsets[1] = ubd_dev->cow.data_offset;
        io_req->buffer = req->buffer;
        io_req->sectorsize = 1 << 9;
 
-       if(dev->cow.file != NULL)
-               cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
-                          dev->cow.bitmap_len);
+       if(ubd_dev->cow.file != NULL)
+               cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset,
+                          ubd_dev->cow.bitmap_len);
 
        return(0);
 }
@@ -1033,7 +1064,7 @@ static void do_ubd_request(request_queue_t *q)
                        return;
                err = prepare_request(req, &io_req);
                if(!err){
-                       do_ubd = ubd_handler;
+                       do_ubd = 1;
                        n = os_write_file(thread_fd, (char *) &io_req,
                                         sizeof(io_req));
                        if(n != sizeof(io_req))
@@ -1045,18 +1076,18 @@ static void do_ubd_request(request_queue_t *q)
 
 static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-       struct ubd *dev = bdev->bd_disk->private_data;
+       struct ubd *ubd_dev = bdev->bd_disk->private_data;
 
        geo->heads = 128;
        geo->sectors = 32;
-       geo->cylinders = dev->size / (128 * 32 * 512);
+       geo->cylinders = ubd_dev->size / (128 * 32 * 512);
        return 0;
 }
 
 static int ubd_ioctl(struct inode * inode, struct file * file,
                     unsigned int cmd, unsigned long arg)
 {
-       struct ubd *dev = inode->i_bdev->bd_disk->private_data;
+       struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data;
        struct hd_driveid ubd_id = {
                .cyls           = 0,
                .heads          = 128,
@@ -1066,7 +1097,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
        switch (cmd) {
                struct cdrom_volctrl volume;
        case HDIO_GET_IDENTITY:
-               ubd_id.cyls = dev->size / (128 * 32 * 512);
+               ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
                if(copy_to_user((char __user *) arg, (char *) &ubd_id,
                                 sizeof(ubd_id)))
                        return(-EFAULT);
@@ -1353,8 +1384,8 @@ void do_io(struct io_thread_req *req)
  */
 int kernel_fd = -1;
 
-/* Only changed by the io thread */
-int io_count = 0;
+/* Only changed by the io thread. XXX: currently unused. */
+static int io_count = 0;
 
 int io_thread(void *arg)
 {
index d0b690197fd78fa5e8dc94e069e96bbe50dca287..1ea6d928e1cd2a5794057cebac2fa6636363048d 100644 (file)
@@ -14,6 +14,7 @@ struct mconsole_entry {
        struct mc_request request;
 };
 
+/* All these methods are called in process context. */
 struct mc_device {
        struct list_head list;
        char *name;
index 68ed24df5c8fa7f24d5089e305fa91e743c37e5a..e36f92b463ce04dc64ec0f076954e48cf0cb276a 100644 (file)
@@ -14,6 +14,7 @@ SECTIONS
    * is remapped.*/
   __binary_start = .;
   . = ALIGN(4096);             /* Init code and data */
+  _text = .;
   _stext = .;
   __init_begin = .;
   .init.text : {
index 9882342206ecf7a1a78a4661e530b3511af39ee2..b9195355075ab3e9540dd0e880be38b1cd08556a 100644 (file)
@@ -176,7 +176,6 @@ struct {
 int signal_index[32];
 int nsignals = 0;
 int debug_trace = 0;
-extern int io_nsignals, io_count, intr_count;
 
 extern void signal_usr1(int sig);
 
index 8eca47a6ff082f171d76777ebb46d2601c282dcf..f6301274cf3cfea9fdb0eb3680cbe349da63fd57 100644 (file)
@@ -25,6 +25,7 @@ SECTIONS
   . = ALIGN(4096);             /* Init code and data */
 #endif
 
+  _text = .;
   _stext = .;
   __init_begin = .;
   .init.text : {
index 6e945ab4584324b6b6df71a7c32688c7cde95538..256532034c62d11b64bc87db21773749a79e3d76 100644 (file)
@@ -1,6 +1,9 @@
 #include <errno.h>
 #include <linux/unistd.h>
+
 #include <sys/syscall.h>
+#include <unistd.h>
+
 #include "sysdep/tls.h"
 #include "user_util.h"
 
index a2de2580b8af4716593832ef880d1c930042c21b..9f7999f27c77f9d618dae55e875b5ccd64aaf8f2 100644 (file)
@@ -1,6 +1,7 @@
 #include <errno.h>
 #include <sys/ptrace.h>
 #include <sys/syscall.h>
+#include <unistd.h>
 #include <asm/ldt.h>
 #include "sysdep/tls.h"
 #include "uml-config.h"
index 8e55cd5d3d07230bb5d98d5a5113fd6b707cec8a..1b0ad0e4adcd26d29f0b605266dfea0cfb1f19d2 100644 (file)
@@ -5,17 +5,20 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
-#include <sys/syscall.h>
 
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-       if (syscall(__NR_munmap, to, size) < 0){
+       if(munmap(to, size) < 0){
                return(-1);
        }
-       if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+       if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
                return(-1);
        }
-       if (syscall(__NR_munmap, from, size) < 0){
+       if(munmap(from, size) < 0){
                return(-1);
        }
        return(0);
index 57c9286a701bcdc71df35740973674b8c603684e..f4a4bffd8a18bc5fb4f6aadce49fb466453d11bd 100644 (file)
@@ -5,17 +5,20 @@
 
 #include <linux/mman.h>
 #include <asm/unistd.h>
-#include <sys/syscall.h>
 
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
 int switcheroo(int fd, int prot, void *from, void *to, int size)
 {
-       if (syscall(__NR_munmap, to, size) < 0){
+       if(munmap(to, size) < 0){
                return(-1);
        }
-       if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+       if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
                return(-1);
        }
-       if (syscall(__NR_munmap, from, size) < 0){
+       if(munmap(from, size) < 0){
                return(-1);
        }
        return(0);
index a6ba9951e86ce3d4f7a40da027b0516ed548486c..0e0a266d976fb1ee5c1b446c119b2fa2c6e34afb 100644 (file)
@@ -579,6 +579,11 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->rsp = (unsigned long) frame;
        regs->rip = (unsigned long) ka->sa.sa_handler;
 
+       /* Make -mregparm=3 work */
+       regs->rax = sig;
+       regs->rdx = (unsigned long) &frame->info;
+       regs->rcx = (unsigned long) &frame->uc;
+
        asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 
        asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 
        
index d3d76136f53adea6293244f7cd9a9aa07f24b4d0..1d9c3c70a9a05b84469a30f55dfbd369ec239e12 100644 (file)
@@ -456,6 +456,9 @@ static void cfq_add_rq_rb(struct request *rq)
         */
        while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != NULL)
                cfq_dispatch_insert(cfqd->queue, __alias);
+
+       if (!cfq_cfqq_on_rr(cfqq))
+               cfq_add_cfqq_rr(cfqd, cfqq);
 }
 
 static inline void
@@ -1215,11 +1218,12 @@ static inline void changed_ioprio(struct cfq_io_context *cic)
 {
        struct cfq_data *cfqd = cic->key;
        struct cfq_queue *cfqq;
+       unsigned long flags;
 
        if (unlikely(!cfqd))
                return;
 
-       spin_lock(cfqd->queue->queue_lock);
+       spin_lock_irqsave(cfqd->queue->queue_lock, flags);
 
        cfqq = cic->cfqq[ASYNC];
        if (cfqq) {
@@ -1236,7 +1240,7 @@ static inline void changed_ioprio(struct cfq_io_context *cic)
        if (cfqq)
                cfq_mark_cfqq_prio_changed(cfqq);
 
-       spin_unlock(cfqd->queue->queue_lock);
+       spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
 
 static void cfq_ioc_set_ioprio(struct io_context *ioc)
@@ -1362,6 +1366,7 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc,
        struct rb_node **p;
        struct rb_node *parent;
        struct cfq_io_context *__cic;
+       unsigned long flags;
        void *k;
 
        cic->ioc = ioc;
@@ -1391,9 +1396,9 @@ restart:
        rb_link_node(&cic->rb_node, parent, p);
        rb_insert_color(&cic->rb_node, &ioc->cic_root);
 
-       spin_lock_irq(cfqd->queue->queue_lock);
+       spin_lock_irqsave(cfqd->queue->queue_lock, flags);
        list_add(&cic->queue_list, &cfqd->cic_list);
-       spin_unlock_irq(cfqd->queue->queue_lock);
+       spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
 
 /*
@@ -1650,9 +1655,6 @@ static void cfq_insert_request(request_queue_t *q, struct request *rq)
 
        cfq_add_rq_rb(rq);
 
-       if (!cfq_cfqq_on_rr(cfqq))
-               cfq_add_cfqq_rr(cfqd, cfqq);
-
        list_add_tail(&rq->queuelist, &cfqq->fifo);
 
        cfq_rq_enqueued(cfqd, cfqq, rq);
index 136066583c6810b6520c9a090f428427819d44c2..c7b1dac8bee91a6bae5a91981af92378d4a280a8 100644 (file)
@@ -2999,6 +2999,7 @@ void generic_make_request(struct bio *bio)
 {
        request_queue_t *q;
        sector_t maxsector;
+       sector_t old_sector;
        int ret, nr_sectors = bio_sectors(bio);
        dev_t old_dev;
 
@@ -3027,7 +3028,7 @@ void generic_make_request(struct bio *bio)
         * NOTE: we don't repeat the blk_size check for each new device.
         * Stacking drivers are expected to know what they are doing.
         */
-       maxsector = -1;
+       old_sector = -1;
        old_dev = 0;
        do {
                char b[BDEVNAME_SIZE];
@@ -3061,15 +3062,30 @@ end_io:
                 */
                blk_partition_remap(bio);
 
-               if (maxsector != -1)
+               if (old_sector != -1)
                        blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, 
-                                           maxsector);
+                                           old_sector);
 
                blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
 
-               maxsector = bio->bi_sector;
+               old_sector = bio->bi_sector;
                old_dev = bio->bi_bdev->bd_dev;
 
+               maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
+               if (maxsector) {
+                       sector_t sector = bio->bi_sector;
+
+                       if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
+                               /*
+                                * This may well happen - partitions are not checked
+                                * to make sure they are within the size of the
+                                * whole device.
+                                */
+                               handle_bad_sector(bio);
+                               goto end_io;
+                       }
+               }
+
                ret = q->make_request_fn(q, bio);
        } while (ret);
 }
index cef2e70d64f8d57d2e62bbec19a5fda752e05d40..988f8bbd14ffa39cc26976f54ab95818496e2785 100644 (file)
@@ -736,8 +736,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
        }
 
        /* check BUSY/DRQ, perform Command List Override if necessary */
-       ahci_tf_read(ap, &tf);
-       if (tf.command & (ATA_BUSY | ATA_DRQ)) {
+       if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) {
                rc = ahci_clo(ap);
 
                if (rc == -EOPNOTSUPP) {
index 5250187ffce2a610f456e3814d019bc3a4b656b6..720174d628fa762d4ee3e2367645229d14771b06 100644 (file)
@@ -126,8 +126,7 @@ enum {
        ich6_sata               = 7,
        ich6_sata_ahci          = 8,
        ich6m_sata_ahci         = 9,
-       ich7m_sata_ahci         = 10,
-       ich8_sata_ahci          = 11,
+       ich8_sata_ahci          = 10,
 
        /* constants for mapping table */
        P0                      = 0,  /* port 0 */
@@ -227,7 +226,7 @@ static const struct pci_device_id piix_pci_tbl[] = {
        /* 82801GB/GR/GH (ICH7, identical to ICH6) */
        { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
        /* 2801GBM/GHM (ICH7M, identical to ICH6M) */
-       { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7m_sata_ahci },
+       { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
        /* Enterprise Southbridge 2 (where's the datasheet?) */
        { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
        /* SATA Controller 1 IDE (ICH8, no datasheet yet) */
@@ -399,23 +398,10 @@ static const struct piix_map_db ich6m_map_db = {
        .mask = 0x3,
        .port_enable = 0x5,
        .present_shift = 4,
-       .map = {
-               /* PM   PS   SM   SS       MAP */
-               {  P0,  P2,  RV,  RV }, /* 00b */
-               {  RV,  RV,  RV,  RV },
-               {  P0,  P2, IDE, IDE }, /* 10b */
-               {  RV,  RV,  RV,  RV },
-       },
-};
-
-static const struct piix_map_db ich7m_map_db = {
-       .mask = 0x3,
-       .port_enable = 0x5,
-       .present_shift = 4,
 
        /* Map 01b isn't specified in the doc but some notebooks use
-        * it anyway.  ATM, the only case spotted carries subsystem ID
-        * 1025:0107.  This is the only difference from ich6m.
+        * it anyway.  MAP 01b have been spotted on both ICH6M and
+        * ICH7M.
         */
        .map = {
                /* PM   PS   SM   SS       MAP */
@@ -445,7 +431,6 @@ static const struct piix_map_db *piix_map_db_table[] = {
        [ich6_sata]             = &ich6_map_db,
        [ich6_sata_ahci]        = &ich6_map_db,
        [ich6m_sata_ahci]       = &ich6m_map_db,
-       [ich7m_sata_ahci]       = &ich7m_map_db,
        [ich8_sata_ahci]        = &ich8_map_db,
 };
 
@@ -556,19 +541,7 @@ static struct ata_port_info piix_port_info[] = {
                .port_ops       = &piix_sata_ops,
        },
 
-       /* ich7m_sata_ahci: 10 */
-       {
-               .sht            = &piix_sht,
-               .flags          = ATA_FLAG_SATA |
-                                 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
-                                 PIIX_FLAG_AHCI,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x07, /* mwdma0-2 */
-               .udma_mask      = 0x7f, /* udma0-6 */
-               .port_ops       = &piix_sata_ops,
-       },
-
-       /* ich8_sata_ahci: 11 */
+       /* ich8_sata_ahci: 10 */
        {
                .sht            = &piix_sht,
                .flags          = ATA_FLAG_SATA |
index 83728a9457ad896590e79fa44d55d9e6efedaf8f..a8fd0c3e59b30a5a816d5cbb32a354b055b98920 100644 (file)
@@ -6122,7 +6122,6 @@ EXPORT_SYMBOL_GPL(ata_std_prereset);
 EXPORT_SYMBOL_GPL(ata_std_softreset);
 EXPORT_SYMBOL_GPL(sata_std_hardreset);
 EXPORT_SYMBOL_GPL(ata_std_postreset);
-EXPORT_SYMBOL_GPL(ata_dev_revalidate);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_pair);
 EXPORT_SYMBOL_GPL(ata_port_disable);
index a5ecb71390a919863029896fe68df162416c63b3..0ed263be652a9bd47aada22078a05a3a11baea5b 100644 (file)
@@ -53,6 +53,7 @@ extern unsigned ata_exec_internal(struct ata_device *dev,
 extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
 extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                           int post_reset, u16 *id);
+extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
 extern int ata_dev_configure(struct ata_device *dev, int print_info);
 extern int sata_down_spd_limit(struct ata_port *ap);
 extern int sata_set_spd_needed(struct ata_port *ap);
index 323b607108063b41d84913c7b14ac3ae2b26ec90..d65ebfd7c7b220537d961a06725fecb6490cb7be 100644 (file)
@@ -117,10 +117,14 @@ static const struct pci_device_id nv_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
-       { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC },
-       { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC },
-       { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC },
-       { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC },
+       { PCI_VDEVICE(NVIDIA, 0x045c), GENERIC }, /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x045d), GENERIC }, /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x045e), GENERIC }, /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x045f), GENERIC }, /* MCP65 */
+       { PCI_VDEVICE(NVIDIA, 0x0550), GENERIC }, /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x0551), GENERIC }, /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x0552), GENERIC }, /* MCP67 */
+       { PCI_VDEVICE(NVIDIA, 0x0553), GENERIC }, /* MCP67 */
        { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
                PCI_ANY_ID, PCI_ANY_ID,
                PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
index 0738f52463a953ccd5f630f3709bdc9e649aaa7b..9d1235ba06b1fc8a3a9e3bc3bca3f92533ef2f55 100644 (file)
@@ -240,7 +240,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        struct ata_probe_ent *probe_ent = NULL;
        int rc;
        u32 genctl;
-       struct ata_port_info *ppi[2];
+       struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
        int pci_dev_busy = 0;
        u8 pmr;
        u8 port2_start;
@@ -265,27 +265,20 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                goto err_out_regions;
 
-       ppi[0] = ppi[1] = &sis_port_info;
-       probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-       if (!probe_ent) {
-               rc = -ENOMEM;
-               goto err_out_regions;
-       }
-
        /* check and see if the SCRs are in IO space or PCI cfg space */
        pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
        if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
-               probe_ent->port_flags |= SIS_FLAG_CFGSCR;
+               pi.flags |= SIS_FLAG_CFGSCR;
 
        /* if hardware thinks SCRs are in IO space, but there are
         * no IO resources assigned, change to PCI cfg space.
         */
-       if ((!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) &&
+       if ((!(pi.flags & SIS_FLAG_CFGSCR)) &&
            ((pci_resource_start(pdev, SIS_SCR_PCI_BAR) == 0) ||
             (pci_resource_len(pdev, SIS_SCR_PCI_BAR) < 128))) {
                genctl &= ~GENCTL_IOMAPPED_SCR;
                pci_write_config_dword(pdev, SIS_GENCTL, genctl);
-               probe_ent->port_flags |= SIS_FLAG_CFGSCR;
+               pi.flags |= SIS_FLAG_CFGSCR;
        }
 
        pci_read_config_byte(pdev, SIS_PMR, &pmr);
@@ -306,6 +299,12 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                port2_start = 0x20;
        }
 
+       probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
+       if (!probe_ent) {
+               rc = -ENOMEM;
+               goto err_out_regions;
+       }
+
        if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
                probe_ent->port[0].scr_addr =
                        pci_resource_start(pdev, SIS_SCR_PCI_BAR);
index 845b8680032a0a904de4460f25873b2a1ccd857d..cbc07250b8984f1c95f07539da45f89d6a914a57 100644 (file)
@@ -282,7 +282,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
                clear_bit(ready_bit, &(info->tx_state));
 
                if (bt_cb(skb)->pkt_type & 0x80) {
-                       DECLARE_WAIT_QUEUE_HEAD(wq);
+                       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
                        DEFINE_WAIT(wait);
 
                        unsigned char baud_reg;
index e72ab36a5494e3a695e17c8fb5bc238db5d562d1..9f306880491abea6b809e568ebeff51945bb49d6 100644 (file)
@@ -48,7 +48,7 @@ static int ide_generic_all;           /* Set to claim all devices */
 static int __init ide_generic_all_on(char *unused)
 {
        ide_generic_all = 1;
-       printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.");
+       printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
        return 1;
 }
 __setup("all-generic-ide", ide_generic_all_on);
index 8a7b8fab62383670a600abfda49f6d718b971a5c..31e5cc49d61a01899cea3e6d5220809f2b889be7 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/ethtool.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
+#include <asm/unaligned.h>
 #include <net/arp.h>
 
 #include "config_roms.h"
@@ -491,7 +492,7 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
        int i;
        struct eth1394_priv *priv = netdev_priv(dev);
        struct hpsb_host *host = priv->host;
-       u64 guid = *((u64*)&(host->csr.rom->bus_info_data[3]));
+       u64 guid = get_unaligned((u64*)&(host->csr.rom->bus_info_data[3]));
        u16 maxpayload = 1 << (host->csr.max_rec + 1);
        int max_speed = IEEE1394_SPEED_MAX;
 
@@ -514,8 +515,8 @@ static void ether1394_reset_priv (struct net_device *dev, int set_mtu)
                                      ETHER1394_GASP_OVERHEAD)));
 
                /* Set our hardware address while we're at it */
-               *(u64*)dev->dev_addr = guid;
-               *(u64*)dev->broadcast = ~0x0ULL;
+               memcpy(dev->dev_addr, &guid, sizeof(u64));
+               memset(dev->broadcast, 0xff, sizeof(u64));
        }
 
        spin_unlock_irqrestore (&priv->lock, flags);
@@ -894,6 +895,7 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb,
                u16 maxpayload;
                struct eth1394_node_ref *node;
                struct eth1394_node_info *node_info;
+               __be64 guid;
 
                /* Sanity check. MacOSX seems to be sending us 131 in this
                 * field (atleast on my Panther G5). Not sure why. */
@@ -902,8 +904,9 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb,
 
                maxpayload = min(eth1394_speedto_maxpayload[sspd], (u16)(1 << (max_rec + 1)));
 
+               guid = get_unaligned(&arp1394->s_uniq_id);
                node = eth1394_find_node_guid(&priv->ip_node_list,
-                                             be64_to_cpu(arp1394->s_uniq_id));
+                                             be64_to_cpu(guid));
                if (!node) {
                        return 0;
                }
@@ -931,10 +934,9 @@ static inline u16 ether1394_parse_encap(struct sk_buff *skb,
                arp_ptr += arp->ar_pln;         /* skip over sender IP addr */
 
                if (arp->ar_op == htons(ARPOP_REQUEST))
-                       /* just set ARP req target unique ID to 0 */
-                       *((u64*)arp_ptr) = 0;
+                       memset(arp_ptr, 0, sizeof(u64));
                else
-                       *((u64*)arp_ptr) = *((u64*)dev->dev_addr);
+                       memcpy(arp_ptr, dev->dev_addr, sizeof(u64));
        }
 
        /* Now add the ethernet header. */
@@ -1675,8 +1677,10 @@ static int ether1394_tx (struct sk_buff *skb, struct net_device *dev)
                if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF])
                        priv->bc_dgl++;
        } else {
+               __be64 guid = get_unaligned((u64 *)eth->h_dest);
+
                node = eth1394_find_node_guid(&priv->ip_node_list,
-                                             be64_to_cpu(*(u64*)eth->h_dest));
+                                             be64_to_cpu(guid));
                if (!node) {
                        ret = -EAGAIN;
                        goto fail;
index aca165d43aa050952dbaaac63e34241cbfd10dd7..d8d256dadddf85cc37d51ab0508bc5dd4e5006e5 100644 (file)
@@ -616,7 +616,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
        } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
                skb_reserve(bcs->skb, HW_HDR_LEN);
        else {
-               dev_warn(cs->dev, "could not allocate skb\n");
+               gig_dbg(DEBUG_INIT, "could not allocate skb\n");
                bcs->inputstate |= INS_skip_frame;
        }
 
index a625576fdeeb3eb5c5ac1c7ebc15f3aea841df39..08a40f4e4f60332f370f180a89124fe26ee3e85b 100644 (file)
@@ -915,8 +915,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
                        char *result, unsigned int maxlen)
 {
        struct crypt_config *cc = (struct crypt_config *) ti->private;
-       const char *cipher;
-       const char *chainmode = NULL;
        unsigned int sz = 0;
 
        switch (type) {
@@ -925,14 +923,11 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
                break;
 
        case STATUSTYPE_TABLE:
-               cipher = crypto_blkcipher_name(cc->tfm);
-
-               chainmode = cc->chainmode;
-
                if (cc->iv_mode)
-                       DMEMIT("%s-%s-%s ", cipher, chainmode, cc->iv_mode);
+                       DMEMIT("%s-%s-%s ", cc->cipher, cc->chainmode,
+                              cc->iv_mode);
                else
-                       DMEMIT("%s-%s ", cipher, chainmode);
+                       DMEMIT("%s-%s ", cc->cipher, cc->chainmode);
 
                if (cc->key_size > 0) {
                        if ((maxlen - sz) < ((cc->key_size << 1) + 1))
index 01a5a702b037e9c12e22fd1ef43ebd211b8f4204..a2350640384b5a75c09fc17a5f744c9a7fac9462 100644 (file)
@@ -124,7 +124,7 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
 int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
                          unsigned long timeout, struct i2o_dma *dma)
 {
-       DECLARE_WAIT_QUEUE_HEAD(wq);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
        struct i2o_exec_wait *wait;
        static u32 tcntxt = 0x80000000;
        unsigned long flags;
index e38846eb51faa95e606b3f5e555e0a54137fb63d..28c17d1ca5cb8c1e4b19c2467c3b1c6b304cc3d2 100644 (file)
@@ -2112,7 +2112,7 @@ config SKGE
 
 config SKY2
        tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
-       depends on PCI && EXPERIMENTAL
+       depends on PCI
        select CRC32
        ---help---
          This driver supports Gigabit Ethernet adapters based on the
@@ -2120,8 +2120,8 @@ config SKY2
          Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
          88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
 
-         This driver does not support the original Yukon chipset: a seperate
-         driver, skge, is provided for Yukon-based adapters.
+         There is companion driver for the older Marvell Yukon and
+         Genesis based adapters: skge.
 
          To compile this driver as a module, choose M here: the module
          will be called sky2.  This is recommended.
index 127561c782fd501d4cb1830489d3ebe61645113a..8ebd68e2af98229374e43dc2b45285e8fd2fd6a1 100644 (file)
@@ -193,12 +193,9 @@ static struct net_device_stats *ep93xx_get_stats(struct net_device *dev)
 static int ep93xx_rx(struct net_device *dev, int *budget)
 {
        struct ep93xx_priv *ep = netdev_priv(dev);
-       int tail_offset;
        int rx_done;
        int processed;
 
-       tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr;
-
        rx_done = 0;
        processed = 0;
        while (*budget > 0) {
@@ -211,36 +208,28 @@ static int ep93xx_rx(struct net_device *dev, int *budget)
 
                entry = ep->rx_pointer;
                rstat = ep->descs->rstat + entry;
-               if ((void *)rstat - (void *)ep->descs == tail_offset) {
+
+               rstat0 = rstat->rstat0;
+               rstat1 = rstat->rstat1;
+               if (!(rstat0 & RSTAT0_RFP) || !(rstat1 & RSTAT1_RFP)) {
                        rx_done = 1;
                        break;
                }
 
-               rstat0 = rstat->rstat0;
-               rstat1 = rstat->rstat1;
                rstat->rstat0 = 0;
                rstat->rstat1 = 0;
 
-               if (!(rstat0 & RSTAT0_RFP))
-                       printk(KERN_CRIT "ep93xx_rx: buffer not done "
-                                        " %.8x %.8x\n", rstat0, rstat1);
                if (!(rstat0 & RSTAT0_EOF))
                        printk(KERN_CRIT "ep93xx_rx: not end-of-frame "
                                         " %.8x %.8x\n", rstat0, rstat1);
                if (!(rstat0 & RSTAT0_EOB))
                        printk(KERN_CRIT "ep93xx_rx: not end-of-buffer "
                                         " %.8x %.8x\n", rstat0, rstat1);
-               if (!(rstat1 & RSTAT1_RFP))
-                       printk(KERN_CRIT "ep93xx_rx: buffer1 not done "
-                                        " %.8x %.8x\n", rstat0, rstat1);
                if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry)
                        printk(KERN_CRIT "ep93xx_rx: entry mismatch "
                                         " %.8x %.8x\n", rstat0, rstat1);
 
                if (!(rstat0 & RSTAT0_RWE)) {
-                       printk(KERN_NOTICE "ep93xx_rx: receive error "
-                                        " %.8x %.8x\n", rstat0, rstat1);
-
                        ep->stats.rx_errors++;
                        if (rstat0 & RSTAT0_OE)
                                ep->stats.rx_fifo_errors++;
@@ -301,13 +290,8 @@ err:
 
 static int ep93xx_have_more_rx(struct ep93xx_priv *ep)
 {
-       struct ep93xx_rstat *rstat;
-       int tail_offset;
-
-       rstat = ep->descs->rstat + ep->rx_pointer;
-       tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr;
-
-       return !((void *)rstat - (void *)ep->descs == tail_offset);
+       struct ep93xx_rstat *rstat = ep->descs->rstat + ep->rx_pointer;
+       return !!((rstat->rstat0 & RSTAT0_RFP) && (rstat->rstat1 & RSTAT1_RFP));
 }
 
 static int ep93xx_poll(struct net_device *dev, int *budget)
@@ -347,7 +331,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
        struct ep93xx_priv *ep = netdev_priv(dev);
        int entry;
 
-       if (unlikely(skb->len) > MAX_PKT_SIZE) {
+       if (unlikely(skb->len > MAX_PKT_SIZE)) {
                ep->stats.tx_dropped++;
                dev_kfree_skb(skb);
                return NETDEV_TX_OK;
@@ -379,10 +363,8 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
 static void ep93xx_tx_complete(struct net_device *dev)
 {
        struct ep93xx_priv *ep = netdev_priv(dev);
-       int tail_offset;
        int wake;
 
-       tail_offset = rdl(ep, REG_TXSTSQCURADD) - ep->descs_dma_addr;
        wake = 0;
 
        spin_lock(&ep->tx_pending_lock);
@@ -393,15 +375,13 @@ static void ep93xx_tx_complete(struct net_device *dev)
 
                entry = ep->tx_clean_pointer;
                tstat = ep->descs->tstat + entry;
-               if ((void *)tstat - (void *)ep->descs == tail_offset)
-                       break;
 
                tstat0 = tstat->tstat0;
+               if (!(tstat0 & TSTAT0_TXFP))
+                       break;
+
                tstat->tstat0 = 0;
 
-               if (!(tstat0 & TSTAT0_TXFP))
-                       printk(KERN_CRIT "ep93xx_tx_complete: buffer not done "
-                                        " %.8x\n", tstat0);
                if (tstat0 & TSTAT0_FA)
                        printk(KERN_CRIT "ep93xx_tx_complete: frame aborted "
                                         " %.8x\n", tstat0);
index 4873dc610d22e9f772d6a0242b3c66dc200eeed4..7db3c8af08942a76aa4244f430ec5b66691dd8b7 100644 (file)
@@ -102,7 +102,7 @@ static void enable_mac(struct net_device *, int);
 // externs
 extern int get_ethernet_addr(char *ethernet_addr);
 extern void str2eaddr(unsigned char *ea, unsigned char *str);
-extern char * __init prom_getcmdline(void);
+extern char * prom_getcmdline(void);
 
 /*
  * Theory of operation
index eb7d44de59ff1aa91e9a833c3bab423430a7359d..4538c99733fdb6611be1448c45e1a6941d17b6c5 100644 (file)
@@ -586,8 +586,8 @@ int ehea_sense_port_attr(struct ehea_port *port)
        u64 hret;
        struct hcp_ehea_port_cb0 *cb0;
 
-       cb0 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
-       if (!cb0) {
+       cb0 = kzalloc(H_CB_ALIGNMENT, GFP_ATOMIC);   /* May be called via */
+       if (!cb0) {                                  /* ehea_neq_tasklet() */
                ehea_error("no mem for cb0");
                ret = -ENOMEM;
                goto out;
@@ -765,8 +765,7 @@ static void ehea_parse_eqe(struct ehea_adapter *adapter, u64 eqe)
 
                if (EHEA_BMASK_GET(NEQE_PORT_UP, eqe)) {
                        if (!netif_carrier_ok(port->netdev)) {
-                               ret = ehea_sense_port_attr(
-                                       port);
+                               ret = ehea_sense_port_attr(port);
                                if (ret) {
                                        ehea_error("failed resensing port "
                                                   "attributes");
@@ -1502,7 +1501,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable)
        if ((enable && port->promisc) || (!enable && !port->promisc))
                return;
 
-       cb7 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
+       cb7 = kzalloc(H_CB_ALIGNMENT, GFP_ATOMIC);
        if (!cb7) {
                ehea_error("no mem for cb7");
                goto out;
@@ -1606,7 +1605,7 @@ static void ehea_add_multicast_entry(struct ehea_port* port, u8* mc_mac_addr)
        struct ehea_mc_list *ehea_mcl_entry;
        u64 hret;
 
-       ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_KERNEL);
+       ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC);
        if (!ehea_mcl_entry) {
                ehea_error("no mem for mcl_entry");
                return;
index be8a66e702b010cb10f3b995302954e077d59698..3b4c478759356fa9f7b8af473385520fa1c023c2 100644 (file)
@@ -15,8 +15,7 @@
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
-*      the Free Software Foundation; either version 2 of the License, or
-*      (at your option) any later version.
+*      the Free Software Foundation; either version 2 of the License.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
index fdbb0d7213b036ee6fa7ef895a307c9894d0b29e..806081b5973392cad24f7ac15a007e2f317f1438 100644 (file)
@@ -2416,7 +2416,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
  * firmware image, and set tx.boundary to 4KB.
  */
 
-#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE  0x0132
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
 #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
 
index a231ab7d28ddccc288dbd4619df552d3a5020d09..33569ec9dbfcbc891acc7bf2b0921039abac845a 100644 (file)
@@ -5985,6 +5985,11 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba,
                        ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1;
                } else {
                        *skb = dev_alloc_skb(size);
+                       if (!(*skb)) {
+                               DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n",
+                                         dev->name);
+                               return -ENOMEM;
+                       }
                        ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 =
                                pci_map_single(sp->pdev, (*skb)->data,
                                               dev->mtu + 4,
@@ -6007,7 +6012,11 @@ static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba,
                        ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2;
                } else {
                        *skb = dev_alloc_skb(size);
-
+                       if (!(*skb)) {
+                               DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n",
+                                         dev->name);
+                               return -ENOMEM;
+                       }
                        ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 =
                                pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
                                               PCI_DMA_FROMDEVICE);
index e7e414928f89459dab22c753be80eb7a477590b4..b2949035f66a93a8554735168f140bc36797bbaf 100644 (file)
@@ -11,8 +11,7 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2 of the License.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
index 95efdb5bbbe10da3a1932c3614d09ce85cadda09..16616f5440d037a279392c4b9d6be5e3e1232248 100644 (file)
@@ -10,8 +10,7 @@
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation; either version 2 of the License.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -3239,7 +3238,11 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
                dev->poll = sky2_poll;
        dev->weight = NAPI_WEIGHT;
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = sky2_netpoll;
+       /* Network console (only works on port 0)
+        * because netpoll makes assumptions about NAPI
+        */
+       if (port == 0)
+               dev->poll_controller = sky2_netpoll;
 #endif
 
        sky2 = netdev_priv(dev);
index 4f756960db2ae94281b4eedd9c1b2eec1c4ec4cc..cb7dbb63c9d9da6b6794dc30045943f4cac4eced 100644 (file)
@@ -370,6 +370,10 @@ static int __init proteon_init(void)
                dev->dma = dma[i];
                pdev = platform_device_register_simple("proteon",
                        i, NULL, 0);
+               if (IS_ERR(pdev)) {
+                       free_netdev(dev);
+                       continue;
+               }
                err = setup_card(dev, &pdev->dev);
                if (!err) {
                        proteon_dev[i] = pdev;
@@ -385,9 +389,10 @@ static int __init proteon_init(void)
        /* Probe for cards. */
        if (num == 0) {
                printk(KERN_NOTICE "proteon.c: No cards found.\n");
-               return (-ENODEV);
+               platform_driver_unregister(&proteon_driver);
+               return -ENODEV;
        }
-       return (0);
+       return 0;
 }
 
 static void __exit proteon_cleanup(void)
index d6ba41cf3110665ceb3b4a8332921a6baaf28efd..33afea31d87b93b591a640cc3a4771923f7184d2 100644 (file)
@@ -380,6 +380,10 @@ static int __init sk_isa_init(void)
                dev->dma = dma[i];
                pdev = platform_device_register_simple("skisa",
                        i, NULL, 0);
+               if (IS_ERR(pdev)) {
+                       free_netdev(dev);
+                       continue;
+               }
                err = setup_card(dev, &pdev->dev);
                if (!err) {
                        sk_isa_dev[i] = pdev;
@@ -395,9 +399,10 @@ static int __init sk_isa_init(void)
        /* Probe for cards. */
        if (num == 0) {
                printk(KERN_NOTICE "skisa.c: No cards found.\n");
-               return (-ENODEV);
+               platform_driver_unregister(&sk_isa_driver);
+               return -ENODEV;
        }
-       return (0);
+       return 0;
 }
 
 static void __exit sk_isa_cleanup(void)
index 58b7efbb075015462469454e0a174805038edeb7..b5d0d7fb647a3455fd4d0e91bf03aa2c5dc75b1e 100644 (file)
@@ -127,7 +127,7 @@ config LANMEDIA
 # There is no way to detect a Sealevel board. Force it modular
 config SEALEVEL_4021
        tristate "Sealevel Systems 4021 support"
-       depends on WAN && ISA && m && ISA_DMA_API
+       depends on WAN && ISA && m && ISA_DMA_API && INET
        help
          This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
 
index dcf46add3adfece0ce13b4d57173dddcabca9316..5c322dfb79f6e2a7ebc325b04228750999d8738b 100644 (file)
@@ -500,7 +500,7 @@ static int __init n2_init(void)
 #ifdef MODULE
                printk(KERN_INFO "n2: no card initialized\n");
 #endif
-               return -ENOSYS; /* no parameters specified, abort */
+               return -EINVAL; /* no parameters specified, abort */
        }
 
        printk(KERN_INFO "%s\n", version);
@@ -538,11 +538,11 @@ static int __init n2_init(void)
                        n2_run(io, irq, ram, valid[0], valid[1]);
 
                if (*hw == '\x0')
-                       return first_card ? 0 : -ENOSYS;
+                       return first_card ? 0 : -EINVAL;
        }while(*hw++ == ':');
 
        printk(KERN_ERR "n2: invalid hardware parameters\n");
-       return first_card ? 0 : -ENOSYS;
+       return first_card ? 0 : -EINVAL;
 }
 
 
index b3fa7ed71faf2ffdebef04f0bc3ff46a33340651..5a49216fe4cfb5e81b2064ad51fe88075e8d0972 100644 (file)
@@ -49,7 +49,7 @@
 
 #include <linux/wait.h>
 typedef wait_queue_head_t adpt_wait_queue_head_t;
-#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait)
 typedef wait_queue_t adpt_wait_queue_t;
 
 /*
index 2d95ac9c32c1576e1a6ea01c562fac839330dac6..e31f6122106f1ed830c6972be2c10e471df4e773 100644 (file)
@@ -1153,7 +1153,7 @@ static int __imm_attach(struct parport *pb)
 {
        struct Scsi_Host *host;
        imm_struct *dev;
-       DECLARE_WAIT_QUEUE_HEAD(waiting);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
        DEFINE_WAIT(wait);
        int ports;
        int modes, ppb;
index d586c3d3b0d0dac1381ae240547fab3ea675713b..19c79a0549a7718cbf4560d3818c23e81c059579 100644 (file)
@@ -305,7 +305,7 @@ lpfc_do_work(void *p)
 {
        struct lpfc_hba *phba = p;
        int rc;
-       DECLARE_WAIT_QUEUE_HEAD(work_waitq);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(work_waitq);
 
        set_user_nice(current, -20);
        phba->work_wait = &work_waitq;
index 24a1779b9af4366a761c19955a22b68fb6b4d368..582f5ea4e84e3c7b9f00c59ae58f5fab2af41925 100644 (file)
@@ -2983,7 +2983,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
                         struct lpfc_iocbq * prspiocbq,
                         uint32_t timeout)
 {
-       DECLARE_WAIT_QUEUE_HEAD(done_q);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
        long timeleft, timeout_req = 0;
        int retval = IOCB_SUCCESS;
        uint32_t creg_val;
@@ -3061,7 +3061,7 @@ int
 lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
                         uint32_t timeout)
 {
-       DECLARE_WAIT_QUEUE_HEAD(done_q);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q);
        DECLARE_WAITQUEUE(wq_entry, current);
        uint32_t timeleft = 0;
        int retval;
index b0eba39f208af27612ed5c86cd45c5cffe5e6205..89a2a9f11e41f6352f287ed976a0fc58e9abbbb5 100644 (file)
@@ -1012,7 +1012,7 @@ static LIST_HEAD(ppa_hosts);
 static int __ppa_attach(struct parport *pb)
 {
        struct Scsi_Host *host;
-       DECLARE_WAIT_QUEUE_HEAD(waiting);
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
        DEFINE_WAIT(wait);
        ppa_struct *dev;
        int ports;
index 08a07f0b8d94e2945584fe085254b75a52eb11af..69cbff3f57cf3abb49a4a289b662348ff9409c6d 100644 (file)
@@ -1,6 +1,6 @@
 config SCSI_QLA_ISCSI
        tristate "QLogic ISP4XXX host adapter family support"
-       depends on PCI && SCSI
+       depends on PCI && SCSI && NET
        select SCSI_ISCSI_ATTRS
        ---help---
        This driver supports the QLogic 40xx (ISP4XXX) iSCSI host
index ff4fa25f9fd12cdac405130e096c2200d9eb40fc..711bd151143913c0f48a836701f196dbc96eeb79 100644 (file)
@@ -921,7 +921,7 @@ static void handle_dma_error_intr(void *arg, uint32_t other_ir)
 {
        struct ioc4_port *port = (struct ioc4_port *)arg;
        struct hooks *hooks = port->ip_hooks;
-       unsigned int flags;
+       unsigned long flags;
 
        spin_lock_irqsave(&port->ip_lock, flags);
 
@@ -1834,7 +1834,7 @@ static void handle_intr(void *arg, uint32_t sio_ir)
        struct ioc4_port *port = (struct ioc4_port *)arg;
        struct hooks *hooks = port->ip_hooks;
        unsigned int rx_high_rd_aborted = 0;
-       unsigned int flags;
+       unsigned long flags;
        struct uart_port *the_port;
        int loop_counter;
 
index cf3d20eb781cde127e53f1af4c553bea198fa13a..40873635d80e70d24b4dd57be0ba83488e950766 100644 (file)
@@ -554,7 +554,7 @@ static int usbnet_stop (struct net_device *net)
 {
        struct usbnet           *dev = netdev_priv(net);
        int                     temp;
-       DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); 
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
        DECLARE_WAITQUEUE (wait, current);
 
        netif_stop_queue (net);
index fe1488374f620cad6fa5fce1e8eef17b3ff79132..e3993213d10e39cb2e98629dc114775dcc23aa37 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/backlight.h>
 
 #include <asm/cpu/dac.h>
-#include <asm/hp6xx/hp6xx.h>
+#include <asm/hp6xx.h>
 #include <asm/hd64461.h>
 
 #define HP680_MAX_INTENSITY 255
index bad0e98fb3b6fa64165b77c21707f6306dd152b3..9a40bbecf76b1293fe15df72c37bd9df9303a169 100644 (file)
@@ -157,7 +157,7 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
                out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
                break;
        case cmap_gxt2000:
-               out_le32((unsigned __iomem *) par->cmap_adr + regno,
+               out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
                         (red << 16 | green << 8 | blue));
                break;
        }
@@ -213,7 +213,7 @@ static int offb_blank(int blank, struct fb_info *info)
                                out_le32(par->cmap_adr + 0xb4, 0);
                                break;
                        case cmap_gxt2000:
-                               out_le32((unsigned __iomem *) par->cmap_adr + i,
+                               out_le32(((unsigned __iomem *) par->cmap_adr) + i,
                                         0);
                                break;
                        }
@@ -226,13 +226,23 @@ static int offb_blank(int blank, struct fb_info *info)
 static void __iomem *offb_map_reg(struct device_node *np, int index,
                                  unsigned long offset, unsigned long size)
 {
-       struct resource r;
-
-       if (of_address_to_resource(np, index, &r))
-               return 0;
-       if ((r.start + offset + size) > r.end)
-               return 0;
-       return ioremap(r.start + offset, size);
+       const u32 *addrp;
+       u64 asize, taddr;
+       unsigned int flags;
+
+       addrp = of_get_pci_address(np, index, &asize, &flags);
+       if (addrp == NULL)
+               addrp = of_get_address(np, index, &asize, &flags);
+       if (addrp == NULL)
+               return NULL;
+       if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+               return NULL;
+       if ((offset + size) > asize)
+               return NULL;
+       taddr = of_translate_address(np, addrp);
+       if (taddr == OF_BAD_ADDR)
+               return NULL;
+       return ioremap(taddr + offset, size);
 }
 
 static void __init offb_init_fb(const char *name, const char *full_name,
@@ -289,7 +299,6 @@ static void __init offb_init_fb(const char *name, const char *full_name,
 
        par->cmap_type = cmap_unknown;
        if (depth == 8) {
-               /* Palette hacks disabled for now */
                if (dp && !strncmp(name, "ATY,Rage128", 11)) {
                        par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
                        if (par->cmap_adr)
@@ -313,7 +322,8 @@ static void __init offb_init_fb(const char *name, const char *full_name,
                            ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
                        par->cmap_data = par->cmap_adr + 1;
                        par->cmap_type = cmap_m64;
-               } else if (dp && device_is_compatible(dp, "pci1014,b7")) {
+               } else if (dp && (device_is_compatible(dp, "pci1014,b7") ||
+                                 device_is_compatible(dp, "pci1014,21c"))) {
                        par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
                        if (par->cmap_adr)
                                par->cmap_type = cmap_gxt2000;
@@ -433,7 +443,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
        pp = get_property(dp, "linux,bootx-linebytes", &len);
        if (pp == NULL)
                pp = get_property(dp, "linebytes", &len);
-       if (pp && len == sizeof(u32))
+       if (pp && len == sizeof(u32) && (*pp != 0xffffffffu))
                pitch = *pp;
        else
                pitch = width * ((depth + 7) / 8);
@@ -496,7 +506,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)
                offb_init_fb(no_real_node ? "bootx" : dp->name,
                             no_real_node ? "display" : dp->full_name,
                             width, height, depth, pitch, address,
-                            no_real_node ? dp : NULL);
+                            no_real_node ? NULL : dp);
        }
 }
 
index 702b88cbd91d2dc91eb81cb41784574b89df4edd..36c0e7af9d0f18df487aab2420414fd95b1f1302 100644 (file)
@@ -641,35 +641,48 @@ static void free_bd_holder(struct bd_holder *bo)
        kfree(bo);
 }
 
+/**
+ * find_bd_holder - find matching struct bd_holder from the block device
+ *
+ * @bdev:      struct block device to be searched
+ * @bo:                target struct bd_holder
+ *
+ * Returns matching entry with @bo in @bdev->bd_holder_list.
+ * If found, increment the reference count and return the pointer.
+ * If not found, returns NULL.
+ */
+static struct bd_holder *find_bd_holder(struct block_device *bdev,
+                                       struct bd_holder *bo)
+{
+       struct bd_holder *tmp;
+
+       list_for_each_entry(tmp, &bdev->bd_holder_list, list)
+               if (tmp->sdir == bo->sdir) {
+                       tmp->count++;
+                       return tmp;
+               }
+
+       return NULL;
+}
+
 /**
  * add_bd_holder - create sysfs symlinks for bd_claim() relationship
  *
  * @bdev:      block device to be bd_claimed
  * @bo:                preallocated and initialized by alloc_bd_holder()
  *
- * If there is no matching entry with @bo in @bdev->bd_holder_list,
- * add @bo to the list, create symlinks.
+ * Add @bo to @bdev->bd_holder_list, create symlinks.
  *
- * Returns 0 if symlinks are created or already there.
- * Returns -ve if something fails and @bo can be freed.
+ * Returns 0 if symlinks are created.
+ * Returns -ve if something fails.
  */
 static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo)
 {
-       struct bd_holder *tmp;
        int ret;
 
        if (!bo)
                return -EINVAL;
 
-       list_for_each_entry(tmp, &bdev->bd_holder_list, list) {
-               if (tmp->sdir == bo->sdir) {
-                       tmp->count++;
-                       /* We've already done what we need to do here. */
-                       free_bd_holder(bo);
-                       return 0;
-               }
-       }
-
        if (!bd_holder_grab_dirs(bdev, bo))
                return -EBUSY;
 
@@ -740,7 +753,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
                                struct kobject *kobj)
 {
        int res;
-       struct bd_holder *bo;
+       struct bd_holder *bo, *found;
 
        if (!kobj)
                return -EINVAL;
@@ -751,9 +764,16 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
 
        mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
        res = bd_claim(bdev, holder);
-       if (res == 0)
-               res = add_bd_holder(bdev, bo);
-       if (res)
+       if (res == 0) {
+               found = find_bd_holder(bdev, bo);
+               if (found == NULL) {
+                       res = add_bd_holder(bdev, bo);
+                       if (res)
+                               bd_release(bdev);
+               }
+       }
+
+       if (res || found)
                free_bd_holder(bo);
        mutex_unlock(&bdev->bd_mutex);
 
index ed35a9712fa15ae8a2c87e5a0c5405b3a162a835..f49f105394b70a91268a7ed63d56544aeff10fba 100644 (file)
@@ -94,25 +94,53 @@ static int ecryptfs_calculate_md5(char *dst,
                                  struct ecryptfs_crypt_stat *crypt_stat,
                                  char *src, int len)
 {
-       int rc = 0;
        struct scatterlist sg;
+       struct hash_desc desc = {
+               .tfm = crypt_stat->hash_tfm,
+               .flags = CRYPTO_TFM_REQ_MAY_SLEEP
+       };
+       int rc = 0;
 
-       mutex_lock(&crypt_stat->cs_md5_tfm_mutex);
+       mutex_lock(&crypt_stat->cs_hash_tfm_mutex);
        sg_init_one(&sg, (u8 *)src, len);
-       if (!crypt_stat->md5_tfm) {
-               crypt_stat->md5_tfm =
-                       crypto_alloc_tfm("md5", CRYPTO_TFM_REQ_MAY_SLEEP);
-               if (!crypt_stat->md5_tfm) {
-                       rc = -ENOMEM;
+       if (!desc.tfm) {
+               desc.tfm = crypto_alloc_hash(ECRYPTFS_DEFAULT_HASH, 0,
+                                            CRYPTO_ALG_ASYNC);
+               if (IS_ERR(desc.tfm)) {
+                       rc = PTR_ERR(desc.tfm);
                        ecryptfs_printk(KERN_ERR, "Error attempting to "
-                                       "allocate crypto context\n");
+                                       "allocate crypto context; rc = [%d]\n",
+                                       rc);
                        goto out;
                }
+               crypt_stat->hash_tfm = desc.tfm;
        }
-       crypto_digest_init(crypt_stat->md5_tfm);
-       crypto_digest_update(crypt_stat->md5_tfm, &sg, 1);
-       crypto_digest_final(crypt_stat->md5_tfm, dst);
-       mutex_unlock(&crypt_stat->cs_md5_tfm_mutex);
+       crypto_hash_init(&desc);
+       crypto_hash_update(&desc, &sg, len);
+       crypto_hash_final(&desc, dst);
+       mutex_unlock(&crypt_stat->cs_hash_tfm_mutex);
+out:
+       return rc;
+}
+
+int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
+                                          char *cipher_name,
+                                          char *chaining_modifier)
+{
+       int cipher_name_len = strlen(cipher_name);
+       int chaining_modifier_len = strlen(chaining_modifier);
+       int algified_name_len;
+       int rc;
+
+       algified_name_len = (chaining_modifier_len + cipher_name_len + 3);
+       (*algified_name) = kmalloc(algified_name_len, GFP_KERNEL);
+       if (!(algified_name)) {
+               rc = -ENOMEM;
+               goto out;
+       }
+       snprintf((*algified_name), algified_name_len, "%s(%s)",
+                chaining_modifier, cipher_name);
+       rc = 0;
 out:
        return rc;
 }
@@ -178,7 +206,7 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
        memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
        mutex_init(&crypt_stat->cs_mutex);
        mutex_init(&crypt_stat->cs_tfm_mutex);
-       mutex_init(&crypt_stat->cs_md5_tfm_mutex);
+       mutex_init(&crypt_stat->cs_hash_tfm_mutex);
        ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED);
 }
 
@@ -191,9 +219,9 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
 void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
 {
        if (crypt_stat->tfm)
-               crypto_free_tfm(crypt_stat->tfm);
-       if (crypt_stat->md5_tfm)
-               crypto_free_tfm(crypt_stat->md5_tfm);
+               crypto_free_blkcipher(crypt_stat->tfm);
+       if (crypt_stat->hash_tfm)
+               crypto_free_hash(crypt_stat->hash_tfm);
        memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
 }
 
@@ -203,7 +231,7 @@ void ecryptfs_destruct_mount_crypt_stat(
        if (mount_crypt_stat->global_auth_tok_key)
                key_put(mount_crypt_stat->global_auth_tok_key);
        if (mount_crypt_stat->global_key_tfm)
-               crypto_free_tfm(mount_crypt_stat->global_key_tfm);
+               crypto_free_blkcipher(mount_crypt_stat->global_key_tfm);
        memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
 }
 
@@ -269,6 +297,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
                               struct scatterlist *src_sg, int size,
                               unsigned char *iv)
 {
+       struct blkcipher_desc desc = {
+               .tfm = crypt_stat->tfm,
+               .info = iv,
+               .flags = CRYPTO_TFM_REQ_MAY_SLEEP
+       };
        int rc = 0;
 
        BUG_ON(!crypt_stat || !crypt_stat->tfm
@@ -282,8 +315,8 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
        }
        /* Consider doing this once, when the file is opened */
        mutex_lock(&crypt_stat->cs_tfm_mutex);
-       rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
-                                 crypt_stat->key_size);
+       rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
+                                    crypt_stat->key_size);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
                                rc);
@@ -292,7 +325,7 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
                goto out;
        }
        ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
-       crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv);
+       crypto_blkcipher_encrypt_iv(&desc, dest_sg, src_sg, size);
        mutex_unlock(&crypt_stat->cs_tfm_mutex);
 out:
        return rc;
@@ -675,12 +708,17 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
                               struct scatterlist *src_sg, int size,
                               unsigned char *iv)
 {
+       struct blkcipher_desc desc = {
+               .tfm = crypt_stat->tfm,
+               .info = iv,
+               .flags = CRYPTO_TFM_REQ_MAY_SLEEP
+       };
        int rc = 0;
 
        /* Consider doing this once, when the file is opened */
        mutex_lock(&crypt_stat->cs_tfm_mutex);
-       rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
-                                 crypt_stat->key_size);
+       rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key,
+                                    crypt_stat->key_size);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
                                rc);
@@ -689,8 +727,7 @@ static int decrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,
                goto out;
        }
        ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
-       rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size,
-                                     iv);
+       rc = crypto_blkcipher_decrypt_iv(&desc, dest_sg, src_sg, size);
        mutex_unlock(&crypt_stat->cs_tfm_mutex);
        if (rc) {
                ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
@@ -759,6 +796,7 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
  */
 int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
 {
+       char *full_alg_name;
        int rc = -EINVAL;
 
        if (!crypt_stat->cipher) {
@@ -775,16 +813,24 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
                goto out;
        }
        mutex_lock(&crypt_stat->cs_tfm_mutex);
-       crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
-                                          ECRYPTFS_DEFAULT_CHAINING_MODE
-                                          | CRYPTO_TFM_REQ_WEAK_KEY);
-       mutex_unlock(&crypt_stat->cs_tfm_mutex);
+       rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
+                                                   crypt_stat->cipher, "cbc");
+       if (rc)
+               goto out;
+       crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0,
+                                                CRYPTO_ALG_ASYNC);
+       kfree(full_alg_name);
        if (!crypt_stat->tfm) {
                ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
                                "Error initializing cipher [%s]\n",
                                crypt_stat->cipher);
+               mutex_unlock(&crypt_stat->cs_tfm_mutex);
                goto out;
        }
+       crypto_blkcipher_set_flags(crypt_stat->tfm,
+                                  (ECRYPTFS_DEFAULT_CHAINING_MODE
+                                   | CRYPTO_TFM_REQ_WEAK_KEY));
+       mutex_unlock(&crypt_stat->cs_tfm_mutex);
        rc = 0;
 out:
        return rc;
@@ -1145,28 +1191,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
 int ecryptfs_read_header_region(char *data, struct dentry *dentry,
                                struct vfsmount *mnt)
 {
-       struct file *file;
+       struct file *lower_file;
        mm_segment_t oldfs;
        int rc;
 
-       mnt = mntget(mnt);
-       file = dentry_open(dentry, mnt, O_RDONLY);
-       if (IS_ERR(file)) {
-               ecryptfs_printk(KERN_DEBUG, "Error opening file to "
-                               "read header region\n");
-               mntput(mnt);
-               rc = PTR_ERR(file);
+       if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt,
+                                          O_RDONLY))) {
+               printk(KERN_ERR
+                      "Error opening lower_file to read header region\n");
                goto out;
        }
-       file->f_pos = 0;
+       lower_file->f_pos = 0;
        oldfs = get_fs();
        set_fs(get_ds());
        /* For releases 0.1 and 0.2, all of the header information
         * fits in the first data extent-sized region. */
-       rc = file->f_op->read(file, (char __user *)data,
-                             ECRYPTFS_DEFAULT_EXTENT_SIZE, &file->f_pos);
+       rc = lower_file->f_op->read(lower_file, (char __user *)data,
+                             ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
        set_fs(oldfs);
-       fput(file);
+       if ((rc = ecryptfs_close_lower_file(lower_file))) {
+               printk(KERN_ERR "Error closing lower_file\n");
+               goto out;
+       }
        rc = 0;
 out:
        return rc;
@@ -1573,84 +1619,52 @@ out:
 
 /**
  * ecryptfs_process_cipher - Perform cipher initialization.
- * @tfm: Crypto context set by this function
  * @key_tfm: Crypto context for key material, set by this function
- * @cipher_name: Name of the cipher.
- * @key_size: Size of the key in bytes.
+ * @cipher_name: Name of the cipher
+ * @key_size: Size of the key in bytes
  *
  * Returns zero on success. Any crypto_tfm structs allocated here
  * should be released by other functions, such as on a superblock put
  * event, regardless of whether this function succeeds for fails.
  */
 int
-ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
-                       char *cipher_name, size_t key_size)
+ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
+                       size_t *key_size)
 {
        char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
+       char *full_alg_name;
        int rc;
 
-       *tfm = *key_tfm = NULL;
-       if (key_size > ECRYPTFS_MAX_KEY_BYTES) {
+       *key_tfm = NULL;
+       if (*key_size > ECRYPTFS_MAX_KEY_BYTES) {
                rc = -EINVAL;
                printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum "
-                      "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES);
+                     "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES);
                goto out;
        }
-       *tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE
-                                             | CRYPTO_TFM_REQ_WEAK_KEY));
-       if (!(*tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Unable to allocate crypto cipher with name "
-                      "[%s]\n", cipher_name);
+       rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, cipher_name,
+                                                   "ecb");
+       if (rc)
                goto out;
-       }
-       *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY);
-       if (!(*key_tfm)) {
-               rc = -EINVAL;
+       *key_tfm = crypto_alloc_blkcipher(full_alg_name, 0, CRYPTO_ALG_ASYNC);
+       kfree(full_alg_name);
+       if (IS_ERR(*key_tfm)) {
+               rc = PTR_ERR(*key_tfm);
                printk(KERN_ERR "Unable to allocate crypto cipher with name "
-                      "[%s]\n", cipher_name);
-               goto out;
-       }
-       if (key_size < crypto_tfm_alg_min_keysize(*tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*tfm));
-               goto out;
-       }
-       if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; minimum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
+                      "[%s]; rc = [%d]\n", cipher_name, rc);
                goto out;
        }
-       if (key_size > crypto_tfm_alg_max_keysize(*tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*tfm));
-               goto out;
-       }
-       if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) {
-               rc = -EINVAL;
-               printk(KERN_ERR "Request key size is [%Zd]; maximum key size "
-                      "supported by cipher [%s] is [%d]\n", key_size,
-                      cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
-               goto out;
-       }
-       get_random_bytes(dummy_key, key_size);
-       rc = crypto_cipher_setkey(*tfm, dummy_key, key_size);
-       if (rc) {
-               printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
-                      "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
-               rc = -EINVAL;
-               goto out;
+       crypto_blkcipher_set_flags(*key_tfm, CRYPTO_TFM_REQ_WEAK_KEY);
+       if (*key_size == 0) {
+               struct blkcipher_alg *alg = crypto_blkcipher_alg(*key_tfm);
+
+               *key_size = alg->max_keysize;
        }
-       rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size);
+       get_random_bytes(dummy_key, *key_size);
+       rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size);
        if (rc) {
                printk(KERN_ERR "Error attempting to set key of size [%Zd] for "
-                      "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+                      "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc);
                rc = -EINVAL;
                goto out;
        }
index f0d2a433242b58757f33483fec2a301410ce2aab..0b9992ab990f4cab4983a89aa4eb4f4026a1820b 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <linux/dcache.h>
 #include <linux/namei.h>
+#include <linux/mount.h>
 #include "ecryptfs_kernel.h"
 
 /**
@@ -76,8 +77,13 @@ static void ecryptfs_d_release(struct dentry *dentry)
        if (ecryptfs_dentry_to_private(dentry))
                kmem_cache_free(ecryptfs_dentry_info_cache,
                                ecryptfs_dentry_to_private(dentry));
-       if (lower_dentry)
+       if (lower_dentry) {
+               struct vfsmount *lower_mnt =
+                       ecryptfs_dentry_to_lower_mnt(dentry);
+
+               mntput(lower_mnt);
                dput(lower_dentry);
+       }
        return;
 }
 
index 872c9958531a0cf649d18de01805f65fae7d277d..f992533d1692b7a47d58f0f004712adc22efb01c 100644 (file)
@@ -175,6 +175,7 @@ ecryptfs_get_key_payload_data(struct key *key)
 #define ECRYPTFS_DEFAULT_CIPHER "aes"
 #define ECRYPTFS_DEFAULT_KEY_BYTES 16
 #define ECRYPTFS_DEFAULT_CHAINING_MODE CRYPTO_TFM_MODE_CBC
+#define ECRYPTFS_DEFAULT_HASH "md5"
 #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
 #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED
 #define MD5_DIGEST_SIZE 16
@@ -204,15 +205,15 @@ struct ecryptfs_crypt_stat {
        size_t extent_shift;
        unsigned int extent_mask;
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
-       struct crypto_tfm *tfm;
-       struct crypto_tfm *md5_tfm; /* Crypto context for generating
-                                    * the initialization vectors */
+       struct crypto_blkcipher *tfm;
+       struct crypto_hash *hash_tfm; /* Crypto context for generating
+                                      * the initialization vectors */
        unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
        unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
        unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
        unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX];
        struct mutex cs_tfm_mutex;
-       struct mutex cs_md5_tfm_mutex;
+       struct mutex cs_hash_tfm_mutex;
        struct mutex cs_mutex;
 };
 
@@ -244,7 +245,7 @@ struct ecryptfs_mount_crypt_stat {
        struct ecryptfs_auth_tok *global_auth_tok;
        struct key *global_auth_tok_key;
        size_t global_default_cipher_key_size;
-       struct crypto_tfm *global_key_tfm;
+       struct crypto_blkcipher *global_key_tfm;
        struct mutex global_key_tfm_mutex;
        unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
                                                 + 1];
@@ -425,6 +426,9 @@ void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
 void ecryptfs_destruct_mount_crypt_stat(
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
 int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
+int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
+                                          char *cipher_name,
+                                          char *chaining_modifier);
 int ecryptfs_write_inode_size_to_header(struct file *lower_file,
                                        struct inode *lower_inode,
                                        struct inode *inode);
@@ -473,10 +477,14 @@ ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
                          unsigned char *src, struct dentry *ecryptfs_dentry);
 int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
 int
-ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
-                       char *cipher_name, size_t key_size);
+ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
+                       size_t *key_size);
 int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
 int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
 void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
+int ecryptfs_open_lower_file(struct file **lower_file,
+                            struct dentry *lower_dentry,
+                            struct vfsmount *lower_mnt, int flags);
+int ecryptfs_close_lower_file(struct file *lower_file);
 
 #endif /* #ifndef ECRYPTFS_KERNEL_H */
index c8550c9f9cd277d43df40b966fb5e47930597cb4..a92ef05eff8f3d1ba52bdf481d14c728f9591eb1 100644 (file)
@@ -198,6 +198,33 @@ retry:
 
 struct kmem_cache *ecryptfs_file_info_cache;
 
+int ecryptfs_open_lower_file(struct file **lower_file,
+                            struct dentry *lower_dentry,
+                            struct vfsmount *lower_mnt, int flags)
+{
+       int rc = 0;
+
+       dget(lower_dentry);
+       mntget(lower_mnt);
+       *lower_file = dentry_open(lower_dentry, lower_mnt, flags);
+       if (IS_ERR(*lower_file)) {
+               printk(KERN_ERR "Error opening lower file for lower_dentry "
+                      "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n",
+                      lower_dentry, lower_mnt, flags);
+               rc = PTR_ERR(*lower_file);
+               *lower_file = NULL;
+               goto out;
+       }
+out:
+       return rc;
+}
+
+int ecryptfs_close_lower_file(struct file *lower_file)
+{
+       fput(lower_file);
+       return 0;
+}
+
 /**
  * ecryptfs_open
  * @inode: inode speciying file to open
@@ -244,19 +271,15 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
                ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
        }
        mutex_unlock(&crypt_stat->cs_mutex);
-       /* This mntget & dget is undone via fput when the file is released */
-       dget(lower_dentry);
        lower_flags = file->f_flags;
        if ((lower_flags & O_ACCMODE) == O_WRONLY)
                lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
        if (file->f_flags & O_APPEND)
                lower_flags &= ~O_APPEND;
        lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
-       mntget(lower_mnt);
        /* Corresponding fput() in ecryptfs_release() */
-       lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags);
-       if (IS_ERR(lower_file)) {
-               rc = PTR_ERR(lower_file);
+       if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
+                                          lower_flags))) {
                ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
                goto out_puts;
        }
@@ -341,11 +364,16 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
        struct file *lower_file = ecryptfs_file_to_lower(file);
        struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file);
        struct inode *lower_inode = ecryptfs_inode_to_lower(inode);
+       int rc;
 
-       fput(lower_file);
+       if ((rc = ecryptfs_close_lower_file(lower_file))) {
+               printk(KERN_ERR "Error closing lower_file\n");
+               goto out;
+       }
        inode->i_blocks = lower_inode->i_blocks;
        kmem_cache_free(ecryptfs_file_info_cache, file_info);
-       return 0;
+out:
+       return rc;
 }
 
 static int
index efdd2b7b62d707da7d7fdba901d5cc4331be0e54..ff4865d24f0f1061dcc7dbd47fd169330f136869 100644 (file)
@@ -231,7 +231,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
        int lower_flags;
        struct ecryptfs_crypt_stat *crypt_stat;
        struct dentry *lower_dentry;
-       struct dentry *tlower_dentry = NULL;
        struct file *lower_file;
        struct inode *inode, *lower_inode;
        struct vfsmount *lower_mnt;
@@ -241,30 +240,19 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
                        lower_dentry->d_name.name);
        inode = ecryptfs_dentry->d_inode;
        crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
-       tlower_dentry = dget(lower_dentry);
-       if (!tlower_dentry) {
-               rc = -ENOMEM;
-               ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry\n");
-               goto out;
-       }
        lower_flags = ((O_CREAT | O_WRONLY | O_TRUNC) & O_ACCMODE) | O_RDWR;
 #if BITS_PER_LONG != 32
        lower_flags |= O_LARGEFILE;
 #endif
        lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
-       mntget(lower_mnt);
        /* Corresponding fput() at end of this function */
-       lower_file = dentry_open(tlower_dentry, lower_mnt, lower_flags);
-       if (IS_ERR(lower_file)) {
-               rc = PTR_ERR(lower_file);
+       if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
+                                          lower_flags))) {
                ecryptfs_printk(KERN_ERR,
                                "Error opening dentry; rc = [%i]\n", rc);
                goto out;
        }
-       /* fput(lower_file) should handle the puts if we do this */
-       lower_file->f_dentry = tlower_dentry;
-       lower_file->f_vfsmnt = lower_mnt;
-       lower_inode = tlower_dentry->d_inode;
+       lower_inode = lower_dentry->d_inode;
        if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
                ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
                ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_ENCRYPTED);
@@ -285,7 +273,8 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
        }
        rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode);
 out_fput:
-       fput(lower_file);
+       if ((rc = ecryptfs_close_lower_file(lower_file)))
+               printk(KERN_ERR "Error closing lower_file\n");
 out:
        return rc;
 }
@@ -336,7 +325,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
        struct dentry *lower_dir_dentry;
        struct dentry *lower_dentry;
        struct vfsmount *lower_mnt;
-       struct dentry *tlower_dentry = NULL;
        char *encoded_name;
        unsigned int encoded_namelen;
        struct ecryptfs_crypt_stat *crypt_stat = NULL;
@@ -347,27 +335,32 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
        lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent);
        dentry->d_op = &ecryptfs_dops;
        if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, "."))
-           || (dentry->d_name.len == 2 && !strcmp(dentry->d_name.name, "..")))
-               goto out_drop;
+           || (dentry->d_name.len == 2
+               && !strcmp(dentry->d_name.name, ".."))) {
+               d_drop(dentry);
+               goto out;
+       }
        encoded_namelen = ecryptfs_encode_filename(crypt_stat,
                                                   dentry->d_name.name,
                                                   dentry->d_name.len,
                                                   &encoded_name);
        if (encoded_namelen < 0) {
                rc = encoded_namelen;
-               goto out_drop;
+               d_drop(dentry);
+               goto out;
        }
        ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen "
                        "= [%d]\n", encoded_name, encoded_namelen);
        lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry,
                                      encoded_namelen - 1);
        kfree(encoded_name);
-       lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
        if (IS_ERR(lower_dentry)) {
                ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n");
                rc = PTR_ERR(lower_dentry);
-               goto out_drop;
+               d_drop(dentry);
+               goto out;
        }
+       lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
        ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->"
                        "d_name.name = [%s]\n", lower_dentry,
                lower_dentry->d_name.name);
@@ -408,12 +401,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
                                "as we *think* we are about to unlink\n");
                goto out;
        }
-       tlower_dentry = dget(lower_dentry);
-       if (!tlower_dentry || IS_ERR(tlower_dentry)) {
-               rc = -ENOMEM;
-               ecryptfs_printk(KERN_ERR, "Cannot dget lower_dentry\n");
-               goto out_dput;
-       }
        /* Released in this function */
        page_virt =
            (char *)kmem_cache_alloc(ecryptfs_header_cache_2,
@@ -425,7 +412,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
                goto out_dput;
        }
        memset(page_virt, 0, PAGE_CACHE_SIZE);
-       rc = ecryptfs_read_header_region(page_virt, tlower_dentry, nd->mnt);
+       rc = ecryptfs_read_header_region(page_virt, lower_dentry, nd->mnt);
        crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
        if (!ECRYPTFS_CHECK_FLAG(crypt_stat->flags, ECRYPTFS_POLICY_APPLIED))
                ecryptfs_set_default_sizes(crypt_stat);
@@ -448,9 +435,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
 
 out_dput:
        dput(lower_dentry);
-       if (tlower_dentry)
-               dput(tlower_dentry);
-out_drop:
        d_drop(dentry);
 out:
        return ERR_PTR(rc);
@@ -486,8 +470,8 @@ out_lock:
        unlock_dir(lower_dir_dentry);
        dput(lower_new_dentry);
        dput(lower_old_dentry);
-       if (!new_dentry->d_inode)
-               d_drop(new_dentry);
+       d_drop(new_dentry);
+       d_drop(old_dentry);
        return rc;
 }
 
@@ -576,41 +560,24 @@ out:
 
 static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
 {
-       int rc = 0;
-       struct dentry *tdentry = NULL;
        struct dentry *lower_dentry;
-       struct dentry *tlower_dentry = NULL;
        struct dentry *lower_dir_dentry;
+       int rc;
 
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
-       if (!(tdentry = dget(dentry))) {
-               rc = -EINVAL;
-               ecryptfs_printk(KERN_ERR, "Error dget'ing dentry [%p]\n",
-                               dentry);
-               goto out;
-       }
+       dget(dentry);
        lower_dir_dentry = lock_parent(lower_dentry);
-       if (!(tlower_dentry = dget(lower_dentry))) {
-               rc = -EINVAL;
-               ecryptfs_printk(KERN_ERR, "Error dget'ing lower_dentry "
-                               "[%p]\n", lower_dentry);
-               goto out;
-       }
+       dget(lower_dentry);
        rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
-       if (!rc) {
-               d_delete(tlower_dentry);
-               tlower_dentry = NULL;
-       }
+       dput(lower_dentry);
+       if (!rc)
+               d_delete(lower_dentry);
        ecryptfs_copy_attr_times(dir, lower_dir_dentry->d_inode);
        dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
        unlock_dir(lower_dir_dentry);
        if (!rc)
                d_drop(dentry);
-out:
-       if (tdentry)
-               dput(tdentry);
-       if (tlower_dentry)
-               dput(tlower_dentry);
+       dput(dentry);
        return rc;
 }
 
@@ -832,12 +799,11 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
        }
        lower_dentry = ecryptfs_dentry_to_lower(dentry);
        /* This dget & mntget is released through fput at out_fput: */
-       dget(lower_dentry);
        lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
-       mntget(lower_mnt);
-       lower_file = dentry_open(lower_dentry, lower_mnt, O_RDWR);
-       if (unlikely(IS_ERR(lower_file))) {
-               rc = PTR_ERR(lower_file);
+       if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
+                                          O_RDWR))) {
+               ecryptfs_printk(KERN_ERR,
+                               "Error opening dentry; rc = [%i]\n", rc);
                goto out_free;
        }
        ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
@@ -879,7 +845,8 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
                = CURRENT_TIME;
        mark_inode_dirty_sync(inode);
 out_fput:
-       fput(lower_file);
+       if ((rc = ecryptfs_close_lower_file(lower_file)))
+               printk(KERN_ERR "Error closing lower_file\n");
 out_free:
        if (ecryptfs_file_to_private(&fake_ecryptfs_file))
                kmem_cache_free(ecryptfs_file_info_cache,
index ba454785a0c5864c6878041980829cfeda477a82..c3746f56d1627ab2246d5086731103353f9537d3 100644 (file)
@@ -458,14 +458,16 @@ out:
 static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
                               struct ecryptfs_crypt_stat *crypt_stat)
 {
-       int rc = 0;
        struct ecryptfs_password *password_s_ptr;
-       struct crypto_tfm *tfm = NULL;
        struct scatterlist src_sg[2], dst_sg[2];
        struct mutex *tfm_mutex = NULL;
        /* TODO: Use virt_to_scatterlist for these */
        char *encrypted_session_key;
        char *session_key;
+       struct blkcipher_desc desc = {
+               .flags = CRYPTO_TFM_REQ_MAY_SLEEP
+       };
+       int rc = 0;
 
        password_s_ptr = &auth_tok->token.password;
        if (ECRYPTFS_CHECK_FLAG(password_s_ptr->flags,
@@ -482,30 +484,37 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
        if (!strcmp(crypt_stat->cipher,
                    crypt_stat->mount_crypt_stat->global_default_cipher_name)
            && crypt_stat->mount_crypt_stat->global_key_tfm) {
-               tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+               desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
                tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
        } else {
-               tfm = crypto_alloc_tfm(crypt_stat->cipher,
-                                      CRYPTO_TFM_REQ_WEAK_KEY);
-               if (!tfm) {
-                       printk(KERN_ERR "Error allocating crypto context\n");
-                       rc = -ENOMEM;
+               char *full_alg_name;
+
+               rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
+                                                           crypt_stat->cipher,
+                                                           "ecb");
+               if (rc)
+                       goto out;
+               desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
+                                                 CRYPTO_ALG_ASYNC);
+               kfree(full_alg_name);
+               if (IS_ERR(desc.tfm)) {
+                       rc = PTR_ERR(desc.tfm);
+                       printk(KERN_ERR "Error allocating crypto context; "
+                              "rc = [%d]\n", rc);
                        goto out;
                }
-       }
-       if (password_s_ptr->session_key_encryption_key_bytes
-           < crypto_tfm_alg_min_keysize(tfm)) {
-               printk(KERN_WARNING "Session key encryption key is [%d] bytes; "
-                      "minimum keysize for selected cipher is [%d] bytes.\n",
-                      password_s_ptr->session_key_encryption_key_bytes,
-                      crypto_tfm_alg_min_keysize(tfm));
-               rc = -EINVAL;
-               goto out;
+               crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
        }
        if (tfm_mutex)
                mutex_lock(tfm_mutex);
-       crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
-                            crypt_stat->key_size);
+       rc = crypto_blkcipher_setkey(desc.tfm,
+                                    password_s_ptr->session_key_encryption_key,
+                                    crypt_stat->key_size);
+       if (rc < 0) {
+               printk(KERN_ERR "Error setting key for crypto context\n");
+               rc = -EINVAL;
+               goto out_free_tfm;
+       }
        /* TODO: virt_to_scatterlist */
        encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
        if (!encrypted_session_key) {
@@ -531,9 +540,12 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
        auth_tok->session_key.decrypted_key_size =
            auth_tok->session_key.encrypted_key_size;
        dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
-       /* TODO: Handle error condition */
-       crypto_cipher_decrypt(tfm, dst_sg, src_sg,
-                             auth_tok->session_key.encrypted_key_size);
+       rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg,
+                                     auth_tok->session_key.encrypted_key_size);
+       if (rc) {
+               printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc);
+               goto out_free_memory;
+       }
        auth_tok->session_key.decrypted_key_size =
            auth_tok->session_key.encrypted_key_size;
        memcpy(auth_tok->session_key.decrypted_key, session_key,
@@ -546,6 +558,7 @@ static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
        if (ecryptfs_verbosity > 0)
                ecryptfs_dump_hex(crypt_stat->key,
                                  crypt_stat->key_size);
+out_free_memory:
        memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
        free_page((unsigned long)encrypted_session_key);
        memset(session_key, 0, PAGE_CACHE_SIZE);
@@ -554,7 +567,7 @@ out_free_tfm:
        if (tfm_mutex)
                mutex_unlock(tfm_mutex);
        else
-               crypto_free_tfm(tfm);
+               crypto_free_blkcipher(desc.tfm);
 out:
        return rc;
 }
@@ -803,19 +816,21 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
                   struct ecryptfs_crypt_stat *crypt_stat,
                   struct ecryptfs_key_record *key_rec, size_t *packet_size)
 {
-       int rc = 0;
-
        size_t i;
        size_t signature_is_valid = 0;
        size_t encrypted_session_key_valid = 0;
        char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
        struct scatterlist dest_sg[2];
        struct scatterlist src_sg[2];
-       struct crypto_tfm *tfm = NULL;
        struct mutex *tfm_mutex = NULL;
        size_t key_rec_size;
        size_t packet_size_length;
        size_t cipher_code;
+       struct blkcipher_desc desc = {
+               .tfm = NULL,
+               .flags = CRYPTO_TFM_REQ_MAY_SLEEP
+       };
+       int rc = 0;
 
        (*packet_size) = 0;
        /* Check for a valid signature on the auth_tok */
@@ -882,33 +897,48 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
        if (!strcmp(crypt_stat->cipher,
                    crypt_stat->mount_crypt_stat->global_default_cipher_name)
            && crypt_stat->mount_crypt_stat->global_key_tfm) {
-               tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+               desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
                tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
-       } else
-               tfm = crypto_alloc_tfm(crypt_stat->cipher, 0);
-       if (!tfm) {
-               ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
-                               "context for cipher [%s]\n",
-                               crypt_stat->cipher);
-               rc = -EINVAL;
-               goto out;
+       } else {
+               char *full_alg_name;
+
+               rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
+                                                           crypt_stat->cipher,
+                                                           "ecb");
+               if (rc)
+                       goto out;
+               desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
+                                                 CRYPTO_ALG_ASYNC);
+               kfree(full_alg_name);
+               if (IS_ERR(desc.tfm)) {
+                       rc = PTR_ERR(desc.tfm);
+                       ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
+                                       "context for cipher [%s]; rc = [%d]\n",
+                                       crypt_stat->cipher, rc);
+                       goto out;
+               }
+               crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
        }
        if (tfm_mutex)
                mutex_lock(tfm_mutex);
-       rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
-                                 crypt_stat->key_size);
+       rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key,
+                                    crypt_stat->key_size);
        if (rc < 0) {
                if (tfm_mutex)
                        mutex_unlock(tfm_mutex);
                ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
-                               "context\n");
+                               "context; rc = [%d]\n", rc);
                goto out;
        }
        rc = 0;
        ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
                        crypt_stat->key_size);
-       crypto_cipher_encrypt(tfm, dest_sg, src_sg,
-                             (*key_rec).enc_key_size);
+       rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg,
+                                     (*key_rec).enc_key_size);
+       if (rc) {
+               printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc);
+               goto out;
+       }
        if (tfm_mutex)
                mutex_unlock(tfm_mutex);
        ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
@@ -971,8 +1001,8 @@ encrypted_session_key_set:
               (*key_rec).enc_key_size);
        (*packet_size) += (*key_rec).enc_key_size;
 out:
-       if (tfm && !tfm_mutex)
-               crypto_free_tfm(tfm);
+       if (desc.tfm && !tfm_mutex)
+               crypto_free_blkcipher(desc.tfm);
        if (rc)
                (*packet_size) = 0;
        return rc;
index 5938a232d11bd3e3feed0ed01ae3ba5a04918c7f..a78d87d14bafb2256313753cc8aeaeeb6c0b381f 100644 (file)
@@ -208,7 +208,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
        char *cipher_name_dst;
        char *cipher_name_src;
        char *cipher_key_bytes_src;
-       struct crypto_tfm *tmp_tfm;
        int cipher_name_len;
 
        if (!options) {
@@ -305,25 +304,19 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
                    = '\0';
        }
        if (!cipher_key_bytes_set) {
-               mount_crypt_stat->global_default_cipher_key_size =
-                       ECRYPTFS_DEFAULT_KEY_BYTES;
-               ecryptfs_printk(KERN_DEBUG, "Cipher key size was not "
-                               "specified.  Defaulting to [%d]\n",
-                               mount_crypt_stat->
-                               global_default_cipher_key_size);
+               mount_crypt_stat->global_default_cipher_key_size = 0;
        }
        rc = ecryptfs_process_cipher(
-               &tmp_tfm,
                &mount_crypt_stat->global_key_tfm,
                mount_crypt_stat->global_default_cipher_name,
-               mount_crypt_stat->global_default_cipher_key_size);
-       if (tmp_tfm)
-               crypto_free_tfm(tmp_tfm);
+               &mount_crypt_stat->global_default_cipher_key_size);
        if (rc) {
                printk(KERN_ERR "Error attempting to initialize cipher [%s] "
                       "with key size [%Zd] bytes; rc = [%d]\n",
                       mount_crypt_stat->global_default_cipher_name,
                       mount_crypt_stat->global_default_cipher_key_size, rc);
+               mount_crypt_stat->global_key_tfm = NULL;
+               mount_crypt_stat->global_auth_tok_key = NULL;
                rc = -EINVAL;
                goto out;
        }
index c337c0410fb14b890f2932682355ed1b4baa273c..825757ae48676d6a488f64413316a7429b55fbbc 100644 (file)
@@ -137,23 +137,6 @@ static void ecryptfs_clear_inode(struct inode *inode)
        iput(ecryptfs_inode_to_lower(inode));
 }
 
-/**
- * ecryptfs_umount_begin
- *
- * Called in do_umount().
- */
-static void ecryptfs_umount_begin(struct vfsmount *vfsmnt, int flags)
-{
-       struct vfsmount *lower_mnt =
-               ecryptfs_dentry_to_lower_mnt(vfsmnt->mnt_sb->s_root);
-       struct super_block *lower_sb;
-
-       mntput(lower_mnt);
-       lower_sb = lower_mnt->mnt_sb;
-       if (lower_sb->s_op->umount_begin)
-               lower_sb->s_op->umount_begin(lower_mnt, flags);
-}
-
 /**
  * ecryptfs_show_options
  *
@@ -193,6 +176,5 @@ struct super_operations ecryptfs_sops = {
        .statfs = ecryptfs_statfs,
        .remount_fs = NULL,
        .clear_inode = ecryptfs_clear_inode,
-       .umount_begin = ecryptfs_umount_begin,
        .show_options = ecryptfs_show_options
 };
index 276ea7e8144ae3cfc8e58b7819ae59c126f90578..059a9ff28b4d03b66fff8a2aff97ba962d14ceb4 100644 (file)
 
 #ifdef CONFIG_X86_IO_APIC
 
-#define IO_APIC_BASE(idx) \
-               ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \
-               + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))
-
 /*
  * The structure of the IO-APIC:
  */
@@ -119,31 +115,8 @@ extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
 
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
-       *IO_APIC_BASE(apic) = reg;
-       return *(IO_APIC_BASE(apic)+4);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
-       *IO_APIC_BASE(apic) = reg;
-       *(IO_APIC_BASE(apic)+4) = value;
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index regiser
- */
+/* Older SiS APIC requires we rewrite the index register */
 extern int sis_apic_bug;
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
-{
-       if (sis_apic_bug)
-               *IO_APIC_BASE(apic) = reg;
-       *(IO_APIC_BASE(apic)+4) = value;
-}
 
 /* 1 if "noapic" boot option passed */
 extern int skip_ioapic_setup;
index 0b210abbe0033ce06a1f7c1db28e8bcf0395ef6e..d000689d91421f6b0103660fe047146b166d50d0 100644 (file)
@@ -659,6 +659,7 @@ ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second,
 }
 
 extern s64 ia64_sal_cache_flush (u64 cache_type);
+extern void __init check_sal_cache_flush (void);
 
 /* Initialize all the processor and platform level instruction and data caches */
 static inline s64
index 9adb51211c2270d7500dfb00d8ed3a59264651e6..449c8c0fa2bdc65165ff62248fdb4dbf8cba129e 100644 (file)
@@ -389,7 +389,7 @@ xlate_dev_kmem_ptr (char * p)
        struct page *page;
        char * ptr;
 
-       page = virt_to_page((unsigned long)p >> PAGE_SHIFT);
+       page = virt_to_page((unsigned long)p);
        if (PageUncached(page))
                ptr = (char *)__pa(p) + __IA64_UNCACHED_OFFSET;
        else
index e3038a4599eef0f8ffa61693bd63a09a22cd2df2..838eb3144d8188dc0938a48ef9a96c6380a62846 100644 (file)
@@ -344,6 +344,7 @@ symbol              =       value
 #define PTR_L          lw
 #define PTR_S          sw
 #define PTR_LA         la
+#define PTR_LI         li
 #define PTR_SLL                sll
 #define PTR_SLLV       sllv
 #define PTR_SRL                srl
@@ -368,6 +369,7 @@ symbol              =       value
 #define PTR_L          ld
 #define PTR_S          sd
 #define PTR_LA         dla
+#define PTR_LI         dli
 #define PTR_SLL                dsll
 #define PTR_SLLV       dsllv
 #define PTR_SRL                dsrl
index 5f7dcf5452e75db5a35ea9b41d8ed0a67fd29d07..d107832de1b65f786648bb3dac70b44509c85c7a 100644 (file)
 
 #if (_MIPS_SZLONG == 64)
 
-/*
- * Don't use this one in new code
- */
-#define do_div64_32(res, high, low, base) ({ \
-       unsigned int __quot, __mod; \
-       unsigned long __div; \
-       unsigned int __low, __high, __base; \
-       \
-       __high = (high); \
-       __low = (low); \
-       __div = __high; \
-       __div = __div << 32 | __low; \
-       __base = (base); \
-       \
-       __mod = __div % __base; \
-       __div = __div / __base; \
-       \
-       __quot = __div; \
-       (res) = __quot; \
-       __mod; })
-
 /*
  * Hey, we're already 64-bit, no
  * need to play games..
index f637ce70758fb363b930f18615726c6205d060d7..3e9468f424f43a7ed51b513b4416c23f44ee21ca 100644 (file)
@@ -352,6 +352,8 @@ do {                                                                        \
 #define write_vpe_c0_vpecontrol(val)   mttc0(1, 1, val)
 #define read_vpe_c0_vpeconf0()         mftc0(1, 2)
 #define write_vpe_c0_vpeconf0(val)     mttc0(1, 2, val)
+#define read_vpe_c0_count()            mftc0(9, 0)
+#define write_vpe_c0_count(val)                mttc0(9, 0, val)
 #define read_vpe_c0_status()           mftc0(12, 0)
 #define write_vpe_c0_status(val)       mttc0(12, 0, val)
 #define read_vpe_c0_cause()            mftc0(13, 0)
index 582c1fe6cc4ac1243206f9d9901b251cb3d3d25a..af121c67dc7197d01d5094e0e689d5fe1095bdc7 100644 (file)
@@ -48,7 +48,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 
        ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
        if (ret) {
-               init = pgd_offset(&init_mm, 0);
+               init = pgd_offset(&init_mm, 0UL);
                pgd_init((unsigned long)ret);
                memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
index d05fb6f38aa7523c61e943f81d33ab2257058a1d..7e7320300aa3884440286066482876eb5db8f5ea 100644 (file)
@@ -174,7 +174,7 @@ static inline void pud_clear(pud_t *pudp)
 #define __pmd_offset(address)  pmd_index(address)
 
 /* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, 0)
+#define pgd_offset_k(address) pgd_offset(&init_mm, 0UL)
 
 #define pgd_index(address)     (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 #define pmd_index(address)     (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
index b09e16c93ca020f215a81e7a2b2ec637c1f06345..2ba6988ddc8e897a3c43fdd2844d08a625a7d054 100644 (file)
@@ -51,8 +51,8 @@ extern void sb1250_mask_irq(int cpu, int irq);
 extern void sb1250_unmask_irq(int cpu, int irq);
 extern void sb1250_smp_finish(void);
 
+extern void bcm1480_hpt_setup(void);
 extern void bcm1480_time_init(void);
-extern unsigned long bcm1480_gettimeoffset(void);
 extern void bcm1480_mask_irq(int cpu, int irq);
 extern void bcm1480_unmask_irq(int cpu, int irq);
 extern void bcm1480_smp_finish(void);
index 28512ba2266e6f388c8db4450646de6c64dc9d29..625acd337bc3fe32bf0f0532cf30268d0af6c54c 100644 (file)
@@ -48,7 +48,8 @@ extern void (*mips_timer_ack)(void);
  * If mips_hpt_read is NULL, an R4k-compatible timer setup is attempted.
  */
 extern unsigned int (*mips_hpt_read)(void);
-extern void (*mips_hpt_init)(unsigned int);
+extern void (*mips_hpt_init)(void);
+extern unsigned int mips_hpt_mask;
 
 /*
  * to_tm() converts system time back to (year, mon, day, hour, min, sec).
@@ -57,13 +58,6 @@ extern void (*mips_hpt_init)(unsigned int);
  */
 extern void to_tm(unsigned long tim, struct rtc_time *tm);
 
-/*
- * do_gettimeoffset(). By default, this func pointer points to
- * do_null_gettimeoffset(), which leads to the same resolution as HZ.
- * Higher resolution versions are available, which give ~1us resolution.
- */
-extern unsigned long (*do_gettimeoffset)(void);
-
 /*
  * high-level timer interrupt routines.
  */
index 30240a445dbbf3ff72f0d54ed6f6b1904f2eb330..ec56aa52f669f2092847290b9fccb8309d6ae35e 100644 (file)
 #define __NR_set_robust_list           (__NR_Linux + 309)
 #define __NR_get_robust_list           (__NR_Linux + 310)
 #define __NR_kexec_load                        (__NR_Linux + 311)
+#define __NR_getcpu                    (__NR_Linux + 312)
+#define __NR_epoll_pwait               (__NR_Linux + 313)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls            311
+#define __NR_Linux_syscalls            313
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux                 4000
-#define __NR_O32_Linux_syscalls                311
+#define __NR_O32_Linux_syscalls                313
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
 #define __NR_set_robust_list           (__NR_Linux + 268)
 #define __NR_get_robust_list           (__NR_Linux + 269)
 #define __NR_kexec_load                        (__NR_Linux + 270)
+#define __NR_getcpu                    (__NR_Linux + 271)
+#define __NR_epoll_pwait               (__NR_Linux + 272)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls            270
+#define __NR_Linux_syscalls            272
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux                  5000
-#define __NR_64_Linux_syscalls         270
+#define __NR_64_Linux_syscalls         272
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
 #define __NR_set_robust_list           (__NR_Linux + 272)
 #define __NR_get_robust_list           (__NR_Linux + 273)
 #define __NR_kexec_load                        (__NR_Linux + 274)
+#define __NR_getcpu                    (__NR_Linux + 275)
+#define __NR_epoll_pwait               (__NR_Linux + 276)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls            274
+#define __NR_Linux_syscalls            276
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux                 6000
-#define __NR_N32_Linux_syscalls                274
+#define __NR_N32_Linux_syscalls                276
 
 #ifdef __KERNEL__
 
@@ -1189,6 +1195,7 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
 #endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */
 
 
+#define __ARCH_OMIT_COMPAT_SYS_GETDENTS64
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
index 1938d6abd255056f46711b2786c3720123d90445..b8708aedf925327c13e727d094ad6398b3156850 100644 (file)
@@ -14,7 +14,17 @@ struct task_struct;
 #ifdef __powerpc64__
 #include <asm/paca.h>
 
-#define current                (get_paca()->__current)
+static inline struct task_struct *get_current(void)
+{
+       struct task_struct *task;
+
+       __asm__ __volatile__("ld %0,%1(13)"
+       : "=r" (task)
+       : "i" (offsetof(struct paca_struct, __current)));
+
+       return task;
+}
+#define current        get_current()
 
 #else
 
index 3baff8b0fd5add68cb7dfde5e1324ac182a7801e..c2c5f14b5f5ff3dd8c335cf4025d3c34096f58a1 100644 (file)
@@ -163,8 +163,11 @@ extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count);
 
 static inline void mmiowb(void)
 {
-       __asm__ __volatile__ ("sync" : : : "memory");
-       get_paca()->io_sync = 0;
+       unsigned long tmp;
+
+       __asm__ __volatile__("sync; li %0,0; stb %0,%1(13)"
+       : "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync))
+       : "memory");
 }
 
 /*
index a5e98641a2ae7a8b3724d328687e7dd46a454119..39fad685ffab6c99f72b060141ba7902d1efd607 100644 (file)
 #define _ASM_IOMMU_H
 #ifdef __KERNEL__
 
-#include <asm/types.h>
+#include <linux/compiler.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
+#include <asm/types.h>
+#include <asm/bitops.h>
+
+#define IOMMU_PAGE_SHIFT      12
+#define IOMMU_PAGE_SIZE       (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
+#define IOMMU_PAGE_MASK       (~((1 << IOMMU_PAGE_SHIFT) - 1))
+#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
+
+#ifndef __ASSEMBLY__
+
+/* Pure 2^n version of get_order */
+static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
+{
+       return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1;
+}
+
+#endif   /* __ASSEMBLY__ */
+
 
 /*
  * IOMAP_MAX_ORDER defines the largest contiguous block
  * of dma space we can get.  IOMAP_MAX_ORDER = 13
  * allows up to 2**12 pages (4096 * 4096) = 16 MB
  */
-#define IOMAP_MAX_ORDER 13
+#define IOMAP_MAX_ORDER                13
 
 struct iommu_table {
        unsigned long  it_busno;     /* Bus number this table belongs to */
index 5b33994cd488ffc2f94f7b85b0fa12fa0cb047c4..07a10e590c1de44d951bb0b25e3bdfd364670f94 100644 (file)
@@ -42,7 +42,7 @@ struct op_powerpc_model {
        void (*reg_setup) (struct op_counter_config *,
                           struct op_system_config *,
                           int num_counters);
-       void (*cpu_setup) (void *);
+       void (*cpu_setup) (struct op_counter_config *);
        void (*start) (struct op_counter_config *);
        void (*stop) (void);
        void (*handle_interrupt) (struct pt_regs *,
@@ -121,7 +121,90 @@ static inline void ctr_write(unsigned int i, unsigned int val)
                break;
        }
 }
-#endif /* !CONFIG_FSL_BOOKE */
+#else /* CONFIG_FSL_BOOKE */
+static inline u32 get_pmlca(int ctr)
+{
+       u32 pmlca;
+
+       switch (ctr) {
+               case 0:
+                       pmlca = mfpmr(PMRN_PMLCA0);
+                       break;
+               case 1:
+                       pmlca = mfpmr(PMRN_PMLCA1);
+                       break;
+               case 2:
+                       pmlca = mfpmr(PMRN_PMLCA2);
+                       break;
+               case 3:
+                       pmlca = mfpmr(PMRN_PMLCA3);
+                       break;
+               default:
+                       panic("Bad ctr number\n");
+       }
+
+       return pmlca;
+}
+
+static inline void set_pmlca(int ctr, u32 pmlca)
+{
+       switch (ctr) {
+               case 0:
+                       mtpmr(PMRN_PMLCA0, pmlca);
+                       break;
+               case 1:
+                       mtpmr(PMRN_PMLCA1, pmlca);
+                       break;
+               case 2:
+                       mtpmr(PMRN_PMLCA2, pmlca);
+                       break;
+               case 3:
+                       mtpmr(PMRN_PMLCA3, pmlca);
+                       break;
+               default:
+                       panic("Bad ctr number\n");
+       }
+}
+
+static inline unsigned int ctr_read(unsigned int i)
+{
+       switch(i) {
+               case 0:
+                       return mfpmr(PMRN_PMC0);
+               case 1:
+                       return mfpmr(PMRN_PMC1);
+               case 2:
+                       return mfpmr(PMRN_PMC2);
+               case 3:
+                       return mfpmr(PMRN_PMC3);
+               default:
+                       return 0;
+       }
+}
+
+static inline void ctr_write(unsigned int i, unsigned int val)
+{
+       switch(i) {
+               case 0:
+                       mtpmr(PMRN_PMC0, val);
+                       break;
+               case 1:
+                       mtpmr(PMRN_PMC1, val);
+                       break;
+               case 2:
+                       mtpmr(PMRN_PMC2, val);
+                       break;
+               case 3:
+                       mtpmr(PMRN_PMC3, val);
+                       break;
+               default:
+                       break;
+       }
+}
+
+
+#endif /* CONFIG_FSL_BOOKE */
+
 
 extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);
 
index 07d6a427931983d4df83ea146083a289f3f7f980..8588be68e0ad616e987a95746d7b8f8ef9995939 100644 (file)
@@ -32,18 +32,5 @@ void release_pmc_hardware(void);
 void power4_enable_pmcs(void);
 #endif
 
-#ifdef CONFIG_FSL_BOOKE
-void init_pmc_stop(int ctr);
-void set_pmc_event(int ctr, int event);
-void set_pmc_user_kernel(int ctr, int user, int kernel);
-void set_pmc_marked(int ctr, int mark0, int mark1);
-void pmc_start_ctr(int ctr, int enable);
-void pmc_start_ctrs(int enable);
-void pmc_stop_ctrs(void);
-void dump_pmcs(void);
-
-extern struct op_powerpc_model op_model_fsl_booke;
-#endif
-
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PMC_H */
index 43627596003b8ec7017230fa292aac27c4a52995..f7b1227d64548ab68f557f78a1ba1fa5afe89bf1 100644 (file)
@@ -25,8 +25,8 @@
  *
  * We have to use the sync instructions for mb(), since lwsync doesn't
  * order loads with respect to previous stores.  Lwsync is fine for
- * rmb(), though.  Note that lwsync is interpreted as sync by
- * 32-bit and older 64-bit CPUs.
+ * rmb(), though. Note that rmb() actually uses a sync on 32-bit
+ * architectures.
  *
  * For wmb(), we use sync since wmb is used in drivers to order
  * stores to system memory with respect to writes to the device.
@@ -34,7 +34,7 @@
  * SMP since it is only used to order updates to system memory.
  */
 #define mb()   __asm__ __volatile__ ("sync" : : : "memory")
-#define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
+#define rmb()  __asm__ __volatile__ (__stringify(LWSYNC) : : : "memory")
 #define wmb()  __asm__ __volatile__ ("sync" : : : "memory")
 #define read_barrier_depends()  do { } while(0)
 
index c9483adbf59994edc016a90b4f8dfac29449e72f..f663634cccc9c89b8d87164d98387cc61e97773a 100644 (file)
@@ -22,6 +22,8 @@
 #define _ASM_POWERPC_TCE_H
 #ifdef __KERNEL__
 
+#include <asm/iommu.h>
+
 /*
  * Tces come in two formats, one for the virtual bus and a different
  * format for PCI
@@ -33,7 +35,6 @@
 
 #define TCE_SHIFT      12
 #define TCE_PAGE_SIZE  (1 << TCE_SHIFT)
-#define TCE_PAGE_FACTOR        (PAGE_SHIFT - TCE_SHIFT)
 
 #define TCE_ENTRY_SIZE         8               /* each TCE is 64 bits */
 
index 7596ab83e0d4dcb5136fda0483c83a1af90e846f..6cd3e9e2a76ac62334f28a379e610fc9a0599df4 100644 (file)
@@ -327,11 +327,17 @@ extern unsigned short *irq_mask_register;
  */
 void init_IRQ_pint(void);
 
+struct ipr_data {
+       unsigned int irq;
+       unsigned int addr;      /* Address of Interrupt Priority Register */
+       int shift;              /* Shifts of the 16-bit data */
+       int priority;           /* The priority */
+};
+
 /*
  * Function for "on chip support modules".
  */
-extern void make_ipr_irq(unsigned int irq, unsigned int addr,
-                        int pos,  int priority);
+extern void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs);
 extern void make_imask_irq(unsigned int irq);
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7300)
index f1a0cbc966be0c8667a5acf7afe54982c043a9bc..1c2abde122cd962ccf5713af59793eec463d4d07 100644 (file)
 #define __NR_sync_file_range   314
 #define __NR_tee               315
 #define __NR_vmsplice          316
+#define __NR_move_pages                317
+#define __NR_getcpu            318
+#define __NR_epoll_pwait       319
 
-#define NR_syscalls 317
+#define NR_syscalls 320
 
 #ifdef __KERNEL__
 
index dee40206b221f8d30d1e011faf79eedbea81402c..7392fc4a954e2d603805c319071bc1cbb89e2d19 100644 (file)
@@ -87,24 +87,22 @@ static inline int
 futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
 {
        __asm__ __volatile__(
-       "\n1:   lduwa   [%2] %%asi, %0\n"
-       "2:     casa    [%2] %%asi, %0, %1\n"
-       "3:\n"
+       "\n1:   casa    [%3] %%asi, %2, %0\n"
+       "2:\n"
        "       .section .fixup,#alloc,#execinstr\n"
        "       .align  4\n"
-       "4:     ba      3b\n"
-       "        mov    %3, %0\n"
+       "3:     ba      2b\n"
+       "        mov    %4, %0\n"
        "       .previous\n"
        "       .section __ex_table,\"a\"\n"
        "       .align  4\n"
-       "       .word   1b, 4b\n"
-       "       .word   2b, 4b\n"
+       "       .word   1b, 3b\n"
        "       .previous\n"
-       : "=&r" (oldval)
-       : "r" (newval), "r" (uaddr), "i" (-EFAULT)
+       : "=r" (newval)
+       : "0" (newval), "r" (oldval), "r" (uaddr), "i" (-EFAULT)
        : "memory");
 
-       return oldval;
+       return newval;
 }
 
 #endif /* !(_SPARC64_FUTEX_H) */
index 1010153faaf93731054d8789c6105ea9057ae70a..f0454516dd318d2b30bd86988f900dd72c66adab 100644 (file)
        
   __initcall_start = .;
   .initcall.init : {
-       *(.initcall1.init) 
-       *(.initcall2.init) 
-       *(.initcall3.init) 
-       *(.initcall4.init) 
-       *(.initcall5.init) 
-       *(.initcall6.init) 
-       *(.initcall7.init)
+       INITCALLS
   }
   __initcall_end = .;
 
index b03d5a340dc810723368d1cc4fbf73b703e9628d..abd2debebca2525a79395ac1d389388d9bc85e91 100644 (file)
@@ -702,7 +702,6 @@ extern int ata_std_prereset(struct ata_port *ap);
 extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
 extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
 extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
-extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
 extern void ata_port_disable(struct ata_port *);
 extern void ata_std_ports(struct ata_ioports *ioaddr);
 #ifdef CONFIG_PCI
index 70420bbae82b3b219847d0ed5f230728412a1de6..8b3ef418721980542adccfb4feb8cc63f82410af 100644 (file)
@@ -355,7 +355,7 @@ struct nand_buffers {
  * @priv:              [OPTIONAL] pointer to private chip date
  * @errstat:           [OPTIONAL] hardware specific function to perform additional error status checks
  *                     (determine if errors are correctable)
- * @write_page         [REPLACEABLE] High-level page write function
+ * @write_page:                [REPLACEABLE] High-level page write function
  */
 
 struct nand_chip {
index b3b9048421d8489568d27f41ff1303e09ab51f37..e820d00e13836af125710e67753ad5fee2b9bc36 100644 (file)
@@ -79,6 +79,15 @@ struct task_struct;
 
 extern void init_waitqueue_head(wait_queue_head_t *q);
 
+#ifdef CONFIG_LOCKDEP
+# define __WAIT_QUEUE_HEAD_INIT_ONSTACK(name) \
+       ({ init_waitqueue_head(&name); name; })
+# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) \
+       wait_queue_head_t name = __WAIT_QUEUE_HEAD_INIT_ONSTACK(name)
+#else
+# define DECLARE_WAIT_QUEUE_HEAD_ONSTACK(name) DECLARE_WAIT_QUEUE_HEAD(name)
+#endif
+
 static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
 {
        q->flags = 0;
index 5072a943fe3571eb0465aea4418348e55f46549d..f0166563c602f12aba2867b60965959bfb57f6a7 100644 (file)
@@ -1718,7 +1718,7 @@ static struct module *load_module(void __user *umod,
        set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
        if (strcmp(mod->name, "ndiswrapper") == 0)
-               add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
+               add_taint(TAINT_PROPRIETARY_MODULE);
        if (strcmp(mod->name, "driverloader") == 0)
                add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
 
index 2039585ec5e1785b859ea6b9c0b6ca827dac7e29..f45c5e70773c0b2fd6437b3a69ecfbefc1e40bf6 100644 (file)
@@ -455,10 +455,9 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
        int is_thread_group;
        struct nlattr *na;
 
-       if (!family_registered || !tidstats)
+       if (!family_registered)
                return;
 
-       rc = 0;
        /*
         * Size includes space for nested attributes
         */
@@ -466,8 +465,15 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
                nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
 
        is_thread_group = (tsk->signal->stats != NULL);
-       if (is_thread_group)
-               size = 2 * size;        /* PID + STATS + TGID + STATS */
+       if (is_thread_group) {
+               /* PID + STATS + TGID + STATS */
+               size = 2 * size;
+               /* fill the tsk->signal->stats structure */
+               fill_tgid_exit(tsk);
+       }
+
+       if (!tidstats)
+               return;
 
        rc = prepare_reply(NULL, TASKSTATS_CMD_NEW, &rep_skb, &reply, size);
        if (rc < 0)
@@ -487,11 +493,8 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
                goto send;
 
        /*
-        * tsk has/had a thread group so fill the tsk->signal->stats structure
         * Doesn't matter if tsk is the leader or the last group member leaving
         */
-
-       fill_tgid_exit(tsk);
        if (!group_dead)
                goto send;
 
index 65a5036a3d9519031526f499c5495ac23401a90e..96f77013d3f038ea03b688c448e2ef69a77aee06 100644 (file)
@@ -80,13 +80,17 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
  */
 void xacct_add_tsk(struct taskstats *stats, struct task_struct *p)
 {
+       struct mm_struct *mm;
+
        /* convert pages-jiffies to Mbyte-usec */
        stats->coremem = jiffies_to_usecs(p->acct_rss_mem1) * PAGE_SIZE / MB;
        stats->virtmem = jiffies_to_usecs(p->acct_vm_mem1) * PAGE_SIZE / MB;
-       if (p->mm) {
+       mm = get_task_mm(p);
+       if (mm) {
                /* adjust to KB unit */
-               stats->hiwater_rss   = p->mm->hiwater_rss * PAGE_SIZE / KB;
-               stats->hiwater_vm    = p->mm->hiwater_vm * PAGE_SIZE / KB;
+               stats->hiwater_rss   = mm->hiwater_rss * PAGE_SIZE / KB;
+               stats->hiwater_vm    = mm->hiwater_vm * PAGE_SIZE / KB;
+               mmput(mm);
        }
        stats->read_char        = p->rchar;
        stats->write_char       = p->wchar;
index 708e2e0371aff2ae8be46529c112be0078e58686..485e35c3b28bac873b468eda0239b03958df71e3 100644 (file)
@@ -1584,7 +1584,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
 
        if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) {
                rt = atrtr_find(&usat->sat_addr);
-               dev = rt->dev;
        } else {
                struct atalk_addr at_hint;
 
@@ -1592,7 +1591,6 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
                at_hint.s_net  = at->src_net;
 
                rt = atrtr_find(&at_hint);
-               dev = rt->dev;
        }
        if (!rt)
                return -ENETUNREACH;
index 3df55b2bd91d7a8357254c5ab05a4d740f06fbb4..9f85666f29f75dd322c6672f7e72b8433fbc52d2 100644 (file)
@@ -86,7 +86,7 @@ static inline int ebt_do_match (struct ebt_entry_match *m,
 static inline int ebt_dev_check(char *entry, const struct net_device *device)
 {
        int i = 0;
-       char *devname = device->name;
+       const char *devname = device->name;
 
        if (*entry == '\0')
                return 0;
index 3c23760c5827518769f14ea3eaaa8fefb1e73397..f735455dc5d178c2d61f001e007e03fe8a86b5e4 100644 (file)
@@ -1946,7 +1946,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
        do {
                struct sk_buff *nskb;
                skb_frag_t *frag;
-               int hsize, nsize;
+               int hsize;
                int k;
                int size;
 
@@ -1957,11 +1957,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                hsize = skb_headlen(skb) - offset;
                if (hsize < 0)
                        hsize = 0;
-               nsize = hsize + doffset;
-               if (nsize > len + doffset || !sg)
-                       nsize = len + doffset;
+               if (hsize > len || !sg)
+                       hsize = len;
 
-               nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
+               nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
                if (unlikely(!nskb))
                        goto err;
 
index 2fbb84bf4e26850d5d4c6094c633a810c677da3c..162032baeac0acb4fddece61def024fe370c684f 100644 (file)
@@ -352,14 +352,14 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len)
 
 #ifdef CONFIG_IP_DCCP_CCID2_DEBUG
        ccid2_pr_debug("pipe=%d\n", hctx->ccid2hctx_pipe);
-       ccid2_pr_debug("Sent: seq=%llu\n", seq);
+       ccid2_pr_debug("Sent: seq=%llu\n", (unsigned long long)seq);
        do {
                struct ccid2_seq *seqp = hctx->ccid2hctx_seqt;
 
                while (seqp != hctx->ccid2hctx_seqh) {
                        ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
-                                      seqp->ccid2s_seq, seqp->ccid2s_acked,
-                                      seqp->ccid2s_sent);
+                                      (unsigned long long)seqp->ccid2s_seq,
+                                      seqp->ccid2s_acked, seqp->ccid2s_sent);
                        seqp = seqp->ccid2s_next;
                }
        } while (0);
@@ -480,7 +480,8 @@ static inline void ccid2_new_ack(struct sock *sk,
                /* first measurement */
                if (hctx->ccid2hctx_srtt == -1) {
                        ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
-                                      r, jiffies, seqp->ccid2s_seq);
+                                      r, jiffies,
+                                      (unsigned long long)seqp->ccid2s_seq);
                        ccid2_change_srtt(hctx, r);
                        hctx->ccid2hctx_rttvar = r >> 1;
                } else {
@@ -636,8 +637,9 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                        u64 ackno_end_rl;
 
                        dccp_set_seqno(&ackno_end_rl, ackno - rl);
-                       ccid2_pr_debug("ackvec start:%llu end:%llu\n", ackno,
-                                      ackno_end_rl);
+                       ccid2_pr_debug("ackvec start:%llu end:%llu\n",
+                                      (unsigned long long)ackno,
+                                      (unsigned long long)ackno_end_rl);
                        /* if the seqno we are analyzing is larger than the
                         * current ackno, then move towards the tail of our
                         * seqnos.
@@ -672,7 +674,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
 
                                        seqp->ccid2s_acked = 1;
                                        ccid2_pr_debug("Got ack for %llu\n",
-                                                      seqp->ccid2s_seq);
+                                                      (unsigned long long)seqp->ccid2s_seq);
                                        ccid2_hc_tx_dec_pipe(sk);
                                }
                                if (seqp == hctx->ccid2hctx_seqt) {
@@ -718,7 +720,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                while (1) {
                        if (!seqp->ccid2s_acked) {
                                ccid2_pr_debug("Packet lost: %llu\n",
-                                              seqp->ccid2s_seq);
+                                              (unsigned long long)seqp->ccid2s_seq);
                                /* XXX need to traverse from tail -> head in
                                 * order to detect multiple congestion events in
                                 * one ack vector.
index e2077a3aa8c097156c34e4e12fd1f4a36320af08..6460233407c786f4138671765786d98db3bab6ae 100644 (file)
@@ -1307,7 +1307,8 @@ int cipso_v4_socket_setattr(const struct socket *sock,
 
        /* We can't use ip_options_get() directly because it makes a call to
         * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
-        * we can't block here. */
+        * we won't always have CAP_NET_RAW even though we _always_ want to
+        * set the IPOPT_CIPSO option. */
        opt_len = (buf_len + 3) & ~3;
        opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
        if (opt == NULL) {
@@ -1317,11 +1318,9 @@ int cipso_v4_socket_setattr(const struct socket *sock,
        memcpy(opt->__data, buf, buf_len);
        opt->optlen = opt_len;
        opt->is_data = 1;
+       opt->cipso = sizeof(struct iphdr);
        kfree(buf);
        buf = NULL;
-       ret_val = ip_options_compile(opt, NULL);
-       if (ret_val != 0)
-               goto socket_setattr_failure;
 
        sk_inet = inet_sk(sk);
        if (sk_inet->is_icsk) {
index 8dabbfc312674bd574df7f69f2a5646146723c18..9f02917d6f45319de4680eade1dda3cf3440b050 100644 (file)
@@ -443,7 +443,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                opt->router_alert = optptr - iph;
                        break;
                      case IPOPT_CIPSO:
-                       if (opt->cipso) {
+                       if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) {
                                pp_ptr = optptr;
                                goto error;
                        }
index 0849f1cced13364b014ef787157e1d7c76995f4e..413c2d0a1f3dee117db48289865279113f70e348 100644 (file)
@@ -466,7 +466,13 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i
                return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset)
+               return -EINVAL;
+
        t = arpt_get_target(e);
+       if (e->target_offset + t->u.target_size > e->next_offset)
+               return -EINVAL;
+
        target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name,
                                                        t->u.user.revision),
                                         "arpt_%s", t->u.user.name);
@@ -621,20 +627,18 @@ static int translate_table(const char *name,
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
-               duprintf("Looping hook\n");
-               return -ELOOP;
-       }
-
        /* Finally, each sanity check must pass */
        i = 0;
        ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
                                 check_entry, name, size, &i);
 
-       if (ret != 0) {
-               ARPT_ENTRY_ITERATE(entry0, newinfo->size,
-                                  cleanup_entry, &i);
-               return ret;
+       if (ret != 0)
+               goto cleanup;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
+               duprintf("Looping hook\n");
+               goto cleanup;
        }
 
        /* And one copy for every other CPU */
@@ -643,6 +647,9 @@ static int translate_table(const char *name,
                        memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
+       return 0;
+cleanup:
+       ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
        return ret;
 }
 
index 4b90927619b80d2e0461bdd395dc7a82a68e340c..8a455439b128258de3e42926640834975579d5af 100644 (file)
@@ -547,12 +547,18 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
                return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
+               return -EINVAL;
+
        j = 0;
        ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j);
        if (ret != 0)
                goto cleanup_matches;
 
        t = ipt_get_target(e);
+       ret = -EINVAL;
+       if (e->target_offset + t->u.target_size > e->next_offset)
+                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET,
                                                     t->u.user.name,
                                                     t->u.user.revision),
@@ -712,19 +718,17 @@ translate_table(const char *name,
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks, entry0))
-               return -ELOOP;
-
        /* Finally, each sanity check must pass */
        i = 0;
        ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry, name, size, &i);
 
-       if (ret != 0) {
-               IPT_ENTRY_ITERATE(entry0, newinfo->size,
-                                 cleanup_entry, &i);
-               return ret;
-       }
+       if (ret != 0)
+               goto cleanup;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry0))
+               goto cleanup;
 
        /* And one copy for every other CPU */
        for_each_possible_cpu(i) {
@@ -732,6 +736,9 @@ translate_table(const char *name,
                        memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
+       return 0;
+cleanup:
+       IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
        return ret;
 }
 
@@ -1463,6 +1470,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
                return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct compat_xt_entry_target) >
+                                                               e->next_offset)
+               return -EINVAL;
+
        off = 0;
        entry_offset = (void *)e - (void *)base;
        j = 0;
@@ -1472,6 +1483,9 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
                goto cleanup_matches;
 
        t = ipt_get_target(e);
+       ret = -EINVAL;
+       if (e->target_offset + t->u.target_size > e->next_offset)
+                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET,
                                                     t->u.user.name,
                                                     t->u.user.revision),
@@ -1513,7 +1527,7 @@ cleanup_matches:
 
 static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
        void **dstptr, compat_uint_t *size, const char *name,
-       const struct ipt_ip *ip, unsigned int hookmask, int *i)
+       const struct ipt_ip *ip, unsigned int hookmask)
 {
        struct ipt_entry_match *dm;
        struct ipt_match *match;
@@ -1526,22 +1540,13 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
        ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
                             name, hookmask, ip->proto,
                             ip->invflags & IPT_INV_PROTO);
-       if (ret)
-               goto err;
-
-       if (m->u.kernel.match->checkentry
+       if (!ret && m->u.kernel.match->checkentry
            && !m->u.kernel.match->checkentry(name, ip, match, dm->data,
                                              hookmask)) {
                duprintf("ip_tables: check failed for `%s'.\n",
                         m->u.kernel.match->name);
                ret = -EINVAL;
-               goto err;
        }
-       (*i)++;
-       return 0;
-
-err:
-       module_put(m->u.kernel.match->me);
        return ret;
 }
 
@@ -1553,19 +1558,18 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
        struct ipt_target *target;
        struct ipt_entry *de;
        unsigned int origsize;
-       int ret, h, j;
+       int ret, h;
 
        ret = 0;
        origsize = *size;
        de = (struct ipt_entry *)*dstptr;
        memcpy(de, e, sizeof(struct ipt_entry));
 
-       j = 0;
        *dstptr += sizeof(struct compat_ipt_entry);
        ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
-                       name, &de->ip, de->comefrom, &j);
+                       name, &de->ip, de->comefrom);
        if (ret)
-               goto cleanup_matches;
+               goto err;
        de->target_offset = e->target_offset - (origsize - *size);
        t = ipt_get_target(e);
        target = t->u.kernel.target;
@@ -1599,12 +1603,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
                goto err;
        }
        ret = 0;
-       return ret;
-
 err:
-       module_put(t->u.kernel.target->me);
-cleanup_matches:
-       IPT_MATCH_ITERATE(e, cleanup_match, &j);
        return ret;
 }
 
@@ -1618,7 +1617,7 @@ translate_compat_table(const char *name,
                unsigned int *hook_entries,
                unsigned int *underflows)
 {
-       unsigned int i;
+       unsigned int i, j;
        struct xt_table_info *newinfo, *info;
        void *pos, *entry0, *entry1;
        unsigned int size;
@@ -1636,21 +1635,21 @@ translate_compat_table(const char *name,
        }
 
        duprintf("translate_compat_table: size %u\n", info->size);
-       i = 0;
+       j = 0;
        xt_compat_lock(AF_INET);
        /* Walk through entries, checking offsets. */
        ret = IPT_ENTRY_ITERATE(entry0, total_size,
                                check_compat_entry_size_and_hooks,
                                info, &size, entry0,
                                entry0 + total_size,
-                               hook_entries, underflows, &i, name);
+                               hook_entries, underflows, &j, name);
        if (ret != 0)
                goto out_unlock;
 
        ret = -EINVAL;
-       if (i != number) {
+       if (j != number) {
                duprintf("translate_compat_table: %u not %u entries\n",
-                        i, number);
+                        j, number);
                goto out_unlock;
        }
 
@@ -1709,8 +1708,10 @@ translate_compat_table(const char *name,
 free_newinfo:
        xt_free_table_info(newinfo);
 out:
+       IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j);
        return ret;
 out_unlock:
+       compat_flush_offsets();
        xt_compat_unlock(AF_INET);
        goto out;
 }
index b430cf2a4f6609db27f6ea137e3f18b0281bd442..5c31dead2bdc6dca82a19e1aa7eb17c85fe5344d 100644 (file)
@@ -329,7 +329,7 @@ error:
        return err; 
 }
 
-static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+static int raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
 {
        struct iovec *iov;
        u8 __user *type = NULL;
@@ -338,7 +338,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
        unsigned int i;
 
        if (!msg->msg_iov)
-               return;
+               return 0;
 
        for (i = 0; i < msg->msg_iovlen; i++) {
                iov = &msg->msg_iov[i];
@@ -360,8 +360,9 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
                                code = iov->iov_base;
 
                        if (type && code) {
-                               get_user(fl->fl_icmp_type, type);
-                               get_user(fl->fl_icmp_code, code);
+                               if (get_user(fl->fl_icmp_type, type) ||
+                                   get_user(fl->fl_icmp_code, code))
+                                       return -EFAULT;
                                probed = 1;
                        }
                        break;
@@ -372,6 +373,7 @@ static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
                if (probed)
                        break;
        }
+       return 0;
 }
 
 static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
@@ -480,8 +482,11 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                    .proto = inet->hdrincl ? IPPROTO_RAW :
                                                             sk->sk_protocol,
                                  };
-               if (!inet->hdrincl)
-                       raw_probe_proto_opt(&fl, msg);
+               if (!inet->hdrincl) {
+                       err = raw_probe_proto_opt(&fl, msg);
+                       if (err)
+                               goto done;
+               }
 
                security_sk_classify_flow(sk, &fl);
                err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
index e82a5be894b51ca523697910daafb41c9a823e9d..15061b3144118d25c491e7eed58ca86394e65b9c 100644 (file)
@@ -129,13 +129,6 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
        return ret;
 }
 
-static int __init tcp_congestion_default(void)
-{
-       return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
-}
-
-late_initcall(tcp_congestion_default);
-
 ctl_table ipv4_table[] = {
         {
                .ctl_name       = NET_IPV4_TCP_TIMESTAMPS,
index af0aca1e6be612ee100cc99bca70102ed644a3eb..1e2982f4acd414733e4d31f51a1b2b1fab56a2e6 100644 (file)
@@ -131,6 +131,14 @@ int tcp_set_default_congestion_control(const char *name)
        return ret;
 }
 
+/* Set default value from kernel configuration at bootup */
+static int __init tcp_congestion_default(void)
+{
+       return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
+}
+late_initcall(tcp_congestion_default);
+
+
 /* Get current default congestion control */
 void tcp_get_default_congestion_control(char *name)
 {
index 1d672b0547f25c9bed0fcb72a2125bc0b475c857..6d4533b58dcad4100dd8ca853ce07d69912f5f4c 100644 (file)
@@ -330,8 +330,10 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int *
        fl->share = freq->flr_share;
        addr_type = ipv6_addr_type(&freq->flr_dst);
        if ((addr_type&IPV6_ADDR_MAPPED)
-           || addr_type == IPV6_ADDR_ANY)
+           || addr_type == IPV6_ADDR_ANY) {
+               err = -EINVAL;
                goto done;
+       }
        ipv6_addr_copy(&fl->dst, &freq->flr_dst);
        atomic_set(&fl->users, 1);
        switch (fl->share) {
@@ -587,6 +589,8 @@ static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flo
        while (!fl) {
                if (++state->bucket <= FL_HASH_MASK)
                        fl = fl_ht[state->bucket];
+               else
+                       break;
        }
        return fl;
 }
@@ -623,9 +627,13 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v)
        read_unlock_bh(&ip6_fl_lock);
 }
 
-static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl)
+static int ip6fl_seq_show(struct seq_file *seq, void *v)
 {
-       while(fl) {
+       if (v == SEQ_START_TOKEN)
+               seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
+                          "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
+       else {
+               struct ip6_flowlabel *fl = v;
                seq_printf(seq,
                           "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n",
                           (unsigned)ntohl(fl->label),
@@ -636,17 +644,7 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl)
                           (long)(fl->expires - jiffies)/HZ,
                           NIP6(fl->dst),
                           fl->opt ? fl->opt->opt_nflen : 0);
-               fl = fl->next;
        }
-}
-
-static int ip6fl_seq_show(struct seq_file *seq, void *v)
-{
-       if (v == SEQ_START_TOKEN)
-               seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n",
-                          "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt");
-       else
-               ip6fl_fl_seq_show(seq, v);
        return 0;
 }
 
index 4bc4e5b3379415130234b3668e19a94ccb448658..d7c45a9c15feb6994fa55614a69f663dde9c724c 100644 (file)
@@ -40,7 +40,7 @@ config IP6_NF_QUEUE
          To compile it as a module, choose M here.  If unsure, say N.
 
 config IP6_NF_IPTABLES
-       tristate "IP6 tables support (required for filtering/masq/NAT)"
+       tristate "IP6 tables support (required for filtering)"
        depends on NETFILTER_XTABLES
        help
          ip6tables is a general, extensible packet identification framework.
index 53bf977cca63424072107de6e9608e6fa021fcab..167c2ea88f6be997807cd6fe81e2a0d1c47f3934 100644 (file)
@@ -586,12 +586,19 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
                return -EINVAL;
        }
 
+       if (e->target_offset + sizeof(struct ip6t_entry_target) >
+                                                               e->next_offset)
+               return -EINVAL;
+
        j = 0;
        ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j);
        if (ret != 0)
                goto cleanup_matches;
 
        t = ip6t_get_target(e);
+       ret = -EINVAL;
+       if (e->target_offset + t->u.target_size > e->next_offset)
+                       goto cleanup_matches;
        target = try_then_request_module(xt_find_target(AF_INET6,
                                                        t->u.user.name,
                                                        t->u.user.revision),
@@ -751,19 +758,17 @@ translate_table(const char *name,
                }
        }
 
-       if (!mark_source_chains(newinfo, valid_hooks, entry0))
-               return -ELOOP;
-
        /* Finally, each sanity check must pass */
        i = 0;
        ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
                                check_entry, name, size, &i);
 
-       if (ret != 0) {
-               IP6T_ENTRY_ITERATE(entry0, newinfo->size,
-                                 cleanup_entry, &i);
-               return ret;
-       }
+       if (ret != 0)
+               goto cleanup;
+
+       ret = -ELOOP;
+       if (!mark_source_chains(newinfo, valid_hooks, entry0))
+               goto cleanup;
 
        /* And one copy for every other CPU */
        for_each_possible_cpu(i) {
@@ -771,6 +776,9 @@ translate_table(const char *name,
                        memcpy(newinfo->entries[i], entry0, newinfo->size);
        }
 
+       return 0;
+cleanup:
+       IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
        return ret;
 }
 
index d09329ca32670bdb76639826bfdfa53be41f1ae0..d6dedc4aec7794eae523a7b75956e422dd5432e2 100644 (file)
@@ -604,7 +604,7 @@ error:
        return err; 
 }
 
-static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
 {
        struct iovec *iov;
        u8 __user *type = NULL;
@@ -616,7 +616,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
        int i;
 
        if (!msg->msg_iov)
-               return;
+               return 0;
 
        for (i = 0; i < msg->msg_iovlen; i++) {
                iov = &msg->msg_iov[i];
@@ -638,8 +638,9 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
                                code = iov->iov_base;
 
                        if (type && code) {
-                               get_user(fl->fl_icmp_type, type);
-                               get_user(fl->fl_icmp_code, code);
+                               if (get_user(fl->fl_icmp_type, type) ||
+                                   get_user(fl->fl_icmp_code, code))
+                                       return -EFAULT;
                                probed = 1;
                        }
                        break;
@@ -650,7 +651,8 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
                        /* check if type field is readable or not. */
                        if (iov->iov_len > 2 - len) {
                                u8 __user *p = iov->iov_base;
-                               get_user(fl->fl_mh_type, &p[2 - len]);
+                               if (get_user(fl->fl_mh_type, &p[2 - len]))
+                                       return -EFAULT;
                                probed = 1;
                        } else
                                len += iov->iov_len;
@@ -664,6 +666,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
                if (probed)
                        break;
        }
+       return 0;
 }
 
 static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
@@ -787,7 +790,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
        opt = ipv6_fixup_options(&opt_space, opt);
 
        fl.proto = proto;
-       rawv6_probe_proto_opt(&fl, msg);
+       err = rawv6_probe_proto_opt(&fl, msg);
+       if (err)
+               goto out;
  
        ipv6_addr_copy(&fl.fl6_dst, daddr);
        if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
index 7af227bb1551477730b13097e3490241bebc154b..7931e4f898d47a2db4fb971c859f67252cd00a28 100644 (file)
@@ -135,7 +135,7 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
        x6spi = __xfrm6_tunnel_spi_lookup(saddr);
        spi = x6spi ? x6spi->spi : 0;
        read_unlock_bh(&xfrm6_tunnel_spi_lock);
-       return spi;
+       return htonl(spi);
 }
 
 EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup);
@@ -210,7 +210,7 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
                spi = __xfrm6_tunnel_alloc_spi(saddr);
        write_unlock_bh(&xfrm6_tunnel_spi_lock);
 
-       return spi;
+       return htonl(spi);
 }
 
 EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
index 093b3ddc513c96d8234910370f3c28a8feb2b593..836541e509fe14e67e04c10012b94ae594c0446b 100644 (file)
@@ -1520,9 +1520,10 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
                if (iter(ct, data))
                        goto found;
        }
+       write_unlock_bh(&nf_conntrack_lock);
        return NULL;
 found:
-       atomic_inc(&nf_ct_tuplehash_to_ctrack(h)->ct_general.use);
+       atomic_inc(&ct->ct_general.use);
        write_unlock_bh(&nf_conntrack_lock);
        return ct;
 }
index d56e0d21f919dc581df426af4511ee8e52f07155..d527c8977b1f7320a5d0faf3c11a9ca35556e2ed 100644 (file)
@@ -1075,8 +1075,9 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
                        return -EINVAL;
                len = sizeof(int);
                val = nlk->flags & NETLINK_RECV_PKTINFO ? 1 : 0;
-               put_user(len, optlen);
-               put_user(val, optval);
+               if (put_user(len, optlen) ||
+                   put_user(val, optval))
+                       return -EFAULT;
                err = 0;
                break;
        default:
index ef8874babf6ae8c7c23ae26fe1baaea03334dd2f..0441876aa1e7dc2ac4d84ec9a3022559a29e1c10 100644 (file)
@@ -4,7 +4,7 @@
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
  *             as published by the Free Software Foundation; either version
- *             2 of the License, or (at your option) any later version.
+ *             2 of the License.
  *
  *             Many of the algorithms and ideas for this came from
  *             NIST Net which is not copyrighted. 
index 27329ce9c311dc8aaf74c020911fb3d026aeab74..ed0445fe85e7dac8dcc670986cf9745bde58c1de 100644 (file)
@@ -346,11 +346,18 @@ void sctp_association_free(struct sctp_association *asoc)
        struct list_head *pos, *temp;
        int i;
 
-       list_del(&asoc->asocs);
+       /* Only real associations count against the endpoint, so
+        * don't bother for if this is a temporary association.
+        */
+       if (!asoc->temp) {
+               list_del(&asoc->asocs);
 
-       /* Decrement the backlog value for a TCP-style listening socket. */
-       if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
-               sk->sk_ack_backlog--;
+               /* Decrement the backlog value for a TCP-style listening
+                * socket.
+                */
+               if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
+                       sk->sk_ack_backlog--;
+       }
 
        /* Mark as dead, so other users can know this structure is
         * going away.
index 35c49ff2d0621b445dbced33f74894663a189b4d..9b6b394b66f649cf98f5f1e8189fa9131f2b956b 100644 (file)
@@ -144,6 +144,13 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep,
 {
        struct sock *sk = ep->base.sk;
 
+       /* If this is a temporary association, don't bother
+        * since we'll be removing it shortly and don't
+        * want anyone to find it anyway.
+        */
+       if (asoc->temp)
+               return;
+
        /* Now just add it to our list of asocs */
        list_add_tail(&asoc->asocs, &ep->asocs);
 
index 64f630102532c9e3e95379458bd934902bcf2870..6d82f400d13c47a36279f861cc2efed80d105254 100644 (file)
@@ -135,6 +135,9 @@ int sctp_rcv(struct sk_buff *skb)
 
        SCTP_INC_STATS_BH(SCTP_MIB_INSCTPPACKS);
 
+       if (skb_linearize(skb))
+               goto discard_it;
+
        sh = (struct sctphdr *) skb->h.raw;
 
        /* Pull up the IP and SCTP headers. */
@@ -768,6 +771,9 @@ static void __sctp_hash_established(struct sctp_association *asoc)
 /* Add an association to the hash. Local BH-safe. */
 void sctp_hash_established(struct sctp_association *asoc)
 {
+       if (asoc->temp)
+               return;
+
        sctp_local_bh_disable();
        __sctp_hash_established(asoc);
        sctp_local_bh_enable();
@@ -801,6 +807,9 @@ static void __sctp_unhash_established(struct sctp_association *asoc)
 /* Remove association from the hash table.  Local BH-safe. */
 void sctp_unhash_established(struct sctp_association *asoc)
 {
+       if (asoc->temp)
+               return;
+
        sctp_local_bh_disable();
        __sctp_unhash_established(asoc);
        sctp_local_bh_enable();
index fac7674438a4c00b3e28e8a33b0565e6a0d74637..5b4f82fd98f834456ae308cd4ee3426ba29409e8 100644 (file)
@@ -591,7 +591,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
        newinet->dport = htons(asoc->peer.port);
        newinet->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
        newinet->pmtudisc = inet->pmtudisc;
-       newinet->id = 0;
+       newinet->id = asoc->next_tsn ^ jiffies;
 
        newinet->uc_ttl = -1;
        newinet->mc_loop = 1;
index 9f34dec6ff8ec0cd70acfb72e594f016c60a36a8..935bc9187fd81335cd2b3bbf5c5e78fec5b05d73 100644 (file)
@@ -3372,6 +3372,7 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
 {
        struct sock *sk = asoc->base.sk;
        struct socket *sock;
+       struct inet_sock *inetsk;
        int err = 0;
 
        /* An association cannot be branched off from an already peeled-off
@@ -3389,6 +3390,14 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
         * asoc to the newsk.
         */
        sctp_sock_migrate(sk, sock->sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH);
+
+       /* Make peeled-off sockets more like 1-1 accepted sockets.
+        * Set the daddr and initialize id to something more random
+        */
+       inetsk = inet_sk(sock->sk);
+       inetsk->daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr;
+       inetsk->id = asoc->next_tsn ^ jiffies;
+
        *sockp = sock;
 
        return err;
index 8f2320aded5c42f645b406cf51539d10228ef055..0004c1f0ef047377d1db5a645d5e9d0e745ed069 100644 (file)
@@ -147,10 +147,8 @@ auth_domain_lookup(char *name, struct auth_domain *new)
                        return hp;
                }
        }
-       if (new) {
+       if (new)
                hlist_add_head(&new->hash, head);
-               kref_get(&new->ref);
-       }
        spin_unlock(&auth_domain_lock);
        return new;
 }
index 96521f16342b63e80f18f77888fa7b5b06dbd333..64ca1f61dd9497fde7cb31a235468ea1c2606fbe 100644 (file)
@@ -299,9 +299,15 @@ void svc_reserve(struct svc_rqst *rqstp, int space)
 static inline void
 svc_sock_put(struct svc_sock *svsk)
 {
-       if (atomic_dec_and_test(&svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
+       if (atomic_dec_and_test(&svsk->sk_inuse) &&
+                       test_bit(SK_DEAD, &svsk->sk_flags)) {
                dprintk("svc: releasing dead socket\n");
-               sock_release(svsk->sk_sock);
+               if (svsk->sk_sock->file)
+                       sockfd_put(svsk->sk_sock);
+               else
+                       sock_release(svsk->sk_sock);
+               if (svsk->sk_info_authunix != NULL)
+                       svcauth_unix_info_release(svsk->sk_info_authunix);
                kfree(svsk);
        }
 }
@@ -1604,20 +1610,13 @@ svc_delete_socket(struct svc_sock *svsk)
                if (test_bit(SK_TEMP, &svsk->sk_flags))
                        serv->sv_tmpcnt--;
 
-       if (!atomic_read(&svsk->sk_inuse)) {
-               spin_unlock_bh(&serv->sv_lock);
-               if (svsk->sk_sock->file)
-                       sockfd_put(svsk->sk_sock);
-               else
-                       sock_release(svsk->sk_sock);
-               if (svsk->sk_info_authunix != NULL)
-                       svcauth_unix_info_release(svsk->sk_info_authunix);
-               kfree(svsk);
-       } else {
-               spin_unlock_bh(&serv->sv_lock);
-               dprintk(KERN_NOTICE "svc: server socket destroy delayed\n");
-               /* svsk->sk_server = NULL; */
-       }
+       /* This atomic_inc should be needed - svc_delete_socket
+        * should have the semantic of dropping a reference.
+        * But it doesn't yet....
+        */
+       atomic_inc(&svsk->sk_inuse);
+       spin_unlock_bh(&serv->sv_lock);
+       svc_sock_put(svsk);
 }
 
 /*
index c1a1a76759b59259e87a7b12bc190e6c9fcc07cc..b7f3199523caaf846d0aa1479c69888426374040 100644 (file)
@@ -1136,11 +1136,12 @@ int tipc_publish(u32 ref, unsigned int scope, struct tipc_name_seq const *seq)
        int res = -EINVAL;
 
        p_ptr = tipc_port_lock(ref);
+       if (!p_ptr)
+               return -EINVAL;
+
        dbg("tipc_publ %u, p_ptr = %x, conn = %x, scope = %x, "
            "lower = %u, upper = %u\n",
            ref, p_ptr, p_ptr->publ.connected, scope, seq->lower, seq->upper);
-       if (!p_ptr)
-               return -EINVAL;
        if (p_ptr->publ.connected)
                goto exit;
        if (seq->lower > seq->upper)
index 2b2e59d8ffbc8ca197c8b84b98248c92511ce365..b43e7647e125692955b8a9ce5081ee3bb7166bb8 100644 (file)
@@ -323,7 +323,7 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
        x->props.replay_window = p->replay_window;
        x->props.reqid = p->reqid;
        x->props.family = p->family;
-       x->props.saddr = p->saddr;
+       memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr));
        x->props.flags = p->flags;
 }
 
@@ -545,7 +545,7 @@ static void copy_to_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
        memcpy(&p->lft, &x->lft, sizeof(p->lft));
        memcpy(&p->curlft, &x->curlft, sizeof(p->curlft));
        memcpy(&p->stats, &x->stats, sizeof(p->stats));
-       p->saddr = x->props.saddr;
+       memcpy(&p->saddr, &x->props.saddr, sizeof(p->saddr));
        p->mode = x->props.mode;
        p->replay_window = x->props.replay_window;
        p->reqid = x->props.reqid;
index e9969a2fc8462116a5b8cb256e1e8cbc97a7fd3c..8ab5679a37a30324b9b61a61c159dd4978512447 100644 (file)
@@ -3313,7 +3313,13 @@ static int selinux_socket_getpeername(struct socket *sock)
 
 static int selinux_socket_setsockopt(struct socket *sock,int level,int optname)
 {
-       return socket_has_perm(current, sock, SOCKET__SETOPT);
+       int err;
+
+       err = socket_has_perm(current, sock, SOCKET__SETOPT);
+       if (err)
+               return err;
+
+       return selinux_netlbl_socket_setsockopt(sock, level, optname);
 }
 
 static int selinux_socket_getsockopt(struct socket *sock, int level,
index ecab4bddaaf4a4225d00e6990b53b8bdebe041b7..9de10cc2cef2321d9c2ff9cade4c5e04dc11dd9e 100644 (file)
@@ -53,6 +53,9 @@ void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec,
 void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec,
                                      struct sk_security_struct *newssec);
 int selinux_netlbl_inode_permission(struct inode *inode, int mask);
+int selinux_netlbl_socket_setsockopt(struct socket *sock,
+                                    int level,
+                                    int optname);
 #else
 static inline void selinux_netlbl_cache_invalidate(void)
 {
@@ -114,6 +117,13 @@ static inline int selinux_netlbl_inode_permission(struct inode *inode,
 {
        return 0;
 }
+
+static inline int selinux_netlbl_socket_setsockopt(struct socket *sock,
+                                                  int level,
+                                                  int optname)
+{
+       return 0;
+}
 #endif /* CONFIG_NETLABEL */
 
 #endif
index b1f6fb36c6997cc40ea8cf350adf12a9218bf8bc..bfe122764c98c2638183a5d37390e63d5f62a73b 100644 (file)
@@ -2682,4 +2682,41 @@ u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
 
        return peer_sid;
 }
+
+/**
+ * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
+ * @sock: the socket
+ * @level: the socket level or protocol
+ * @optname: the socket option name
+ *
+ * Description:
+ * Check the setsockopt() call and if the user is trying to replace the IP
+ * options on a socket and a NetLabel is in place for the socket deny the
+ * access; otherwise allow the access.  Returns zero when the access is
+ * allowed, -EACCES when denied, and other negative values on error.
+ *
+ */
+int selinux_netlbl_socket_setsockopt(struct socket *sock,
+                                    int level,
+                                    int optname)
+{
+       int rc = 0;
+       struct inode *inode = SOCK_INODE(sock);
+       struct sk_security_struct *sksec = sock->sk->sk_security;
+       struct inode_security_struct *isec = inode->i_security;
+       struct netlbl_lsm_secattr secattr;
+
+       mutex_lock(&isec->lock);
+       if (level == IPPROTO_IP && optname == IP_OPTIONS &&
+           sksec->nlbl_state == NLBL_LABELED) {
+               netlbl_secattr_init(&secattr);
+               rc = netlbl_socket_getattr(sock, &secattr);
+               if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld))
+                       rc = -EACCES;
+               netlbl_secattr_destroy(&secattr);
+       }
+       mutex_unlock(&isec->lock);
+
+       return rc;
+}
 #endif /* CONFIG_NETLABEL */