aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/filesystems.tmpl101
-rw-r--r--Documentation/DocBook/kernel-api.tmpl60
-rw-r--r--Documentation/mips/time.README39
-rw-r--r--Makefile2
-rw-r--r--arch/alpha/kernel/vmlinux.lds.S8
-rw-r--r--arch/arm/Makefile6
-rw-r--r--arch/arm/configs/realview-smp_defconfig994
-rw-r--r--arch/arm/kernel/smp.c20
-rw-r--r--arch/arm/kernel/time.c3
-rw-r--r--arch/arm/kernel/vmlinux.lds.S8
-rw-r--r--arch/arm/mach-iop32x/n2100.c2
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1110.c2
-rw-r--r--arch/arm/vfp/vfpdouble.c2
-rw-r--r--arch/arm/vfp/vfpmodule.c1
-rw-r--r--arch/avr32/kernel/vmlinux.lds.c8
-rw-r--r--arch/cris/arch-v32/drivers/cryptocop.c1
-rw-r--r--arch/frv/kernel/vmlinux.lds.S8
-rw-r--r--arch/h8300/kernel/vmlinux.lds.S8
-rw-r--r--arch/i386/kernel/apm.c2
-rw-r--r--arch/i386/kernel/setup.c2
-rw-r--r--arch/i386/kernel/vmlinux.lds.S8
-rw-r--r--arch/i386/mach-visws/visws_apic.c7
-rw-r--r--arch/i386/pci/fixup.c55
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S8
-rw-r--r--arch/ia64/pci/Makefile2
-rw-r--r--arch/ia64/pci/fixup.c69
-rw-r--r--arch/m32r/kernel/vmlinux.lds.S8
-rw-r--r--arch/m68k/kernel/vmlinux-std.lds8
-rw-r--r--arch/m68k/kernel/vmlinux-sun3.lds8
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S8
-rw-r--r--arch/mips/Kconfig3
-rw-r--r--arch/mips/au1000/common/prom.c2
-rw-r--r--arch/mips/au1000/common/setup.c2
-rw-r--r--arch/mips/au1000/common/time.c106
-rw-r--r--arch/mips/dec/time.c9
-rw-r--r--arch/mips/emma2rh/common/irq_emma2rh.c2
-rw-r--r--arch/mips/emma2rh/markeins/irq_markeins.c4
-rw-r--r--arch/mips/emma2rh/markeins/platform.c88
-rw-r--r--arch/mips/jmr3927/rbhma3100/irq.c3
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c40
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/smp-mt.c154
-rw-r--r--arch/mips/kernel/time.c319
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/kernel/vmlinux.lds.S8
-rw-r--r--arch/mips/mips-boards/generic/time.c7
-rw-r--r--arch/mips/mm/c-sb1.c18
-rw-r--r--arch/mips/momentum/ocelot_g/ocelot_pld.h6
-rw-r--r--arch/mips/momentum/ocelot_g/setup.c5
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c12
-rw-r--r--arch/mips/philips/pnx8550/common/time.c4
-rw-r--r--arch/mips/pmc-sierra/yosemite/i2c-yosemite.c2
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c6
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c16
-rw-r--r--arch/mips/sibyte/bcm1480/time.c33
-rw-r--r--arch/mips/sibyte/sb1250/time.c28
-rw-r--r--arch/mips/tx4927/common/smsc_fdc37m81x.c172
-rw-r--r--arch/mips/tx4927/common/tx4927_setup.c2
-rw-r--r--arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c8
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S8
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S8
-rw-r--r--arch/ppc/kernel/vmlinux.lds.S8
-rw-r--r--arch/s390/appldata/appldata_base.c1
-rw-r--r--arch/s390/kernel/compat_linux.c4
-rw-r--r--arch/s390/kernel/compat_signal.c12
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/signal.c12
-rw-r--r--arch/s390/kernel/traps.c20
-rw-r--r--arch/s390/kernel/vmlinux.lds.S8
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/setup.c12
-rw-r--r--arch/sh/boards/renesas/sh7710voipgw/setup.c105
-rw-r--r--arch/sh/boards/se/7300/irq.c20
-rw-r--r--arch/sh/boards/se/73180/irq.c47
-rw-r--r--arch/sh/boards/se/7343/irq.c90
-rw-r--r--arch/sh/boards/se/770x/irq.c80
-rw-r--r--arch/sh/boards/se/7751/irq.c85
-rw-r--r--arch/sh/boards/sh03/setup.c13
-rw-r--r--arch/sh/boards/snapgear/setup.c12
-rw-r--r--arch/sh/boards/titan/setup.c12
-rw-r--r--arch/sh/configs/r7780rp_defconfig174
-rw-r--r--arch/sh/configs/titan_defconfig101
-rw-r--r--arch/sh/drivers/dma/dma-sh.c42
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c106
-rw-r--r--arch/sh/kernel/cpu/irq/pint.c8
-rw-r--r--arch/sh/kernel/syscalls.S3
-rw-r--r--arch/sh/kernel/vmlinux.lds.S8
-rw-r--r--arch/sh64/kernel/vmlinux.lds.S8
-rw-r--r--arch/sparc/kernel/ebus.c8
-rw-r--r--arch/sparc/kernel/of_device.c2
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S8
-rw-r--r--arch/sparc64/kernel/ebus.c8
-rw-r--r--arch/sparc64/kernel/isa.c8
-rw-r--r--arch/sparc64/kernel/of_device.c2
-rw-r--r--arch/sparc64/kernel/prom.c21
-rw-r--r--arch/sparc64/kernel/traps.c8
-rw-r--r--arch/sparc64/kernel/vmlinux.lds.S8
-rw-r--r--arch/um/Makefile21
-rw-r--r--arch/um/Makefile-i3864
-rw-r--r--arch/um/Makefile-x86_644
-rw-r--r--arch/um/drivers/ubd_kern.c319
-rw-r--r--arch/um/include/mconsole_kern.h1
-rw-r--r--arch/um/kernel/dyn.lds.S1
-rw-r--r--arch/um/kernel/tt/tracer.c1
-rw-r--r--arch/um/kernel/uml.lds.S1
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c3
-rw-r--r--arch/um/os-Linux/tls.c1
-rw-r--r--arch/um/sys-i386/unmap.c11
-rw-r--r--arch/um/sys-x86_64/unmap.c11
-rw-r--r--arch/v850/kernel/vmlinux.lds.S8
-rw-r--r--arch/x86_64/ia32/ia32_signal.c5
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S8
-rw-r--r--arch/x86_64/pci/mmconfig.c5
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S8
-rw-r--r--block/cfq-iosched.c16
-rw-r--r--block/ll_rw_blk.c24
-rw-r--r--drivers/base/Kconfig4
-rw-r--r--drivers/base/dd.c30
-rw-r--r--drivers/block/cciss.c8
-rw-r--r--drivers/bluetooth/bluecard_cs.c2
-rw-r--r--drivers/char/watchdog/sc1200wdt.c9
-rw-r--r--drivers/i2c/busses/i2c-pxa.c8
-rw-r--r--drivers/ide/pci/generic.c8
-rw-r--r--drivers/ieee1394/eth1394.c20
-rw-r--r--drivers/ieee1394/ohci1394.c19
-rw-r--r--drivers/isdn/gigaset/common.c2
-rw-r--r--drivers/md/dm-crypt.c11
-rw-r--r--drivers/md/md.c8
-rw-r--r--drivers/md/multipath.c2
-rw-r--r--drivers/md/raid1.c4
-rw-r--r--drivers/md/raid10.c4
-rw-r--r--drivers/message/i2o/exec-osm.c2
-rw-r--r--drivers/misc/ioc4.c4
-rw-r--r--drivers/mtd/nand/nand_base.c1
-rw-r--r--drivers/net/au1000_eth.c2
-rw-r--r--drivers/net/r8169.c38
-rw-r--r--drivers/net/wan/Kconfig2
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c7
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c6
-rw-r--r--drivers/pci/pci-driver.c13
-rw-r--r--drivers/pci/quirks.c73
-rw-r--r--drivers/pci/rom.c5
-rw-r--r--drivers/pcmcia/at91_cf.c28
-rw-r--r--drivers/pcmcia/au1000_generic.c25
-rw-r--r--drivers/pcmcia/ds.c29
-rw-r--r--drivers/pcmcia/i82092.c9
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c12
-rw-r--r--drivers/pcmcia/omap_cf.c3
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c11
-rw-r--r--drivers/pcmcia/pcmcia_resource.c2
-rw-r--r--drivers/pcmcia/pd6729.c4
-rw-r--r--drivers/pcmcia/pxa2xx_base.c41
-rw-r--r--drivers/pcmcia/pxa2xx_base.h2
-rw-r--r--drivers/pcmcia/pxa2xx_lubbock.c2
-rw-r--r--drivers/pcmcia/soc_common.c1
-rw-r--r--drivers/pcmcia/yenta_socket.c22
-rw-r--r--drivers/s390/cio/css.c7
-rw-r--r--drivers/s390/cio/device.c3
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/crypto/ap_bus.c7
-rw-r--r--drivers/sbus/sbus.c4
-rw-r--r--drivers/scsi/dpt/dpti_i2o.h2
-rw-r--r--drivers/scsi/imm.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c4
-rw-r--r--drivers/scsi/ppa.c2
-rw-r--r--drivers/scsi/qla4xxx/Kconfig2
-rw-r--r--drivers/serial/ioc4_serial.c4
-rw-r--r--drivers/usb/net/usbnet.c2
-rw-r--r--drivers/video/backlight/hp680_bl.c2
-rw-r--r--fs/block_dev.c58
-rw-r--r--fs/dcache.c19
-rw-r--r--fs/ecryptfs/crypto.c206
-rw-r--r--fs/ecryptfs/dentry.c8
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h22
-rw-r--r--fs/ecryptfs/file.c44
-rw-r--r--fs/ecryptfs/inode.c95
-rw-r--r--fs/ecryptfs/keystore.c114
-rw-r--r--fs/ecryptfs/main.c15
-rw-r--r--fs/ecryptfs/super.c18
-rw-r--r--fs/ext4/resize.c23
-rw-r--r--fs/hugetlbfs/inode.c25
-rw-r--r--fs/jbd/transaction.c15
-rw-r--r--fs/jbd2/transaction.c15
-rw-r--r--fs/splice.c9
-rw-r--r--include/asm-arm/uaccess.h20
-rw-r--r--include/asm-generic/vmlinux.lds.h17
-rw-r--r--include/asm-i386/mach-visws/do_timer.h53
-rw-r--r--include/asm-i386/mach-visws/mach_apic.h5
-rw-r--r--include/asm-mips/div64.h21
-rw-r--r--include/asm-mips/mipsmtregs.h2
-rw-r--r--include/asm-mips/sibyte/sb1250.h2
-rw-r--r--include/asm-mips/time.h10
-rw-r--r--include/asm-mips/unistd.h19
-rw-r--r--include/asm-sh/irq.h10
-rw-r--r--include/asm-sh/unistd.h5
-rw-r--r--include/asm-um/common.lds.S8
-rw-r--r--include/linux/compat.h2
-rw-r--r--include/linux/init.h28
-rw-r--r--include/linux/mmzone.h6
-rw-r--r--include/linux/mtd/nand.h2
-rw-r--r--include/linux/pagemap.h14
-rw-r--r--include/linux/sched.h1
-rw-r--r--include/linux/taskstats_kern.h31
-rw-r--r--include/linux/vmalloc.h3
-rw-r--r--include/linux/wait.h9
-rw-r--r--kernel/compat.c2
-rw-r--r--kernel/cpu.c12
-rw-r--r--kernel/exit.c1
-rw-r--r--kernel/fork.c3
-rw-r--r--kernel/module.c4
-rw-r--r--kernel/taskstats.c87
-rw-r--r--kernel/time/ntp.c2
-rw-r--r--kernel/tsacct.c17
-rw-r--r--kernel/workqueue.c6
-rw-r--r--lib/Kconfig.debug2
-rw-r--r--lib/string.c2
-rw-r--r--mm/filemap.c24
-rw-r--r--mm/hugetlb.c3
-rw-r--r--mm/page_alloc.c4
-rw-r--r--mm/sparse.c2
-rw-r--r--mm/vmalloc.c18
-rw-r--r--mm/vmscan.c63
-rw-r--r--mm/vmstat.c2
-rw-r--r--net/appletalk/ddp.c2
-rw-r--r--net/core/skbuff.c9
-rw-r--r--net/dccp/ccids/ccid2.c18
-rw-r--r--net/ipv4/cipso_ipv4.c7
-rw-r--r--net/ipv4/ip_options.c2
-rw-r--r--net/ipv4/netfilter/arp_tables.c25
-rw-r--r--net/ipv4/netfilter/ip_tables.c67
-rw-r--r--net/ipv4/raw.c17
-rw-r--r--net/ipv6/ip6_flowlabel.c24
-rw-r--r--net/ipv6/netfilter/Kconfig2
-rw-r--r--net/ipv6/netfilter/ip6_tables.c24
-rw-r--r--net/ipv6/raw.c17
-rw-r--r--net/netfilter/nf_conntrack_core.c3
-rw-r--r--net/netlink/af_netlink.c5
-rw-r--r--net/sctp/associola.c15
-rw-r--r--net/sctp/endpointola.c7
-rw-r--r--net/sctp/input.c9
-rw-r--r--net/sctp/protocol.c2
-rw-r--r--net/sctp/socket.c9
-rw-r--r--net/sunrpc/svcauth.c4
-rw-r--r--net/sunrpc/svcsock.c31
-rw-r--r--net/xfrm/xfrm_user.c4
-rw-r--r--security/selinux/hooks.c8
-rw-r--r--security/selinux/include/selinux_netlabel.h10
-rw-r--r--security/selinux/ss/services.c37
252 files changed, 3712 insertions, 2444 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 66e1cf73357..3bf5086574b 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -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
index 00000000000..4785032fb6e
--- /dev/null
+++ b/Documentation/DocBook/filesystems.tmpl
@@ -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>
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 2b5ac604948..a166675c430 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -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>
diff --git a/Documentation/mips/time.README b/Documentation/mips/time.README
index e1304b6bc48..a4ce603ed3b 100644
--- a/Documentation/mips/time.README
+++ b/Documentation/mips/time.README
@@ -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.
diff --git a/Makefile b/Makefile
index 25b35992a02..95576199f3c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 19
-EXTRAVERSION =-rc3
+EXTRAVERSION =-rc4
NAME=Avast! A bilge rat!
# *DOCUMENTATION*
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 71470e9d93b..76bf071e376 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -48,13 +48,7 @@ SECTIONS
. = ALIGN(8);
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2a0b2c8a1fe..6f4f8bf3607 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -174,11 +174,13 @@ libs-y := arch/arm/lib/ $(libs-y)
# Default target when executing plain make
ifeq ($(CONFIG_XIP_KERNEL),y)
-all: xipImage
+KBUILD_IMAGE := xipImage
else
-all: zImage
+KBUILD_IMAGE := zImage
endif
+all: $(KBUILD_IMAGE)
+
boot := arch/arm/boot
# Update machine arch and proc symlinks if something which affects
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig
new file mode 100644
index 00000000000..ffd905ff19f
--- /dev/null
+++ b/arch/arm/configs/realview-smp_defconfig
@@ -0,0 +1,994 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.19-rc3
+# Wed Oct 25 14:12:00 2006
+#
+CONFIG_ARM=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+CONFIG_ARCH_REALVIEW=y
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# RealView platform type
+#
+CONFIG_MACH_REALVIEW_EB=y
+CONFIG_REALVIEW_MPCORE=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_GIC=y
+CONFIG_ICST307=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+CONFIG_HOTPLUG_CPU=y
+CONFIG_LOCAL_TIMERS=y
+# CONFIG_PREEMPT is not set
+# CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
+# CONFIG_AEABI is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
+# CONFIG_XIP_KERNEL is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+# CONFIG_APM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_ARM_INTEGRATOR=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SMC91X=y
+# CONFIG_DM9000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=16
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+CONFIG_FB_ARMCLCD=y
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_AC97_CODEC=m
+CONFIG_SND_AC97_BUS=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_ARMAACI=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_ARMMMCI=y
+# CONFIG_MMC_TIFM_SD is not set
+
+#
+# Real Time Clock
+#
+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=y
+
+#
+# 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_PL031=y
+# CONFIG_RTC_DRV_TEST is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS 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_INOTIFY=y
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 421329f5e18..a07d202143c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/module.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
@@ -19,6 +20,7 @@
#include <linux/cpu.h>
#include <linux/smp.h>
#include <linux/seq_file.h>
+#include <linux/irq.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
@@ -474,25 +476,26 @@ void show_local_irqs(struct seq_file *p)
seq_putc(p, '\n');
}
-static void ipi_timer(struct pt_regs *regs)
+static void ipi_timer(void)
{
- int user = user_mode(regs);
-
irq_enter();
- profile_tick(CPU_PROFILING, regs);
- update_process_times(user);
+ profile_tick(CPU_PROFILING);
+ update_process_times(user_mode(get_irq_regs()));
irq_exit();
}
#ifdef CONFIG_LOCAL_TIMERS
asmlinkage void do_local_timer(struct pt_regs *regs)
{
+ struct pt_regs *old_regs = set_irq_regs(regs);
int cpu = smp_processor_id();
if (local_timer_ack()) {
irq_stat[cpu].local_timer_irqs++;
- ipi_timer(regs);
+ ipi_timer();
}
+
+ set_irq_regs(old_regs);
}
#endif
@@ -551,6 +554,7 @@ asmlinkage void do_IPI(struct pt_regs *regs)
{
unsigned int cpu = smp_processor_id();
struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
+ struct pt_regs *old_regs = set_irq_regs(regs);
ipi->ipi_count++;
@@ -574,7 +578,7 @@ asmlinkage void do_IPI(struct pt_regs *regs)
switch (nextmsg) {
case IPI_TIMER:
- ipi_timer(regs);
+ ipi_timer();
break;
case IPI_RESCHEDULE:
@@ -599,6 +603,8 @@ asmlinkage void do_IPI(struct pt_regs *regs)
}
} while (msgs);
}
+
+ set_irq_regs(old_regs);
}
void smp_send_reschedule(int cpu)
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index c03cab5c4c7..0c5a6091a93 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -327,13 +327,12 @@ EXPORT_SYMBOL(restore_time_delta);
*/
void timer_tick(void)
{
- struct pt_regs *regs = get_irq_regs();
profile_tick(CPU_PROFILING);
do_leds();
do_set_rtc();
do_timer(1);
#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
+ update_process_times(user_mode(get_irq_regs()));
#endif
}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 3ca574ee277..a8fa75ea07a 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -45,13 +45,7 @@ SECTIONS
*(.early_param.init)
__early_end = .;
__initcall_start = .;
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
__initcall_end = .;
__con_initcall_start = .;
*(.con_initcall.init)
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index a2c94a47b2b..2499a7707e3 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -85,7 +85,7 @@ n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
irq = IRQ_IOP32X_XINT0;
} else if (PCI_SLOT(dev->devfn) == 2) {
/* RTL8110SB #2 */
- irq = IRQ_IOP32X_XINT1;
+ irq = IRQ_IOP32X_XINT3;
} else if (PCI_SLOT(dev->devfn) == 3) {
/* Sil3512 */
irq = IRQ_IOP32X_XINT2;
diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
index 90a4130114a..78f4c134604 100644
--- a/arch/arm/mach-sa1100/cpu-sa1110.c
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c
@@ -83,7 +83,7 @@ static struct sdram_params sdram_tbl[] __initdata = {
.refresh = 64000,
.cas_latency = 3,
}, { /* Samsung K4S281632B-1H */
- .name = "K4S281632b-1H",
+ .name = "K4S281632B-1H",
.rows = 12,
.tck = 10,
.trp = 20,
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 4fc05ee0a2e..e44b9ed0f81 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -56,7 +56,7 @@ static void vfp_double_normalise_denormal(struct vfp_double *vd)
{
int bits = 31 - fls(vd->significand >> 32);
if (bits == 31)
- bits = 62 - fls(vd->significand);
+ bits = 63 - fls(vd->significand);
vfp_double_dump("normalise_denormal: in", vd);
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index a657a28f08d..f08eafbddcc 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -148,6 +148,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_
/*
* These are arranged in priority order, least to highest.
*/
+ RAISE(FPSCR_DZC, FPSCR_DZE, FPE_FLTDIV);
RAISE(FPSCR_IXC, FPSCR_IXE, FPE_FLTRES);
RAISE(FPSCR_UFC, FPSCR_UFE, FPE_FLTUND);
RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF);
diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c
index cdd627c6b7d..5c4424e362b 100644
--- a/arch/avr32/kernel/vmlinux.lds.c
+++ b/arch/avr32/kernel/vmlinux.lds.c
@@ -38,13 +38,7 @@ SECTIONS
__setup_end = .;
. = ALIGN(4);
__initcall_start = .;
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
__initcall_end = .;
__con_initcall_start = .;
*(.con_initcall.init)
diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
index ba096ebb0b1..2449637e6fc 100644
--- a/arch/cris/arch-v32/drivers/cryptocop.c
+++ b/arch/cris/arch-v32/drivers/cryptocop.c
@@ -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)) {
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index f474534ba78..9c1fb12367f 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -44,13 +44,7 @@ SECTIONS
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S
index 6406c388f88..756325dd480 100644
--- a/arch/h8300/kernel/vmlinux.lds.S
+++ b/arch/h8300/kernel/vmlinux.lds.S
@@ -118,13 +118,7 @@ SECTIONS
. = ALIGN(0x4) ;
___setup_end = .;
___initcall_start = .;
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
___initcall_end = .;
___con_initcall_start = .;
*(.con_initcall.init)
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 2af65858d32..a60358fe9a4 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -198,7 +198,7 @@
* (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>
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 519e63c3c13..141041dde74 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -846,7 +846,7 @@ efi_find_max_pfn(unsigned long start, unsigned long end, void *arg)
static int __init
efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
{
- memory_present(0, start, end);
+ memory_present(0, PFN_UP(start), PFN_DOWN(end));
return 0;
}
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 1e7ac1c44dd..adc1f232afe 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -126,13 +126,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c
index 07097ed4889..38c2b13124d 100644
--- a/arch/i386/mach-visws/visws_apic.c
+++ b/arch/i386/mach-visws/visws_apic.c
@@ -122,7 +122,7 @@ static void end_cobalt_irq(unsigned int irq)
spin_unlock_irqrestore(&cobalt_lock, flags);
}
-static struct hw_interrupt_type cobalt_irq_type = {
+static struct irq_chip cobalt_irq_type = {
.typename = "Cobalt-APIC",
.startup = startup_cobalt_irq,
.shutdown = disable_cobalt_irq,
@@ -159,7 +159,7 @@ static void end_piix4_master_irq(unsigned int irq)
spin_unlock_irqrestore(&cobalt_lock, flags);
}
-static struct hw_interrupt_type piix4_master_irq_type = {
+static struct irq_chip piix4_master_irq_type = {
.typename = "PIIX4-master",
.startup = startup_piix4_master_irq,
.ack = ack_cobalt_irq,
@@ -167,9 +167,8 @@ static struct hw_interrupt_type piix4_master_irq_type = {
};
-static struct hw_interrupt_type piix4_virtual_irq_type = {
+static struct irq_chip piix4_virtual_irq_type = {
.typename = "PIIX4-virtual",
- .startup = startup_8259A_irq,
.shutdown = disable_8259A_irq,
.enable = enable_8259A_irq,
.disable = disable_8259A_irq,
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 908b410f4c9..c1949ff38d6 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -343,6 +343,61 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_ro
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk );
/*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video
+ * card will have it's BIOS copied to C0000 in system RAM.
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ */
+
+static void __devinit pci_fixup_video(struct pci_dev *pdev)
+{
+ struct pci_dev *bridge;
+ struct pci_bus *bus;
+ u16 config;
+
+ if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ return;
+
+ /* Is VGA routed to us? */
+ bus = pdev->bus;
+ while (bus) {
+ bridge = bus->self;
+
+ /*
+ * From information provided by
+ * "David Miller" <davem@davemloft.net>
+ * The bridge control register is valid for PCI header
+ * type BRIDGE, or CARDBUS. Host to PCI controllers use
+ * PCI header type NORMAL.
+ */
+ if (bridge
+ &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) {
+ pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+ &config);
+ if (!(config & PCI_BRIDGE_CTL_VGA))
+ return;
+ }
+ bus = bus->parent;
+ }
+ pci_read_config_word(pdev, PCI_COMMAND, &config);
+ if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+ pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+ printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
+
+/*
* Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
*
* We pretend to bring them out of full D3 state, and restore the proper
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index b3b2e389d6b..d6083a0936f 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -128,13 +128,7 @@ SECTIONS
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET)
{
__initcall_start = .;
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
__initcall_end = .;
}
diff --git a/arch/ia64/pci/Makefile b/arch/ia64/pci/Makefile
index e66889e6922..fb14dc520d2 100644
--- a/arch/ia64/pci/Makefile
+++ b/arch/ia64/pci/Makefile
@@ -1,4 +1,4 @@
#
# Makefile for the ia64-specific parts of the pci bus
#
-obj-y := pci.o
+obj-y := pci.o fixup.o
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
new file mode 100644
index 00000000000..245dc1fedc2
--- /dev/null
+++ b/arch/ia64/pci/fixup.c
@@ -0,0 +1,69 @@
+/*
+ * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
+ * Derived from fixup.c of i386 tree.
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/machvec.h>
+
+/*
+ * Fixup to mark boot BIOS video selected by BIOS before it changes
+ *
+ * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
+ *
+ * The standard boot ROM sequence for an x86 machine uses the BIOS
+ * to select an initial video card for boot display. This boot video
+ * card will have it's BIOS copied to C0000 in system RAM.
+ * IORESOURCE_ROM_SHADOW is used to associate the boot video
+ * card with this copy. On laptops this copy has to be used since
+ * the main ROM may be compressed or combined with another image.
+ * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
+ * is marked here since the boot video device will be the only enabled
+ * video device at this point.
+ */
+
+static void __devinit pci_fixup_video(struct pci_dev *pdev)
+{
+ struct pci_dev *bridge;
+ struct pci_bus *bus;
+ u16 config;
+
+ if ((strcmp(platform_name, "dig") != 0)
+ && (strcmp(platform_name, "hpzx1") != 0))
+ return;
+ /* Maybe, this machine supports legacy memory map. */
+
+ if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ return;
+
+ /* Is VGA routed to us? */
+ bus = pdev->bus;
+ while (bus) {
+ bridge = bus->self;
+
+ /*
+ * From information provided by
+ * "David Miller" <davem@davemloft.net>
+ * The bridge control register is valid for PCI header
+ * type BRIDGE, or CARDBUS. Host to PCI controllers use
+ * PCI header type NORMAL.
+ */
+ if (bridge
+ &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE)
+ ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) {
+ pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
+ &config);
+ if (!(config & PCI_BRIDGE_CTL_VGA))
+ return;
+ }
+ bus = bus->parent;
+ }
+ pci_read_config_word(pdev, PCI_COMMAND, &config);
+ if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
+ pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
+ printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S
index 13c7bb698e3..358b9cee2c6 100644
--- a/arch/m32r/kernel/vmlinux.lds.S
+++ b/arch/m32r/kernel/vmlinux.lds.S
@@ -83,13 +83,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 69d1d3d30c7..d2794452b19 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -54,13 +54,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 65cc39c2418..2550b4ae273 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -48,13 +48,7 @@ __init_begin = .;
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index ccd2ceb05cf..58afa8be604 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -140,13 +140,7 @@ SECTIONS {
*(.init.setup)
__setup_end = .;
__initcall_start = .;
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
__initcall_end = .;
__con_initcall_start = .;
*(.con_initcall.init)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 14af6cce2fa..74ba7637811 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -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
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index b4b010a2fe3..6fce60af005 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -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]);
}
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index 377ae0d8ff0..919172db560 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -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);
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 94f09194d63..fa1c62f0551 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -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
}
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 4cf0c06e241..69e424e9ab6 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -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);
diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c
index 7c930860c92..197ed4c2ba0 100644
--- a/arch/mips/emma2rh/common/irq_emma2rh.c
+++ b/arch/mips/emma2rh/common/irq_emma2rh.c
@@ -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;
diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c
index f23ae9fcffa..0b36eb001e6 100644
--- a/arch/mips/emma2rh/markeins/irq_markeins.c
+++ b/arch/mips/emma2rh/markeins/irq_markeins.c
@@ -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;
diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c
index 15cc61df362..11567702b15 100644
--- a/arch/mips/emma2rh/markeins/platform.c
+++ b/arch/mips/emma2rh/markeins/platform.c
@@ -44,18 +44,45 @@
#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,
},
};
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
index 39a0243bed9..de4a238c28b 100644
--- a/arch/mips/jmr3927/rbhma3100/irq.c
+++ b/arch/mips/jmr3927/rbhma3100/irq.c
@@ -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
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 025434054ed..16e5dfe7aa8 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -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
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 720fac3435d..a95f37de080 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -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
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 3a34f62c8b1..8fb0f60f657 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -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
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 67b92a1d6c7..0da5ca2040f 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -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
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 2875c4a3fa5..b9d00cae8b5 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -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
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 3b5f3b63262..2ac19a6cbf6 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -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)
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index debe86c2f69..e535f86efa2 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -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
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index cce8313ec27..9fda1b8be3a 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -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 */
}
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 0bb9cd88945..25ed3337ce3 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -91,13 +91,7 @@ SECTIONS
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index c079e2ae02a..d817c60c5ca 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -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);
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 5537558f19f..ea49a775bf2 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -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);
diff --git a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h
index fcb8275e219..95e0534026d 100644
--- a/arch/mips/momentum/ocelot_g/ocelot_pld.h
+++ b/arch/mips/momentum/ocelot_g/ocelot_pld.h
@@ -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__ */
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c
index 56ec47039c1..d288f7b0184 100644
--- a/arch/mips/momentum/ocelot_g/setup.c
+++ b/arch/mips/momentum/ocelot_g/setup.c
@@ -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);
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index dd0aec9c3ce..1fb240c57ba 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -31,16 +31,18 @@
#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
diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c
index 0af655b1f33..65c440e8480 100644
--- a/arch/mips/philips/pnx8550/common/time.c
+++ b/arch/mips/philips/pnx8550/common/time.c
@@ -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)
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
index 416da22b3bf..85b14c73c22 100644
--- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
+++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
@@ -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;
diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c
index 65fa3a23ea5..3cc0436db6c 100644
--- a/arch/mips/pmc-sierra/yosemite/smp.c
+++ b/arch/mips/pmc-sierra/yosemite/smp.c
@@ -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);
}
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index 4e870fc4469..c965705f342 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -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)
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index bf12af46132..e136bde5248 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -47,6 +47,12 @@
#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;
}
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index 0ccf1796dd7..bcb74f2c194 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -47,15 +47,11 @@
#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
index 00000000000..33f517bc9a0
--- /dev/null
+++ b/arch/mips/tx4927/common/smsc_fdc37m81x.c
@@ -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
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
index 4658b2ae483..941c441729b 100644
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ b/arch/mips/tx4927/common/tx4927_setup.c
@@ -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)
{
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
index b926e6a75c2..08b20cdfd7b 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c
@@ -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)
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index b3677fc8eef..7b943b45f7c 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -153,13 +153,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index cb0e8d46c3e..e8342d86753 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -108,13 +108,7 @@ SECTIONS
.initcall.init : {
__initcall_start = .;
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
__initcall_end = .;
}
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 095fd332332..16e8661e1fe 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -115,13 +115,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index 45c9fa7d754..af1e8fc7d98 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -310,6 +310,7 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp,
if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) {
return -EFAULT;
}
+ interval = 0;
sscanf(buf, "%i", &interval);
if (interval <= 0) {
P_ERROR("Timer CPU interval has to be > 0!\n");
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 2001767e1dc..5b33f823863 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -757,7 +757,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)))
error = -EFAULT;
}
- copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
+ if (copy_to_user(args->__unused, tmp.__unused,
+ sizeof(tmp.__unused)))
+ error = -EFAULT;
}
return error;
}
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index d49b876a83b..861888ab8c1 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -169,12 +169,12 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
compat_old_sigset_t mask;
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(sa_handler, &act->sa_handler) ||
- __get_user(sa_restorer, &act->sa_restorer))
+ __get_user(sa_restorer, &act->sa_restorer) ||
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+ __get_user(mask, &act->sa_mask))
return -EFAULT;
new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
}
@@ -185,10 +185,10 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
sa_restorer = (unsigned long) old_ka.sa.sa_restorer;
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(sa_handler, &oact->sa_handler) ||
- __put_user(sa_restorer, &oact->sa_restorer))
+ __put_user(sa_restorer, &oact->sa_restorer) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index cb0efae6802..71e54ef0931 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1664,4 +1664,4 @@ sys_getcpu_wrapper:
llgtr %r2,%r2 # unsigned *
llgtr %r3,%r3 # unsigned *
llgtr %r4,%r4 # struct getcpu_cache *
- jg sys_tee
+ jg sys_getcpu
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 4392a77cbae..4c8a7954ef4 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -80,10 +80,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
old_sigset_t mask;
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+ __get_user(mask, &act->sa_mask))
return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
siginitset(&new_ka.sa.sa_mask, mask);
}
@@ -92,10 +92,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
if (!ret && oact) {
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
}
return ret;
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 66375a5e3d1..92ecffbc8d8 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -462,7 +462,8 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
local_irq_enable();
if (regs->psw.mask & PSW_MASK_PSTATE) {
- get_user(*((__u16 *) opcode), (__u16 __user *) location);
+ if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
+ return;
if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
if (current->ptrace & PT_PTRACED)
force_sig(SIGTRAP, current);
@@ -470,20 +471,25 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
signal = SIGILL;
#ifdef CONFIG_MATHEMU
} else if (opcode[0] == 0xb3) {
- get_user(*((__u16 *) (opcode+2)), location+1);
+ if (get_user(*((__u16 *) (opcode+2)), location+1))
+ return;
signal = math_emu_b3(opcode, regs);
} else if (opcode[0] == 0xed) {
- get_user(*((__u32 *) (opcode+2)),
- (__u32 __user *)(location+1));
+ if (get_user(*((__u32 *) (opcode+2)),
+ (__u32 __user *)(location+1)))
+ return;
signal = math_emu_ed(opcode, regs);
} else if (*((__u16 *) opcode) == 0xb299) {
- get_user(*((__u16 *) (opcode+2)), location+1);
+ if (get_user(*((__u16 *) (opcode+2)), location+1))
+ return;
signal = math_emu_srnm(opcode, regs);
} else if (*((__u16 *) opcode) == 0xb29c) {
- get_user(*((__u16 *) (opcode+2)), location+1);
+ if (get_user(*((__u16 *) (opcode+2)), location+1))
+ return;
signal = math_emu_stfpc(opcode, regs);
} else if (*((__u16 *) opcode) == 0xb29d) {
- get_user(*((__u16 *) (opcode+2)), location+1);
+ if (get_user(*((__u16 *) (opcode+2)), location+1))
+ return;
signal = math_emu_lfpc(opcode, regs);
#endif
} else
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index af9e69a0301..fe0f2e97ba7 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -83,13 +83,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c
index 1d997ffd793..f7d0e304d89 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/setup.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c
@@ -15,12 +15,16 @@
#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();
}
diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c
index e57e7afab8c..180810b1210 100644
--- a/arch/sh/boards/renesas/sh7710voipgw/setup.c
+++ b/arch/sh/boards/renesas/sh7710voipgw/setup.c
@@ -13,6 +13,51 @@
#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));
}
/*
diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c
index ad1034f98a2..1279d776d60 100644
--- a/arch/sh/boards/se/7300/irq.c
+++ b/arch/sh/boards/se/7300/irq.c
@@ -13,6 +13,17 @@
#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 */
}
diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c
index 2c62b8ea350..e7200c56bb4 100644
--- a/arch/sh/boards/se/73180/irq.c
+++ b/arch/sh/boards/se/73180/irq.c
@@ -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 */
}
diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c
index 288b62f5941..360153ecc55 100644
--- a/arch/sh/boards/se/7343/irq.c
+++ b/arch/sh/boards/se/7343/irq.c
@@ -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 */
}
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
index cff6700bbaf..fcd7cd7fa05 100644
--- a/arch/sh/boards/se/770x/irq.c
+++ b/arch/sh/boards/se/770x/irq.c
@@ -13,6 +13,48 @@
#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));
}
diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c
index c607b0a4847..e4c63a48296 100644
--- a/arch/sh/boards/se/7751/irq.c
+++ b/arch/sh/boards/se/7751/irq.c
@@ -14,53 +14,50 @@
#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));
}
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
index 137e2ba9243..5ad1e19771b 100644
--- a/arch/sh/boards/sh03/setup.c
+++ b/arch/sh/boards/sh03/setup.c
@@ -14,14 +14,17 @@
#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;
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c
index 540d0bf1644..650fb364594 100644
--- a/arch/sh/boards/snapgear/setup.c
+++ b/arch/sh/boards/snapgear/setup.c
@@ -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));
}
/*
diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c
index 52b66d8b8d2..a6046d93758 100644
--- a/arch/sh/boards/titan/setup.c
+++ b/arch/sh/boards/titan/setup.c
@@ -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 = {
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig
index 2470364948e..34e2046c321 100644
--- a/arch/sh/configs/r7780rp_defconfig
+++ b/arch/sh/configs/r7780rp_defconfig
@@ -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
@@ -441,76 +441,28 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# 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
@@ -868,14 +869,9 @@ CONFIG_HWMON=y
# 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
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 5e817546113..41049cf14b7 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -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
@@ -714,6 +717,12 @@ CONFIG_BLK_DEV_INITRD=y
CONFIG_ATA_OVER_ETH=m
#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
@@ -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
@@ -1124,14 +1132,9 @@ CONFIG_HWMON=y
# 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
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index d8ece20bb2c..66078601335 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -19,23 +19,34 @@
#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
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index f7997312ef9..a0089563cbf 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -23,24 +23,21 @@
#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);
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c
index 17f47b373d6..f60007783a2 100644
--- a/arch/sh/kernel/cpu/irq/pint.c
+++ b/arch/sh/kernel/cpu/irq/pint.c
@@ -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);
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S
index 768334e9507..ca81976e9e3 100644
--- a/arch/sh/kernel/syscalls.S
+++ b/arch/sh/kernel/syscalls.S
@@ -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
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 5eb93091818..77b4026d568 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -76,13 +76,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S
index a8fcc3a7158..95c4d753e35 100644
--- a/arch/sh64/kernel/vmlinux.lds.S
+++ b/arch/sh64/kernel/vmlinux.lds.S
@@ -108,13 +108,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : C_PHYS(.initcall.init) {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index 75ac24d229b..ba58c3a061f 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -237,12 +237,12 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d
dev->ofdev.node = dp;
dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
dev->ofdev.dev.bus = &ebus_bus_type;
- strcpy(dev->ofdev.dev.bus_id, dp->path_component_name);
+ sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
/* Register with core */
if (of_device_register(&dev->ofdev) != 0)
printk(KERN_DEBUG "ebus: device registration error for %s!\n",
- dev->ofdev.dev.bus_id);
+ dp->path_component_name);
if ((dp = dp->child) != NULL) {
dev->children = (struct linux_ebus_child *)
@@ -332,12 +332,12 @@ void __init ebus_init(void)
ebus->ofdev.node = dp;
ebus->ofdev.dev.parent = &pdev->dev;
ebus->ofdev.dev.bus = &ebus_bus_type;
- strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name);
+ sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
/* Register with core */
if (of_device_register(&ebus->ofdev) != 0)
printk(KERN_DEBUG "ebus: device registration error for %s!\n",
- ebus->ofdev.dev.bus_id);
+ dp->path_component_name);
nd = dp->child;
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index 74bef2a2d37..46200c43ffb 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -651,7 +651,7 @@ build_resources:
if (!parent)
strcpy(op->dev.bus_id, "root");
else
- strcpy(op->dev.bus_id, dp->path_component_name);
+ sprintf(op->dev.bus_id, "%08x", dp->node);
if (of_device_register(op)) {
printk("%s: Could not register of device.\n",
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 1dd78c84888..5cc5ff7f882 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -49,13 +49,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index 2df25c2b407..35bf895fdee 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -389,12 +389,12 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de
dev->ofdev.node = dp;
dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
dev->ofdev.dev.bus = &ebus_bus_type;
- strcpy(dev->ofdev.dev.bus_id, dp->path_component_name);
+ sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
/* Register with core */
if (of_device_register(&dev->ofdev) != 0)
printk(KERN_DEBUG "ebus: device registration error for %s!\n",
- dev->ofdev.dev.bus_id);
+ dp->path_component_name);
dp = dp->child;
if (dp) {
@@ -494,12 +494,12 @@ void __init ebus_init(void)
ebus->ofdev.node = dp;
ebus->ofdev.dev.parent = &pdev->dev;
ebus->ofdev.dev.bus = &ebus_bus_type;
- strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name);
+ sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
/* Register with core */
if (of_device_register(&ebus->ofdev) != 0)
printk(KERN_DEBUG "ebus: device registration error for %s!\n",
- ebus->ofdev.dev.bus_id);
+ dp->path_component_name);
child = dp->child;
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index 0f3aec72ef5..f028e68b23f 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -115,12 +115,12 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
isa_dev->ofdev.node = dp;
isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
isa_dev->ofdev.dev.bus = &isa_bus_type;
- strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name);
+ sprintf(isa_dev->ofdev.dev.bus_id, "isa[%08x]", dp->node);
/* Register with core */
if (of_device_register(&isa_dev->ofdev) != 0) {
printk(KERN_DEBUG "isa: device registration error for %s!\n",
- isa_dev->ofdev.dev.bus_id);
+ dp->path_component_name);
kfree(isa_dev);
goto next_sibling;
}
@@ -191,12 +191,12 @@ void __init isa_init(void)
isa_br->ofdev.node = dp;
isa_br->ofdev.dev.parent = &pdev->dev;
isa_br->ofdev.dev.bus = &isa_bus_type;
- strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name);
+ sprintf(isa_br->ofdev.dev.bus_id, "isa%d", index);
/* Register with core */
if (of_device_register(&isa_br->ofdev) != 0) {
printk(KERN_DEBUG "isa: device registration error for %s!\n",
- isa_br->ofdev.dev.bus_id);
+ dp->path_component_name);
kfree(isa_br);
return;
}
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index 983ca5f485c..8cc14fc6b6f 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -861,7 +861,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
if (!parent)
strcpy(op->dev.bus_id, "root");
else
- sprintf(op->dev.bus_id, "%s@%08x", dp->name, dp->node);
+ sprintf(op->dev.bus_id, "%08x", dp->node);
if (of_device_register(op)) {
printk("%s: Could not register of device.\n",
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index c60efb3cb22..0917c24c4f0 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -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
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 68420e2dad0..fe1796c939c 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -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,
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index b097379a49a..bd9de8c2a2a 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -57,13 +57,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/um/Makefile b/arch/um/Makefile
index c8016a98483..5d5ed726faa 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -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
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index b65ca115ef7..c9f1c5b24c9 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -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)
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index d278682dd79..69ecea63fda 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -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
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index bc458f57921..49c047b75cc 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -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)
{
diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h
index d0b690197fd..1ea6d928e1c 100644
--- a/arch/um/include/mconsole_kern.h
+++ b/arch/um/include/mconsole_kern.h
@@ -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;
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 68ed24df5c8..e36f92b463c 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -14,6 +14,7 @@ SECTIONS
* is remapped.*/
__binary_start = .;
. = ALIGN(4096); /* Init code and data */
+ _text = .;
_stext = .;
__init_begin = .;
.init.text : {
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 9882342206e..b9195355075 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -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);
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 8eca47a6ff0..f6301274cf3 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -25,6 +25,7 @@ SECTIONS
. = ALIGN(4096); /* Init code and data */
#endif
+ _text = .;
_stext = .;
__init_begin = .;
.init.text : {
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 6e945ab4584..256532034c6 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -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"
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index a2de2580b8a..9f7999f27c7 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -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"
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 8e55cd5d3d0..1b0ad0e4adc 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -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);
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
index 57c9286a701..f4a4bffd8a1 100644
--- a/arch/um/sys-x86_64/unmap.c
+++ b/arch/um/sys-x86_64/unmap.c
@@ -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);
diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
index 63399219cd9..88d087f527c 100644
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -140,13 +140,7 @@
___setup_end = . ; \
___initcall_start = . ; \
*(.initcall.init) \
- *(.initcall1.init) \
- *(.initcall2.init) \
- *(.initcall3.init) \
- *(.initcall4.init) \
- *(.initcall5.init) \
- *(.initcall6.init) \
- *(.initcall7.init) \
+ INITCALLS \
. = ALIGN (4) ; \
___initcall_end = . ; \
___con_initcall_start = .; \
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index a6ba9951e86..0e0a266d976 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -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));
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 1283614c9b2..edb24aa714b 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -175,13 +175,7 @@ SECTIONS
__setup_end = .;
__initcall_start = .;
.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
__con_initcall_start = .;
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index 7732f4254d2..e61093b34c2 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -220,7 +220,7 @@ void __init pci_mmcfg_init(int type)
pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
if (pci_mmcfg_virt == NULL) {
- printk("PCI: Can not allocate memory for mmconfig structures\n");
+ printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
return;
}
for (i = 0; i < pci_mmcfg_config_num; ++i) {
@@ -228,7 +228,8 @@ void __init pci_mmcfg_init(int type)
pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address,
MMCONFIG_APER_MAX);
if (!pci_mmcfg_virt[i].virt) {
- printk("PCI: Cannot map mmconfig aperture for segment %d\n",
+ printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
+ "segment %d\n",
pci_mmcfg_config[i].pci_segment_group_number);
return;
}
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index ab6cdbd5eb6..cfe75f52872 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -184,13 +184,7 @@ SECTIONS
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index d3d76136f53..1d9c3c70a9a 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -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);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 136066583c6..c7b1dac8bee 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -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);
}
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 0b4e2243693..1429f3a2629 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -37,8 +37,8 @@ config DEBUG_DRIVER
If you are unsure about this, say N here.
-endmenu
-
config SYS_HYPERVISOR
bool
default n
+
+endmenu
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index db01b95a47a..c5d6bb4290a 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -18,6 +18,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kthread.h>
+#include <linux/wait.h>
#include "base.h"
#include "power/power.h"
@@ -70,6 +71,8 @@ struct stupid_thread_structure {
};
static atomic_t probe_count = ATOMIC_INIT(0);
+static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue);
+
static int really_probe(void *void_data)
{
struct stupid_thread_structure *data = void_data;
@@ -121,6 +124,7 @@ probe_failed:
done:
kfree(data);
atomic_dec(&probe_count);
+ wake_up(&probe_waitqueue);
return ret;
}
@@ -337,6 +341,32 @@ void driver_detach(struct device_driver * drv)
}
}
+#ifdef CONFIG_PCI_MULTITHREAD_PROBE
+static int __init wait_for_probes(void)
+{
+ DEFINE_WAIT(wait);
+
+ printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__,
+ atomic_read(&probe_count));
+ if (!atomic_read(&probe_count))
+ return 0;
+ while (atomic_read(&probe_count)) {
+ prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&probe_count))
+ schedule();
+ }
+ finish_wait(&probe_waitqueue, &wait);
+ return 0;
+}
+
+core_initcall_sync(wait_for_probes);
+postcore_initcall_sync(wait_for_probes);
+arch_initcall_sync(wait_for_probes);
+subsys_initcall_sync(wait_for_probes);
+fs_initcall_sync(wait_for_probes);
+device_initcall_sync(wait_for_probes);
+late_initcall_sync(wait_for_probes);
+#endif
EXPORT_SYMBOL_GPL(device_bind_driver);
EXPORT_SYMBOL_GPL(device_release_driver);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index bc6602606fb..6ffe2b2bdac 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1992,8 +1992,8 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
*block_size = BLOCK_SIZE;
}
if (*total_size != (__u32) 0)
- printk(KERN_INFO " blocks= %lld block_size= %d\n",
- *total_size, *block_size);
+ printk(KERN_INFO " blocks= %llu block_size= %d\n",
+ (unsigned long long)*total_size, *block_size);
kfree(buf);
return;
}
@@ -2027,8 +2027,8 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size,
*total_size = 0;
*block_size = BLOCK_SIZE;
}
- printk(KERN_INFO " blocks= %lld block_size= %d\n",
- *total_size, *block_size);
+ printk(KERN_INFO " blocks= %llu block_size= %d\n",
+ (unsigned long long)*total_size, *block_size);
kfree(buf);
return;
}
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 845b8680032..cbc07250b89 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -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;
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index d8d0f28e0ac..e3239833e4b 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void)
if (io == -1) {
printk(KERN_ERR PFX "io parameter must be specified\n");
ret = -EINVAL;
- goto out_clean;
+ goto out_pnp;
}
#if defined CONFIG_PNP
@@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void)
if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
ret = -EBUSY;
- goto out_clean;
+ goto out_pnp;
}
ret = sc1200wdt_probe();
@@ -435,6 +435,11 @@ out_rbt:
out_io:
release_region(io, io_len);
+out_pnp:
+#if defined CONFIG_PNP
+ if (isapnp)
+ pnp_unregister_driver(&scl200wdt_pnp_driver);
+#endif
goto out_clean;
}
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 81050d3c9b2..c95a6c15416 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -272,7 +272,8 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
__func__, (long)jiffies, ISR, ICR, IBMR);
- if ((ISR & (ISR_UB|ISR_IBB|ISR_SAD)) == ISR_SAD ||
+ if ((ISR & (ISR_UB|ISR_IBB)) == 0 ||
+ (ISR & ISR_SAD) != 0 ||
(ICR & ICR_SCLE) == 0) {
if (i2c_debug > 1)
dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
@@ -492,7 +493,10 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
if (isr & ISR_BED) {
/* what should we do here? */
} else {
- int ret = i2c->slave->read(i2c->slave->data);
+ int ret = 0;
+
+ if (i2c->slave != NULL)
+ ret = i2c->slave->read(i2c->slave->data);
IDBR = ret;
ICR |= ICR_TB; /* allow next byte */
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index ad418ce882c..9f306880491 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -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);
@@ -247,8 +247,10 @@ static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_devi
(!(PCI_FUNC(dev->devfn) & 1)))
goto out;
- if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
- goto out;
+ if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
+ if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 && PCI_FUNC(dev->devfn) != 1)
+ goto out;
+ }
if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
pci_read_config_word(dev, PCI_COMMAND, &command);
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index 8a7b8fab623..31e5cc49d61 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -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;
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index dea13525df8..6e8ea9110c4 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -3552,12 +3552,21 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
{
int err;
+ printk(KERN_INFO "%s does not fully support suspend and resume yet\n",
+ OHCI1394_DRIVER_NAME);
+
err = pci_save_state(pdev);
- if (err)
- goto out;
+ if (err) {
+ printk(KERN_ERR "%s: pci_save_state failed with %d\n",
+ OHCI1394_DRIVER_NAME, err);
+ return err;
+ }
err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#ifdef OHCI1394_DEBUG
if (err)
- goto out;
+ printk(KERN_DEBUG "%s: pci_set_power_state failed with %d\n",
+ OHCI1394_DRIVER_NAME, err);
+#endif /* OHCI1394_DEBUG */
/* PowerMac suspend code comes last */
#ifdef CONFIG_PPC_PMAC
@@ -3570,8 +3579,8 @@ static int ohci1394_pci_suspend (struct pci_dev *pdev, pm_message_t state)
pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 0);
}
#endif /* CONFIG_PPC_PMAC */
-out:
- return err;
+
+ return 0;
}
#endif /* CONFIG_PM */
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index aca165d43aa..d8d256daddd 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -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;
}
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index a625576fdee..08a40f4e4f6 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -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))
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7daa7b1e145..50ab4a936e3 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2003,6 +2003,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
kobject_init(&rdev->kobj);
rdev->desc_nr = -1;
+ rdev->saved_raid_disk = -1;
rdev->flags = 0;
rdev->data_offset = 0;
rdev->sb_events = 0;
@@ -4044,11 +4045,8 @@ static int update_size(mddev_t *mddev, unsigned long size)
return -EBUSY;
ITERATE_RDEV(mddev,rdev,tmp) {
sector_t avail;
- if (rdev->sb_offset > rdev->data_offset)
- avail = (rdev->sb_offset*2) - rdev->data_offset;
- else
- avail = get_capacity(rdev->bdev->bd_disk)
- - rdev->data_offset;
+ avail = rdev->size * 2;
+
if (fit && (size == 0 || size > avail/2))
size = avail/2;
if (avail < ((sector_t)size << 1))
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index a6260f0e3b9..14da37fee37 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -277,6 +277,7 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
set_bit(Faulty, &rdev->flags);
set_bit(MD_CHANGE_DEVS, &mddev->flags);
conf->working_disks--;
+ mddev->degraded++;
printk(KERN_ALERT "multipath: IO failure on %s,"
" disabling IO path. \n Operation continuing"
" on %d IO paths.\n",
@@ -336,6 +337,7 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
conf->working_disks++;
+ mddev->degraded--;
rdev->raid_disk = path;
set_bit(In_sync, &rdev->flags);
rcu_assign_pointer(p->rdev, rdev);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index dc9d2def027..656fae912fe 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1474,8 +1474,8 @@ static void fix_read_error(conf_t *conf, int read_disk,
"raid1:%s: read error corrected "
"(%d sectors at %llu on %s)\n",
mdname(mddev), s,
- (unsigned long long)sect +
- rdev->data_offset,
+ (unsigned long long)(sect +
+ rdev->data_offset),
bdevname(rdev->bdev, b));
}
}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 74f17a9a6eb..7492d6033ac 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1470,8 +1470,8 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio)
"raid10:%s: read error corrected"
" (%d sectors at %llu on %s)\n",
mdname(mddev), s,
- (unsigned long long)sect+
- rdev->data_offset,
+ (unsigned long long)(sect+
+ rdev->data_offset),
bdevname(rdev->bdev, b));
rdev_dec_pending(rdev, mddev);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 01a5a702b03..a2350640384 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -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;
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 79354bbbbd6..b995a15b752 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -210,8 +210,8 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
do_div(ns, IOC4_EXTINT_COUNT_DIVISOR);
printk(KERN_DEBUG
- "IOC4 %s: PCI clock is %lld ns.\n",
- pci_name(idd->idd_pdev), ns);
+ "IOC4 %s: PCI clock is %llu ns.\n",
+ pci_name(idd->idd_pdev), (unsigned long long)ns);
}
/* Remember results. We store the extint clock period rather
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index baece61169f..41bfcae1fbf 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1479,6 +1479,7 @@ static void nand_write_page_syndrome(struct mtd_info *mtd,
* @buf: the data to write
* @page: page number to write
* @cached: cached programming
+ * @raw: use _raw version of write_page
*/
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf, int page, int cached, int raw)
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 4873dc610d2..7db3c8af089 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -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
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index d132fe7d475..27f90b2139c 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1397,41 +1397,6 @@ static void rtl8169_netpoll(struct net_device *dev)
}
#endif
-static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr)
-{
- unsigned int i, j;
-
- RTL_W8(Cfg9346, Cfg9346_Unlock);
- for (i = 0; i < 2; i++) {
- __le32 l = 0;
-
- for (j = 0; j < 4; j++) {
- l <<= 8;
- l |= dev->dev_addr[4*i + j];
- }
- RTL_W32(MAC0 + 4*i, cpu_to_be32(l));
- }
- RTL_W8(Cfg9346, Cfg9346_Lock);
-}
-
-static int rtl8169_set_mac_addr(struct net_device *dev, void *p)
-{
- struct rtl8169_private *tp = netdev_priv(dev);
- struct sockaddr *addr = p;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EINVAL;
-
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
- if (netif_running(dev)) {
- spin_lock_irq(&tp->lock);
- __rtl8169_set_mac_addr(dev, tp->mmio_addr);
- spin_unlock_irq(&tp->lock);
- }
- return 0;
-}
-
static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
void __iomem *ioaddr)
{
@@ -1681,7 +1646,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->stop = rtl8169_close;
dev->tx_timeout = rtl8169_tx_timeout;
dev->set_multicast_list = rtl8169_set_rx_mode;
- dev->set_mac_address = rtl8169_set_mac_addr;
dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
@@ -1929,8 +1893,6 @@ rtl8169_hw_start(struct net_device *dev)
/* Enable all known interrupts by setting the interrupt mask. */
RTL_W16(IntrMask, rtl8169_intr_mask);
- __rtl8169_set_mac_addr(dev, ioaddr);
-
netif_start_queue(dev);
}
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 58b7efbb075..b5d0d7fb647 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -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.
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 686d895116d..f63909e4bc3 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -887,6 +887,13 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
PCMCIA_DEVICE_PROD_ID123(
"U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02",
0xc7b8df9d, 0x1700d087, 0x4b74baa0),
+ PCMCIA_DEVICE_PROD_ID123(
+ "Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio",
+ "Ver. 1.00",
+ 0x5cd01705, 0x4271660f, 0x9d08ee12),
+ PCMCIA_DEVICE_PROD_ID123(
+ "corega", "WL PCCL-11", "ISL37300P",
+ 0xa21501a, 0x59868926, 0xc9049a39),
PCMCIA_DEVICE_NULL
};
MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index c44311ac2fd..16167b01626 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1807,8 +1807,8 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
/*
- * latch closed: 1
- * latch open: 0
+ * latch open: 1
+ * latch closed: 0
*/
u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
{
@@ -1816,7 +1816,7 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
sta = get_slot_status(slot);
- return (sta & ACPI_STA_SHOW_IN_UI) ? 1 : 0;
+ return (sta & ACPI_STA_SHOW_IN_UI) ? 0 : 1;
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index b1c0c707d96..194f1d21d3d 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -265,6 +265,13 @@ static int pci_device_remove(struct device * dev)
}
/*
+ * If the device is still on, set the power state as "unknown",
+ * since it might change by the next time we load the driver.
+ */
+ if (pci_dev->current_state == PCI_D0)
+ pci_dev->current_state = PCI_UNKNOWN;
+
+ /*
* We would love to complain here if pci_dev->is_enabled is set, that
* the driver should have called pci_disable_device(), but the
* unfortunate fact is there are too many odd BIOS and bridge setups
@@ -288,6 +295,12 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
suspend_report_result(drv->suspend, i);
} else {
pci_save_state(pci_dev);
+ /*
+ * mark its power state as "unknown", since we don't know if
+ * e.g. the BIOS will change its device state when we suspend.
+ */
+ if (pci_dev->current_state == PCI_D0)
+ pci_dev->current_state = PCI_UNKNOWN;
}
return i;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e8a7f1b1b2b..204b1c8e972 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -714,33 +714,6 @@ static void __devinit quirk_vt82c598_id(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt82c598_id );
-#ifdef CONFIG_ACPI_SLEEP
-
-/*
- * Some VIA systems boot with the abnormal status flag set. This can cause
- * the BIOS to re-POST the system on resume rather than passing control
- * back to the OS. Clear the flag on boot
- */
-static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev)
-{
- u32 reg;
-
- acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
- &reg);
-
- if (reg & 0x800) {
- printk("Clearing abnormal poweroff flag\n");
- acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS,
- (u16)0x800);
- }
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_abnormal_poweroff);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_abnormal_poweroff);
-
-#endif
-
/*
* CardBus controllers have a legacy base address that enables them
* to respond as i82365 pcmcia controllers. We don't want them to
@@ -1619,52 +1592,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
-/*
- * Fixup to mark boot BIOS video selected by BIOS before it changes
- *
- * From information provided by "Jon Smirl" <jonsmirl@gmail.com>
- *
- * The standard boot ROM sequence for an x86 machine uses the BIOS
- * to select an initial video card for boot display. This boot video
- * card will have it's BIOS copied to C0000 in system RAM.
- * IORESOURCE_ROM_SHADOW is used to associate the boot video
- * card with this copy. On laptops this copy has to be used since
- * the main ROM may be compressed or combined with another image.
- * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW
- * is marked here since the boot video device will be the only enabled
- * video device at this point.
- */
-
-static void __devinit fixup_video(struct pci_dev *pdev)
-{
- struct pci_dev *bridge;
- struct pci_bus *bus;
- u16 config;
-
- if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
- return;
-
- /* Is VGA routed to us? */
- bus = pdev->bus;
- while (bus) {
- bridge = bus->self;
- if (bridge) {
- pci_read_config_word(bridge, PCI_BRIDGE_CONTROL,
- &config);
- if (!(config & PCI_BRIDGE_CTL_VGA))
- return;
- }
- bus = bus->parent;
- }
- pci_read_config_word(pdev, PCI_COMMAND, &config);
- if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
- pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW;
- printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev));
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_video);
-
-
static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
{
while (f < end) {
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 43e4a49f2cc..e1dcefc69bb 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -72,8 +72,9 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
int last_image;
/*
- * IORESOURCE_ROM_SHADOW set if the VGA enable bit of the Bridge Control
- * register is set for embedded VGA.
+ * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy
+ * memory map if the VGA enable bit of the Bridge Control register is
+ * set for embedded VGA.
*/
if (res->flags & IORESOURCE_ROM_SHADOW) {
/* primary video rom always starts here */
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index 7f5df9a9f39..3bcb7dc3299 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -241,12 +241,6 @@ static int __init at91_cf_probe(struct platform_device *pdev)
csa = at91_sys_read(AT91_EBI_CSA);
at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
- /* force poweron defaults for these pins ... */
- (void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */
- (void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */
- (void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */
- (void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */
-
/* nWAIT is _not_ a default setting */
(void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */
@@ -316,12 +310,14 @@ static int __init at91_cf_probe(struct platform_device *pdev)
return 0;
fail2:
- iounmap((void __iomem *) cf->socket.io_offset);
release_mem_region(io->start, io->end + 1 - io->start);
fail1:
+ if (cf->socket.io_offset)
+ iounmap((void __iomem *) cf->socket.io_offset);
if (board->irq_pin)
free_irq(board->irq_pin, cf);
fail0a:
+ device_init_wakeup(&pdev->dev, 0);
free_irq(board->det_pin, cf);
device_init_wakeup(&pdev->dev, 0);
fail0:
@@ -360,26 +356,20 @@ static int at91_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
struct at91_cf_data *board = cf->board;
pcmcia_socket_dev_suspend(&pdev->dev, mesg);
- if (device_may_wakeup(&pdev->dev))
+ if (device_may_wakeup(&pdev->dev)) {
enable_irq_wake(board->det_pin);
- else {
+ if (board->irq_pin)
+ enable_irq_wake(board->irq_pin);
+ } else {
disable_irq_wake(board->det_pin);
- disable_irq(board->det_pin);
+ if (board->irq_pin)
+ disable_irq_wake(board->irq_pin);
}
- if (board->irq_pin)
- disable_irq(board->irq_pin);
return 0;
}
static int at91_cf_resume(struct platform_device *pdev)
{
- struct at91_cf_socket *cf = platform_get_drvdata(pdev);
- struct at91_cf_data *board = cf->board;
-
- if (board->irq_pin)
- enable_irq(board->irq_pin);
- if (!device_may_wakeup(&pdev->dev))
- enable_irq(board->det_pin);
pcmcia_socket_dev_resume(&pdev->dev);
return 0;
}
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index d5dd0ce6553..551bde5d943 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -351,6 +351,7 @@ struct skt_dev_info {
int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
{
struct skt_dev_info *sinfo;
+ struct au1000_pcmcia_socket *skt;
int ret, i;
sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
@@ -365,7 +366,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
* Initialise the per-socket structure.
*/
for (i = 0; i < nr; i++) {
- struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+ skt = PCMCIA_SOCKET(i);
memset(skt, 0, sizeof(*skt));
skt->socket.resource_ops = &pccard_static_ops;
@@ -438,17 +439,29 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,
dev_set_drvdata(dev, sinfo);
return 0;
- do {
- struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
+
+out_err:
+ flush_scheduled_work();
+ ops->hw_shutdown(skt);
+ while (i-- > 0) {
+ skt = PCMCIA_SOCKET(i);
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
-out_err:
flush_scheduled_work();
+ if (i == 0) {
+ iounmap(skt->virt_io + (u32)mips_io_port_base);
+ skt->virt_io = NULL;
+ }
+#ifndef CONFIG_MIPS_XXS1500
+ else {
+ iounmap(skt->virt_io + (u32)mips_io_port_base);
+ skt->virt_io = NULL;
+ }
+#endif
ops->hw_shutdown(skt);
- i--;
- } while (i > 0);
+ }
kfree(sinfo);
out:
return ret;
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 74b3124e824..0f701921c13 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -717,6 +717,7 @@ static int pcmcia_requery(struct device *dev, void * _data)
static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
{
int no_devices=0;
+ int ret = 0;
unsigned long flags;
/* must be called with skt_mutex held */
@@ -729,7 +730,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
* missing resource information or other trouble, we need to
* do this now. */
if (no_devices) {
- int ret = pcmcia_card_add(skt);
+ ret = pcmcia_card_add(skt);
if (ret)
return;
}
@@ -741,7 +742,9 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
/* we re-scan all devices, not just the ones connected to this
* socket. This does not matter, though. */
- bus_rescan_devices(&pcmcia_bus_type);
+ ret = bus_rescan_devices(&pcmcia_bus_type);
+ if (ret)
+ printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n");
}
static inline int pcmcia_devmatch(struct pcmcia_device *dev,
@@ -1001,6 +1004,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+ int ret;
if (!count)
return -EINVAL;
@@ -1009,7 +1013,10 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
p_dev->allow_func_id_match = 1;
mutex_unlock(&p_dev->socket->skt_mutex);
- bus_rescan_devices(&pcmcia_bus_type);
+ ret = bus_rescan_devices(&pcmcia_bus_type);
+ if (ret)
+ printk(KERN_INFO "pcmcia: bus_rescan_devices failed after "
+ "allowing func_id matches\n");
return count;
}
@@ -1292,10 +1299,22 @@ struct bus_type pcmcia_bus_type = {
static int __init init_pcmcia_bus(void)
{
+ int ret;
+
spin_lock_init(&pcmcia_dev_list_lock);
- bus_register(&pcmcia_bus_type);
- class_interface_register(&pcmcia_bus_interface);
+ ret = bus_register(&pcmcia_bus_type);
+ if (ret < 0) {
+ printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret);
+ return ret;
+ }
+ ret = class_interface_register(&pcmcia_bus_interface);
+ if (ret < 0) {
+ printk(KERN_WARNING
+ "pcmcia: class_interface_register error: %d\n", ret);
+ bus_unregister(&pcmcia_bus_type);
+ return ret;
+ }
pcmcia_setup_ioctl();
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 82715f44895..c2ea07aa7a1 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -41,6 +41,7 @@ static struct pci_device_id i82092aa_pci_ids[] = {
};
MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
+#ifdef CONFIG_PM
static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
{
return pcmcia_socket_dev_suspend(&dev->dev, state);
@@ -50,14 +51,17 @@ static int i82092aa_socket_resume (struct pci_dev *dev)
{
return pcmcia_socket_dev_resume(&dev->dev);
}
+#endif
static struct pci_driver i82092aa_pci_drv = {
.name = "i82092aa",
.id_table = i82092aa_pci_ids,
.probe = i82092aa_pci_probe,
.remove = __devexit_p(i82092aa_pci_remove),
+#ifdef CONFIG_PM
.suspend = i82092aa_socket_suspend,
.resume = i82092aa_socket_resume,
+#endif
};
@@ -705,10 +709,7 @@ static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_
static int i82092aa_module_init(void)
{
- enter("i82092aa_module_init");
- pci_register_driver(&i82092aa_pci_drv);
- leave("i82092aa_module_init");
- return 0;
+ return pci_register_driver(&i82092aa_pci_drv);
}
static void i82092aa_module_exit(void)
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index e070a289676..3b72be88040 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -427,7 +427,7 @@ static int voltage_set(int slot, int vcc, int vpp)
reg |= BCSR1_PCCVCC1;
break;
default:
- return 1;
+ goto out_unmap;
}
switch(vpp) {
@@ -438,15 +438,15 @@ static int voltage_set(int slot, int vcc, int vpp)
if(vcc == vpp)
reg |= BCSR1_PCCVPP1;
else
- return 1;
+ goto out_unmap;
break;
case 120:
if ((vcc == 33) || (vcc == 50))
reg |= BCSR1_PCCVPP0;
else
- return 1;
+ goto out_unmap;
default:
- return 1;
+ goto out_unmap;
}
/* first, turn off all power */
@@ -457,6 +457,10 @@ static int voltage_set(int slot, int vcc, int vpp)
iounmap(bcsr_io);
return 0;
+
+out_unmap:
+ iounmap(bcsr_io);
+ return 1;
}
#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index c8e838c6976..06bf7f48836 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -309,9 +309,10 @@ static int __devinit omap_cf_probe(struct device *dev)
return 0;
fail2:
- iounmap((void __iomem *) cf->socket.io_offset);
release_mem_region(cf->phys_cf, SZ_8K);
fail1:
+ if (cf->socket.io_offset)
+ iounmap((void __iomem *) cf->socket.io_offset);
free_irq(irq, cf);
fail0:
kfree(cf);
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 9ad18e62658..310ede575ca 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -128,9 +128,12 @@ static int proc_read_drivers(char *buf, char **start, off_t pos,
int count, int *eof, void *data)
{
char *p = buf;
+ int rc;
- bus_for_each_drv(&pcmcia_bus_type, NULL,
- (void *) &p, proc_read_drivers_callback);
+ rc = bus_for_each_drv(&pcmcia_bus_type, NULL,
+ (void *) &p, proc_read_drivers_callback);
+ if (rc < 0)
+ return rc;
return (p - buf);
}
@@ -269,8 +272,10 @@ rescan:
* Prevent this racing with a card insertion.
*/
mutex_lock(&s->skt_mutex);
- bus_rescan_devices(&pcmcia_bus_type);
+ ret = bus_rescan_devices(&pcmcia_bus_type);
mutex_unlock(&s->skt_mutex);
+ if (ret)
+ goto err_put_module;
/* check whether the driver indeed matched. I don't care if this
* is racy or not, because it can only happen on cardmgr access
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 74cebd42403..b9201c2ec38 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -95,7 +95,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
* potential conflicts, just the most obvious ones.
*/
for (i = 0; i < MAX_IO_WIN; i++)
- if ((s->io[i].res) &&
+ if ((s->io[i].res) && *base &&
((s->io[i].res->start & (align-1)) == *base))
return 1;
for (i = 0; i < MAX_IO_WIN; i++) {
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index c83a0a6b158..a70f97fdbbd 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -755,6 +755,7 @@ static void __devexit pd6729_pci_remove(struct pci_dev *dev)
kfree(socket);
}
+#ifdef CONFIG_PM
static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
{
return pcmcia_socket_dev_suspend(&dev->dev, state);
@@ -764,6 +765,7 @@ static int pd6729_socket_resume(struct pci_dev *dev)
{
return pcmcia_socket_dev_resume(&dev->dev);
}
+#endif
static struct pci_device_id pd6729_pci_ids[] = {
{
@@ -781,8 +783,10 @@ static struct pci_driver pd6729_pci_drv = {
.id_table = pd6729_pci_ids,
.probe = pd6729_pci_probe,
.remove = __devexit_p(pd6729_pci_remove),
+#ifdef CONFIG_PM
.suspend = pd6729_socket_suspend,
.resume = pd6729_socket_resume,
+#endif
};
static int pd6729_module_init(void)
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index b3518131ea0..dca9f8549b3 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -166,7 +166,7 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt,
}
#endif
-int pxa2xx_drv_pcmcia_probe(struct device *dev)
+int __pxa2xx_drv_pcmcia_probe(struct device *dev)
{
int ret;
struct pcmcia_low_level *ops;
@@ -203,35 +203,52 @@ int pxa2xx_drv_pcmcia_probe(struct device *dev)
return ret;
}
-EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe);
+EXPORT_SYMBOL(__pxa2xx_drv_pcmcia_probe);
-static int pxa2xx_drv_pcmcia_resume(struct device *dev)
+
+static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
+{
+ return __pxa2xx_drv_pcmcia_probe(&dev->dev);
+}
+
+static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
+{
+ return soc_common_drv_pcmcia_remove(&dev->dev);
+}
+
+static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state)
+{
+ return pcmcia_socket_dev_suspend(&dev->dev, state);
+}
+
+static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
{
- struct pcmcia_low_level *ops = dev->platform_data;
+ struct pcmcia_low_level *ops = dev->dev.platform_data;
int nr = ops ? ops->nr : 0;
MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
- return pcmcia_socket_dev_resume(dev);
+ return pcmcia_socket_dev_resume(&dev->dev);
}
-static struct device_driver pxa2xx_pcmcia_driver = {
+static struct platform_driver pxa2xx_pcmcia_driver = {
.probe = pxa2xx_drv_pcmcia_probe,
- .remove = soc_common_drv_pcmcia_remove,
- .suspend = pcmcia_socket_dev_suspend,
+ .remove = pxa2xx_drv_pcmcia_remove,
+ .suspend = pxa2xx_drv_pcmcia_suspend,
.resume = pxa2xx_drv_pcmcia_resume,
- .name = "pxa2xx-pcmcia",
- .bus = &platform_bus_type,
+ .driver = {
+ .name = "pxa2xx-pcmcia",
+ },
};
static int __init pxa2xx_pcmcia_init(void)
{
- return driver_register(&pxa2xx_pcmcia_driver);
+ return platform_driver_register(&pxa2xx_pcmcia_driver);
}
static void __exit pxa2xx_pcmcia_exit(void)
{
- driver_unregister(&pxa2xx_pcmcia_driver);
+ platform_driver_unregister(&pxa2xx_pcmcia_driver);
}
fs_initcall(pxa2xx_pcmcia_init);
diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h
index e46cff345d4..235d681652c 100644
--- a/drivers/pcmcia/pxa2xx_base.h
+++ b/drivers/pcmcia/pxa2xx_base.h
@@ -1,3 +1,3 @@
/* temporary measure */
-extern int pxa2xx_drv_pcmcia_probe(struct device *);
+extern int __pxa2xx_drv_pcmcia_probe(struct device *);
diff --git a/drivers/pcmcia/pxa2xx_lubbock.c b/drivers/pcmcia/pxa2xx_lubbock.c
index fd1f691c7c2..a92f11143c4 100644
--- a/drivers/pcmcia/pxa2xx_lubbock.c
+++ b/drivers/pcmcia/pxa2xx_lubbock.c
@@ -260,7 +260,7 @@ int __init pcmcia_lubbock_init(struct sa1111_dev *sadev)
lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
sadev->dev.platform_data = &lubbock_pcmcia_ops;
- ret = pxa2xx_drv_pcmcia_probe(&sadev->dev);
+ ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev);
}
return ret;
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 3627e52e0c2..e433704e026 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -824,3 +824,4 @@ int soc_common_drv_pcmcia_remove(struct device *dev)
return 0;
}
+EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 26229d9da76..da471bddc97 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -1197,8 +1197,12 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
ret = pcmcia_register_socket(&socket->socket);
if (ret == 0) {
/* Add the yenta register attributes */
- device_create_file(&dev->dev, &dev_attr_yenta_registers);
- goto out;
+ ret = device_create_file(&dev->dev, &dev_attr_yenta_registers);
+ if (ret == 0)
+ goto out;
+
+ /* error path... */
+ pcmcia_unregister_socket(&socket->socket);
}
unmap:
@@ -1213,7 +1217,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
return ret;
}
-
+#ifdef CONFIG_PM
static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
{
struct yenta_socket *socket = pci_get_drvdata(dev);
@@ -1248,12 +1252,18 @@ static int yenta_dev_resume (struct pci_dev *dev)
struct yenta_socket *socket = pci_get_drvdata(dev);
if (socket) {
+ int rc;
+
pci_set_power_state(dev, 0);
/* FIXME: pci_restore_state needs to have a better interface */
pci_restore_state(dev);
pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
- pci_enable_device(dev);
+
+ rc = pci_enable_device(dev);
+ if (rc)
+ return rc;
+
pci_set_master(dev);
if (socket->type && socket->type->restore_state)
@@ -1262,7 +1272,7 @@ static int yenta_dev_resume (struct pci_dev *dev)
return pcmcia_socket_dev_resume(&dev->dev);
}
-
+#endif
#define CB_ID(vend,dev,type) \
{ \
@@ -1359,8 +1369,10 @@ static struct pci_driver yenta_cardbus_driver = {
.id_table = yenta_table,
.probe = yenta_probe,
.remove = __devexit_p(yenta_close),
+#ifdef CONFIG_PM
.suspend = yenta_dev_suspend,
.resume = yenta_dev_resume,
+#endif
};
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index a2dee5bf5a1..ad7f7e1c016 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -271,10 +271,6 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow)
/* Reset intparm to zeroes. */
sch->schib.pmcw.intparm = 0;
cio_modify(sch);
-
- /* Probe if necessary. */
- if (action == UNREGISTER_PROBE)
- ret = css_probe_device(sch->schid);
break;
case REPROBE:
device_trigger_reprobe(sch);
@@ -283,6 +279,9 @@ static int css_evaluate_known_subchannel(struct subchannel *sch, int slow)
break;
}
spin_unlock_irqrestore(&sch->lock, flags);
+ /* Probe if necessary. */
+ if (action == UNREGISTER_PROBE)
+ ret = css_probe_device(sch->schid);
return ret;
}
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 94bdd4d8a4c..39c98f94050 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -532,8 +532,7 @@ device_remove_files(struct device *dev)
/* this is a simple abstraction for device_register that sets the
* correct bus type and adds the bus specific files */
-int
-ccw_device_register(struct ccw_device *cdev)
+static int ccw_device_register(struct ccw_device *cdev)
{
struct device *dev = &cdev->dev;
int ret;
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index c6140cc97a8..9233b5c0bcc 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -78,7 +78,6 @@ void io_subchannel_recog_done(struct ccw_device *cdev);
int ccw_device_cancel_halt_clear(struct ccw_device *);
-int ccw_device_register(struct ccw_device *);
void ccw_device_do_unreg_rereg(void *);
void ccw_device_call_sch_unregister(void *);
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index c5ccd20b110..79d89c36891 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -739,11 +739,16 @@ static void ap_scan_bus(void *data)
dev = bus_find_device(&ap_bus_type, NULL,
(void *)(unsigned long)qid,
__ap_scan_bus);
+ rc = ap_query_queue(qid, &queue_depth, &device_type);
+ if (dev && rc) {
+ put_device(dev);
+ device_unregister(dev);
+ continue;
+ }
if (dev) {
put_device(dev);
continue;
}
- rc = ap_query_queue(qid, &queue_depth, &device_type);
if (rc)
continue;
rc = ap_init_queue(qid);
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
index 935952ef88f..98fcbb3d556 100644
--- a/drivers/sbus/sbus.c
+++ b/drivers/sbus/sbus.c
@@ -61,11 +61,11 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde
else
sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;
sdev->ofdev.dev.bus = &sbus_bus_type;
- strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name);
+ sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node);
if (of_device_register(&sdev->ofdev) != 0)
printk(KERN_DEBUG "sbus: device registration error for %s!\n",
- sdev->ofdev.dev.bus_id);
+ dp->path_component_name);
}
static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus)
diff --git a/drivers/scsi/dpt/dpti_i2o.h b/drivers/scsi/dpt/dpti_i2o.h
index b3fa7ed71fa..5a49216fe4c 100644
--- a/drivers/scsi/dpt/dpti_i2o.h
+++ b/drivers/scsi/dpt/dpti_i2o.h
@@ -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;
/*
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 2d95ac9c32c..e31f6122106 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -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;
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index d586c3d3b0d..19c79a0549a 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -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;
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 24a1779b9af..582f5ea4e84 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -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;
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index b0eba39f208..89a2a9f11e4 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -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;
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig
index 08a07f0b8d9..69cbff3f57c 100644
--- a/drivers/scsi/qla4xxx/Kconfig
+++ b/drivers/scsi/qla4xxx/Kconfig
@@ -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
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index ff4fa25f9fd..711bd151143 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -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;
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index cf3d20eb781..40873635d80 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -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);
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index fe1488374f6..e3993213d10 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -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
diff --git a/fs/block_dev.c b/fs/block_dev.c
index bc8f27cc448..36c0e7af9d0 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -642,34 +642,47 @@ static void free_bd_holder(struct bd_holder *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);
@@ -1131,6 +1151,8 @@ static int blkdev_open(struct inode * inode, struct file * filp)
filp->f_flags |= O_LARGEFILE;
bdev = bd_acquire(inode);
+ if (bdev == NULL)
+ return -ENOMEM;
res = do_open(bdev, filp, BD_MUTEX_NORMAL);
if (res)
diff --git a/fs/dcache.c b/fs/dcache.c
index a1ff91eef10..fd4a428998e 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -478,11 +478,12 @@ static void prune_dcache(int count, struct super_block *sb)
up_read(s_umount);
}
spin_unlock(&dentry->d_lock);
- /* Cannot remove the first dentry, and it isn't appropriate
- * to move it to the head of the list, so give up, and try
- * later
+ /*
+ * Insert dentry at the head of the list as inserting at the
+ * tail leads to a cycle.
*/
- break;
+ list_add(&dentry->d_lru, &dentry_unused);
+ dentry_stat.nr_unused++;
}
spin_unlock(&dcache_lock);
}
@@ -556,6 +557,7 @@ repeat:
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
{
struct dentry *parent;
+ unsigned detached = 0;
BUG_ON(!IS_ROOT(dentry));
@@ -620,7 +622,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
atomic_dec(&parent->d_count);
list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
+ detached++;
inode = dentry->d_inode;
if (inode) {
@@ -638,7 +640,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
* otherwise we ascend to the parent and move to the
* next sibling if there is one */
if (!parent)
- return;
+ goto out;
dentry = parent;
@@ -647,6 +649,11 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
dentry = list_entry(dentry->d_subdirs.next,
struct dentry, d_u.d_child);
}
+out:
+ /* several dentries were freed, need to correct nr_dentry */
+ spin_lock(&dcache_lock);
+ dentry_stat.nr_dentry -= detached;
+ spin_unlock(&dcache_lock);
}
/*
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index ed35a9712fa..f49f105394b 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -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;
}
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
index f0d2a433242..0b9992ab990 100644
--- a/fs/ecryptfs/dentry.c
+++ b/fs/ecryptfs/dentry.c
@@ -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;
}
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 872c9958531..f992533d169 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -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 */
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index c8550c9f9cd..a92ef05eff8 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -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
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index efdd2b7b62d..ff4865d24f0 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -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,
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index ba454785a0c..c3746f56d16 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -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;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 5938a232d11..a78d87d14ba 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -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;
}
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index c337c0410fb..825757ae486 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -138,23 +138,6 @@ static void ecryptfs_clear_inode(struct inode *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
*
* Prints the directory we are currently mounted over.
@@ -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
};
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 1e9578052cd..4fe49c3661b 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -69,44 +69,49 @@ static int verify_group_input(struct super_block *sb,
else if (outside(input->block_bitmap, start, end))
ext4_warning(sb, __FUNCTION__,
"Block bitmap not in group (block %llu)",
- input->block_bitmap);
+ (unsigned long long)input->block_bitmap);
else if (outside(input->inode_bitmap, start, end))
ext4_warning(sb, __FUNCTION__,
"Inode bitmap not in group (block %llu)",
- input->inode_bitmap);
+ (unsigned long long)input->inode_bitmap);
else if (outside(input->inode_table, start, end) ||
outside(itend - 1, start, end))
ext4_warning(sb, __FUNCTION__,
"Inode table not in group (blocks %llu-%llu)",
- input->inode_table, itend - 1);
+ (unsigned long long)input->inode_table, itend - 1);
else if (input->inode_bitmap == input->block_bitmap)
ext4_warning(sb, __FUNCTION__,
"Block bitmap same as inode bitmap (%llu)",
- input->block_bitmap);
+ (unsigned long long)input->block_bitmap);
else if (inside(input->block_bitmap, input->inode_table, itend))
ext4_warning(sb, __FUNCTION__,
"Block bitmap (%llu) in inode table (%llu-%llu)",
- input->block_bitmap, input->inode_table, itend-1);
+ (unsigned long long)input->block_bitmap,
+ (unsigned long long)input->inode_table, itend - 1);
else if (inside(input->inode_bitmap, input->inode_table, itend))
ext4_warning(sb, __FUNCTION__,
"Inode bitmap (%llu) in inode table (%llu-%llu)",
- input->inode_bitmap, input->inode_table, itend-1);
+ (unsigned long long)input->inode_bitmap,
+ (unsigned long long)input->inode_table, itend - 1);
else if (inside(input->block_bitmap, start, metaend))
ext4_warning(sb, __FUNCTION__,
"Block bitmap (%llu) in GDT table"
" (%llu-%llu)",
- input->block_bitmap, start, metaend - 1);
+ (unsigned long long)input->block_bitmap,
+ start, metaend - 1);
else if (inside(input->inode_bitmap, start, metaend))
ext4_warning(sb, __FUNCTION__,
"Inode bitmap (%llu) in GDT table"
" (%llu-%llu)",
- input->inode_bitmap, start, metaend - 1);
+ (unsigned long long)input->inode_bitmap,
+ start, metaend - 1);
else if (inside(input->inode_table, start, metaend) ||
inside(itend - 1, start, metaend))
ext4_warning(sb, __FUNCTION__,
"Inode table (%llu-%llu) overlaps"
"GDT table (%llu-%llu)",
- input->inode_table, itend - 1, start, metaend - 1);
+ (unsigned long long)input->inode_table,
+ itend - 1, start, metaend - 1);
else
err = 0;
brelse(bh);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 4ee3f006b86..0bea6a619e1 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -271,26 +271,24 @@ static void hugetlbfs_drop_inode(struct inode *inode)
hugetlbfs_forget_inode(inode);
}
-/*
- * h_pgoff is in HPAGE_SIZE units.
- * vma->vm_pgoff is in PAGE_SIZE units.
- */
static inline void
-hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
+hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
{
struct vm_area_struct *vma;
struct prio_tree_iter iter;
- vma_prio_tree_foreach(vma, &iter, root, h_pgoff, ULONG_MAX) {
- unsigned long h_vm_pgoff;
+ vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) {
unsigned long v_offset;
- h_vm_pgoff = vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT);
- v_offset = (h_pgoff - h_vm_pgoff) << HPAGE_SHIFT;
/*
- * Is this VMA fully outside the truncation point?
+ * Can the expression below overflow on 32-bit arches?
+ * No, because the prio_tree returns us only those vmas
+ * which overlap the truncated area starting at pgoff,
+ * and no vma on a 32-bit arch can span beyond the 4GB.
*/
- if (h_vm_pgoff >= h_pgoff)
+ if (vma->vm_pgoff < pgoff)
+ v_offset = (pgoff - vma->vm_pgoff) << PAGE_SHIFT;
+ else
v_offset = 0;
__unmap_hugepage_range(vma,
@@ -303,14 +301,14 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, unsigned long h_pgoff)
*/
static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
{
- unsigned long pgoff;
+ pgoff_t pgoff;
struct address_space *mapping = inode->i_mapping;
if (offset > inode->i_size)
return -EINVAL;
BUG_ON(offset & ~HPAGE_MASK);
- pgoff = offset >> HPAGE_SHIFT;
+ pgoff = offset >> PAGE_SHIFT;
inode->i_size = offset;
spin_lock(&mapping->i_mmap_lock);
@@ -624,7 +622,6 @@ hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
do_div(size, 100);
rest++;
}
- size &= HPAGE_MASK;
pconfig->nr_blocks = (size >> HPAGE_SHIFT);
value = rest;
} else if (!strcmp(opt,"nr_inodes")) {
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index d5c63047a8b..4f82bcd63e4 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -967,6 +967,13 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
*/
jbd_lock_bh_state(bh);
spin_lock(&journal->j_list_lock);
+
+ /* Now that we have bh_state locked, are we really still mapped? */
+ if (!buffer_mapped(bh)) {
+ JBUFFER_TRACE(jh, "unmapped buffer, bailing out");
+ goto no_journal;
+ }
+
if (jh->b_transaction) {
JBUFFER_TRACE(jh, "has transaction");
if (jh->b_transaction != handle->h_transaction) {
@@ -1028,6 +1035,11 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
sync_dirty_buffer(bh);
jbd_lock_bh_state(bh);
spin_lock(&journal->j_list_lock);
+ /* Since we dropped the lock... */
+ if (!buffer_mapped(bh)) {
+ JBUFFER_TRACE(jh, "buffer got unmapped");
+ goto no_journal;
+ }
/* The buffer may become locked again at any
time if it is redirtied */
}
@@ -1824,6 +1836,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
}
}
} else if (transaction == journal->j_committing_transaction) {
+ JBUFFER_TRACE(jh, "on committing transaction");
if (jh->b_jlist == BJ_Locked) {
/*
* The buffer is on the committing transaction's locked
@@ -1838,7 +1851,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* can remove it's next_transaction pointer from the
* running transaction if that is set, but nothing
* else. */
- JBUFFER_TRACE(jh, "on committing transaction");
set_buffer_freed(bh);
if (jh->b_next_transaction) {
J_ASSERT(jh->b_next_transaction ==
@@ -1858,6 +1870,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* i_size already for this truncate so recovery will not
* expose the disk blocks we are discarding here.) */
J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
+ JBUFFER_TRACE(jh, "on running transaction");
may_free = __dispose_buffer(jh, transaction);
}
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index b6cf2be845a..c051a94c8a9 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -967,6 +967,13 @@ int jbd2_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
*/
jbd_lock_bh_state(bh);
spin_lock(&journal->j_list_lock);
+
+ /* Now that we have bh_state locked, are we really still mapped? */
+ if (!buffer_mapped(bh)) {
+ JBUFFER_TRACE(jh, "unmapped buffer, bailing out");
+ goto no_journal;
+ }
+
if (jh->b_transaction) {
JBUFFER_TRACE(jh, "has transaction");
if (jh->b_transaction != handle->h_transaction) {
@@ -1028,6 +1035,11 @@ int jbd2_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
sync_dirty_buffer(bh);
jbd_lock_bh_state(bh);
spin_lock(&journal->j_list_lock);
+ /* Since we dropped the lock... */
+ if (!buffer_mapped(bh)) {
+ JBUFFER_TRACE(jh, "buffer got unmapped");
+ goto no_journal;
+ }
/* The buffer may become locked again at any
time if it is redirtied */
}
@@ -1824,6 +1836,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
}
}
} else if (transaction == journal->j_committing_transaction) {
+ JBUFFER_TRACE(jh, "on committing transaction");
if (jh->b_jlist == BJ_Locked) {
/*
* The buffer is on the committing transaction's locked
@@ -1838,7 +1851,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* can remove it's next_transaction pointer from the
* running transaction if that is set, but nothing
* else. */
- JBUFFER_TRACE(jh, "on committing transaction");
set_buffer_freed(bh);
if (jh->b_next_transaction) {
J_ASSERT(jh->b_next_transaction ==
@@ -1858,6 +1870,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
* i_size already for this truncate so recovery will not
* expose the disk blocks we are discarding here.) */
J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
+ JBUFFER_TRACE(jh, "on running transaction");
may_free = __dispose_buffer(jh, transaction);
}
diff --git a/fs/splice.c b/fs/splice.c
index 49fb9f12993..8d705954d29 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -74,7 +74,7 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *pipe,
wait_on_page_writeback(page);
if (PagePrivate(page))
- try_to_release_page(page, mapping_gfp_mask(mapping));
+ try_to_release_page(page, GFP_KERNEL);
/*
* If we succeeded in removing the mapping, set LRU flag
@@ -333,7 +333,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
break;
error = add_to_page_cache_lru(page, mapping, index,
- mapping_gfp_mask(mapping));
+ GFP_KERNEL);
if (unlikely(error)) {
page_cache_release(page);
if (error == -EEXIST)
@@ -557,7 +557,6 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
{
struct file *file = sd->file;
struct address_space *mapping = file->f_mapping;
- gfp_t gfp_mask = mapping_gfp_mask(mapping);
unsigned int offset, this_len;
struct page *page;
pgoff_t index;
@@ -591,7 +590,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
goto find_page;
page = buf->page;
- if (add_to_page_cache(page, mapping, index, gfp_mask)) {
+ if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) {
unlock_page(page);
goto find_page;
}
@@ -613,7 +612,7 @@ find_page:
* This will also lock the page
*/
ret = add_to_page_cache_lru(page, mapping, index,
- gfp_mask);
+ GFP_KERNEL);
if (unlikely(ret))
goto out;
}
diff --git a/include/asm-arm/uaccess.h b/include/asm-arm/uaccess.h
index 09ad0cab901..5f420a0149f 100644
--- a/include/asm-arm/uaccess.h
+++ b/include/asm-arm/uaccess.h
@@ -383,19 +383,19 @@ do { \
#ifdef CONFIG_MMU
-extern unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n);
-extern unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n);
-extern unsigned long __clear_user(void __user *addr, unsigned long n);
+extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
+extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
+extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
#else
#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0)
#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0)
#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0)
#endif
-extern unsigned long __strncpy_from_user(char *to, const char __user *from, unsigned long count);
-extern unsigned long __strnlen_user(const char __user *s, long n);
+extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count);
+extern unsigned long __must_check __strnlen_user(const char __user *s, long n);
-static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
+static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n);
@@ -404,7 +404,7 @@ static inline unsigned long copy_from_user(void *to, const void __user *from, un
return n;
}
-static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
+static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
n = __copy_to_user(to, from, n);
@@ -414,14 +414,14 @@ static inline unsigned long copy_to_user(void __user *to, const void *from, unsi
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
-static inline unsigned long clear_user(void __user *to, unsigned long n)
+static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
{
if (access_ok(VERIFY_WRITE, to, n))
n = __clear_user(to, n);
return n;
}
-static inline long strncpy_from_user(char *dst, const char __user *src, long count)
+static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count)
{
long res = -EFAULT;
if (access_ok(VERIFY_READ, src, 1))
@@ -431,7 +431,7 @@ static inline long strncpy_from_user(char *dst, const char __user *src, long cou
#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
-static inline long strnlen_user(const char __user *s, long n)
+static inline long __must_check strnlen_user(const char __user *s, long n)
{
unsigned long res = 0;
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 9d0d11c180d..9d873163a7a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -213,3 +213,20 @@
#define NOTES \
.notes : { *(.note.*) } :note
+
+#define INITCALLS \
+ *(.initcall1.init) \
+ *(.initcall1s.init) \
+ *(.initcall2.init) \
+ *(.initcall2s.init) \
+ *(.initcall3.init) \
+ *(.initcall3s.init) \
+ *(.initcall4.init) \
+ *(.initcall4s.init) \
+ *(.initcall5.init) \
+ *(.initcall5s.init) \
+ *(.initcall6.init) \
+ *(.initcall6s.init) \
+ *(.initcall7.init) \
+ *(.initcall7s.init)
+
diff --git a/include/asm-i386/mach-visws/do_timer.h b/include/asm-i386/mach-visws/do_timer.h
deleted file mode 100644
index 21cd696d4d0..00000000000
--- a/include/asm-i386/mach-visws/do_timer.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* defines for inline arch setup functions */
-
-#include <asm/fixmap.h>
-#include <asm/i8259.h>
-#include "cobalt.h"
-
-static inline void do_timer_interrupt_hook(void)
-{
- /* Clear the interrupt */
- co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR);
-
- do_timer(1);
-#ifndef CONFIG_SMP
- update_process_times(user_mode_vm(irq_regs));
-#endif
-/*
- * In the SMP case we use the local APIC timer interrupt to do the
- * profiling, except when we simulate SMP mode on a uniprocessor
- * system, in that case we have to call the local interrupt handler.
- */
-#ifndef CONFIG_X86_LOCAL_APIC
- profile_tick(CPU_PROFILING);
-#else
- if (!using_apic_timer)
- smp_local_timer_interrupt();
-#endif
-}
-
-static inline int do_timer_overflow(int count)
-{
- int i;
-
- spin_lock(&i8259A_lock);
- /*
- * This is tricky when I/O APICs are used;
- * see do_timer_interrupt().
- */
- i = inb(0x20);
- spin_unlock(&i8259A_lock);
-
- /* assumption about timer being IRQ0 */
- if (i & 0x01) {
- /*
- * We cannot detect lost timer interrupts ...
- * well, that's why we call them lost, don't we? :)
- * [hmm, on the Pentium and Alpha we can ... sort of]
- */
- count -= LATCH;
- } else {
- printk("do_slow_gettimeoffset(): hardware timer problem?\n");
- }
- return count;
-}
diff --git a/include/asm-i386/mach-visws/mach_apic.h b/include/asm-i386/mach-visws/mach_apic.h
index de438c7147a..18afe6b6fc4 100644
--- a/include/asm-i386/mach-visws/mach_apic.h
+++ b/include/asm-i386/mach-visws/mach_apic.h
@@ -51,6 +51,11 @@ static inline void clustered_apic_check(void)
{
}
+static inline int apicid_to_node(int logical_apicid)
+{
+ return 0;
+}
+
/* Mapping from cpu number to logical apicid */
static inline int cpu_to_logical_apicid(int cpu)
{
diff --git a/include/asm-mips/div64.h b/include/asm-mips/div64.h
index 5f7dcf5452e..d107832de1b 100644
--- a/include/asm-mips/div64.h
+++ b/include/asm-mips/div64.h
@@ -83,27 +83,6 @@
#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..
*/
diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h
index f637ce70758..3e9468f424f 100644
--- a/include/asm-mips/mipsmtregs.h
+++ b/include/asm-mips/mipsmtregs.h
@@ -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)
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index b09e16c93ca..2ba6988ddc8 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -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);
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index 28512ba2266..625acd337bc 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -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).
@@ -58,13 +59,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.
*/
extern irqreturn_t timer_interrupt(int irq, void *dev_id);
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h
index 30240a445db..ec56aa52f66 100644
--- a/include/asm-mips/unistd.h
+++ b/include/asm-mips/unistd.h
@@ -332,16 +332,18 @@
#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
@@ -620,16 +622,18 @@
#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
@@ -912,16 +916,18 @@
#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
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 7596ab83e0d..6cd3e9e2a76 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -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)
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h
index f1a0cbc966b..1c2abde122c 100644
--- a/include/asm-sh/unistd.h
+++ b/include/asm-sh/unistd.h
@@ -324,8 +324,11 @@
#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__
diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
index 1010153faaf..f0454516dd3 100644
--- a/include/asm-um/common.lds.S
+++ b/include/asm-um/common.lds.S
@@ -42,13 +42,7 @@
__initcall_start = .;
.initcall.init : {
- *(.initcall1.init)
- *(.initcall2.init)
- *(.initcall3.init)
- *(.initcall4.init)
- *(.initcall5.init)
- *(.initcall6.init)
- *(.initcall7.init)
+ INITCALLS
}
__initcall_end = .;
diff --git a/include/linux/compat.h b/include/linux/compat.h
index f4ebf96f530..f1553196826 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -196,7 +196,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
#define BITS_TO_COMPAT_LONGS(bits) \
(((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG)
-long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
unsigned long bitmap_size);
long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
unsigned long bitmap_size);
diff --git a/include/linux/init.h b/include/linux/init.h
index e92b1455d7a..ff40ea118e3 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -84,19 +84,29 @@ extern void setup_arch(char **);
* by link order.
* For backwards compatibility, initcall() puts the call in
* the device init subsection.
+ *
+ * The `id' arg to __define_initcall() is needed so that multiple initcalls
+ * can point at the same handler without causing duplicate-symbol build errors.
*/
-#define __define_initcall(level,fn) \
- static initcall_t __initcall_##fn __attribute_used__ \
+#define __define_initcall(level,fn,id) \
+ static initcall_t __initcall_##fn##id __attribute_used__ \
__attribute__((__section__(".initcall" level ".init"))) = fn
-#define core_initcall(fn) __define_initcall("1",fn)
-#define postcore_initcall(fn) __define_initcall("2",fn)
-#define arch_initcall(fn) __define_initcall("3",fn)
-#define subsys_initcall(fn) __define_initcall("4",fn)
-#define fs_initcall(fn) __define_initcall("5",fn)
-#define device_initcall(fn) __define_initcall("6",fn)
-#define late_initcall(fn) __define_initcall("7",fn)
+#define core_initcall(fn) __define_initcall("1",fn,1)
+#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
+#define postcore_initcall(fn) __define_initcall("2",fn,2)
+#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
+#define arch_initcall(fn) __define_initcall("3",fn,3)
+#define arch_initcall_sync(fn) __define_initcall("3s",fn,3s)
+#define subsys_initcall(fn) __define_initcall("4",fn,4)
+#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
+#define fs_initcall(fn) __define_initcall("5",fn,5)
+#define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
+#define device_initcall(fn) __define_initcall("6",fn,6)
+#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
+#define late_initcall(fn) __define_initcall("7",fn,7)
+#define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
#define __initcall(fn) device_initcall(fn)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ed0762b283a..e06683e2bea 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -218,13 +218,9 @@ struct zone {
* under - it drives the swappiness decision: whether to unmap mapped
* pages.
*
- * temp_priority is used to remember the scanning priority at which
- * this zone was successfully refilled to free_pages == pages_high.
- *
- * Access to both these fields is quite racy even on uniprocessor. But
+ * Access to both this field is quite racy even on uniprocessor. But
* it is expected to average out OK.
*/
- int temp_priority;
int prev_priority;
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 70420bbae82..8b3ef418721 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -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 {
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 64f95092515..c3e255bf859 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -52,19 +52,23 @@ static inline void mapping_set_gfp_mask(struct address_space *m, gfp_t mask)
void release_pages(struct page **pages, int nr, int cold);
#ifdef CONFIG_NUMA
-extern struct page *page_cache_alloc(struct address_space *x);
-extern struct page *page_cache_alloc_cold(struct address_space *x);
+extern struct page *__page_cache_alloc(gfp_t gfp);
#else
+static inline struct page *__page_cache_alloc(gfp_t gfp)
+{
+ return alloc_pages(gfp, 0);
+}
+#endif
+
static inline struct page *page_cache_alloc(struct address_space *x)
{
- return alloc_pages(mapping_gfp_mask(x), 0);
+ return __page_cache_alloc(mapping_gfp_mask(x));
}
static inline struct page *page_cache_alloc_cold(struct address_space *x)
{
- return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
+ return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD);
}
-#endif
typedef int filler_t(void *, struct page *);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6735c1cf334..eafe4a7b823 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -466,7 +466,6 @@ struct signal_struct {
struct pacct_struct pacct; /* per-process accounting information */
#endif
#ifdef CONFIG_TASKSTATS
- spinlock_t stats_lock;
struct taskstats *stats;
#endif
};
diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h
index 16894b7edcc..6562a2050a2 100644
--- a/include/linux/taskstats_kern.h
+++ b/include/linux/taskstats_kern.h
@@ -23,25 +23,26 @@ static inline void taskstats_exit_free(struct taskstats *tidstats)
static inline void taskstats_tgid_init(struct signal_struct *sig)
{
- spin_lock_init(&sig->stats_lock);
sig->stats = NULL;
}
-static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+static inline void taskstats_tgid_alloc(struct task_struct *tsk)
{
+ struct signal_struct *sig = tsk->signal;
struct taskstats *stats;
- unsigned long flags;
- stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
- if (!stats)
+ if (sig->stats != NULL)
return;
- spin_lock_irqsave(&sig->stats_lock, flags);
+ /* No problem if kmem_cache_zalloc() fails */
+ stats = kmem_cache_zalloc(taskstats_cache, SLAB_KERNEL);
+
+ spin_lock_irq(&tsk->sighand->siglock);
if (!sig->stats) {
sig->stats = stats;
stats = NULL;
}
- spin_unlock_irqrestore(&sig->stats_lock, flags);
+ spin_unlock_irq(&tsk->sighand->siglock);
if (stats)
kmem_cache_free(taskstats_cache, stats);
@@ -49,23 +50,13 @@ static inline void taskstats_tgid_alloc(struct signal_struct *sig)
static inline void taskstats_tgid_free(struct signal_struct *sig)
{
- struct taskstats *stats = NULL;
- unsigned long flags;
-
- spin_lock_irqsave(&sig->stats_lock, flags);
- if (sig->stats) {
- stats = sig->stats;
- sig->stats = NULL;
- }
- spin_unlock_irqrestore(&sig->stats_lock, flags);
- if (stats)
- kmem_cache_free(taskstats_cache, stats);
+ if (sig->stats)
+ kmem_cache_free(taskstats_cache, sig->stats);
}
extern void taskstats_exit_alloc(struct taskstats **, unsigned int *);
extern void taskstats_exit_send(struct task_struct *, struct taskstats *, int, unsigned int);
extern void taskstats_init_early(void);
-extern void taskstats_tgid_alloc(struct signal_struct *);
#else
static inline void taskstats_exit_alloc(struct taskstats **ptidstats, unsigned int *mycpu)
{}
@@ -77,7 +68,7 @@ static inline void taskstats_exit_send(struct task_struct *tsk,
{}
static inline void taskstats_tgid_init(struct signal_struct *sig)
{}
-static inline void taskstats_tgid_alloc(struct signal_struct *sig)
+static inline void taskstats_tgid_alloc(struct task_struct *tsk)
{}
static inline void taskstats_tgid_free(struct signal_struct *sig)
{}
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index ce5f1482e6b..dc9a29d84ab 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -60,7 +60,8 @@ extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end);
extern struct vm_struct *get_vm_area_node(unsigned long size,
- unsigned long flags, int node);
+ unsigned long flags, int node,
+ gfp_t gfp_mask);
extern struct vm_struct *remove_vm_area(void *addr);
extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
struct page ***pages);
diff --git a/include/linux/wait.h b/include/linux/wait.h
index b3b9048421d..e820d00e138 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -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;
diff --git a/kernel/compat.c b/kernel/compat.c
index 75573e5d27b..d4898aad6cf 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -678,7 +678,7 @@ int get_compat_sigevent(struct sigevent *event,
? -EFAULT : 0;
}
-long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
unsigned long bitmap_size)
{
int i, j;
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 27dd3ee4709..663c920b223 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -150,18 +150,18 @@ static int _cpu_down(unsigned int cpu)
p = __stop_machine_run(take_cpu_down, NULL, cpu);
mutex_unlock(&cpu_bitmask_lock);
- if (IS_ERR(p)) {
+ if (IS_ERR(p) || cpu_online(cpu)) {
/* CPU didn't die: tell everyone. Can't complain. */
if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED,
(void *)(long)cpu) == NOTIFY_BAD)
BUG();
- err = PTR_ERR(p);
- goto out_allowed;
- }
-
- if (cpu_online(cpu))
+ if (IS_ERR(p)) {
+ err = PTR_ERR(p);
+ goto out_allowed;
+ }
goto out_thread;
+ }
/* Wait for it to sleep (leaving idle task). */
while (!idle_cpu(cpu))
diff --git a/kernel/exit.c b/kernel/exit.c
index f250a5e3e28..06de6c4e8ca 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -128,6 +128,7 @@ static void __exit_signal(struct task_struct *tsk)
flush_sigqueue(&tsk->pending);
if (sig) {
flush_sigqueue(&sig->shared_pending);
+ taskstats_tgid_free(sig);
__cleanup_signal(sig);
}
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 29ebb30850e..3da978eec79 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -830,7 +830,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
if (clone_flags & CLONE_THREAD) {
atomic_inc(&current->signal->count);
atomic_inc(&current->signal->live);
- taskstats_tgid_alloc(current->signal);
+ taskstats_tgid_alloc(current);
return 0;
}
sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
@@ -897,7 +897,6 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
void __cleanup_signal(struct signal_struct *sig)
{
exit_thread_group_keys(sig);
- taskstats_tgid_free(sig);
kmem_cache_free(signal_cachep, sig);
}
diff --git a/kernel/module.c b/kernel/module.c
index 67009bd56c5..f0166563c60 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1342,7 +1342,7 @@ static void set_license(struct module *mod, const char *license)
if (!license_is_gpl_compatible(license)) {
if (!(tainted & TAINT_PROPRIETARY_MODULE))
- printk(KERN_WARNING "%s: module license '%s' taints"
+ printk(KERN_WARNING "%s: module license '%s' taints "
"kernel.\n", mod->name, license);
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
}
@@ -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);
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 5d6a8c54ee8..f45c5e70773 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -77,7 +77,8 @@ static int prepare_reply(struct genl_info *info, u8 cmd, struct sk_buff **skbp,
/*
* If new attributes are added, please revisit this allocation
*/
- skb = nlmsg_new(genlmsg_total_size(size), GFP_KERNEL);
+ size = nlmsg_total_size(genlmsg_total_size(size));
+ skb = nlmsg_new(size, GFP_KERNEL);
if (!skb)
return -ENOMEM;
@@ -174,21 +175,19 @@ static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu)
up_write(&listeners->sem);
}
-static int fill_pid(pid_t pid, struct task_struct *pidtsk,
+static int fill_pid(pid_t pid, struct task_struct *tsk,
struct taskstats *stats)
{
int rc = 0;
- struct task_struct *tsk = pidtsk;
- if (!pidtsk) {
- read_lock(&tasklist_lock);
+ if (!tsk) {
+ rcu_read_lock();
tsk = find_task_by_pid(pid);
- if (!tsk) {
- read_unlock(&tasklist_lock);
+ if (tsk)
+ get_task_struct(tsk);
+ rcu_read_unlock();
+ if (!tsk)
return -ESRCH;
- }
- get_task_struct(tsk);
- read_unlock(&tasklist_lock);
} else
get_task_struct(tsk);
@@ -214,39 +213,30 @@ static int fill_pid(pid_t pid, struct task_struct *pidtsk,
}
-static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
+static int fill_tgid(pid_t tgid, struct task_struct *first,
struct taskstats *stats)
{
- struct task_struct *tsk, *first;
+ struct task_struct *tsk;
unsigned long flags;
+ int rc = -ESRCH;
/*
* Add additional stats from live tasks except zombie thread group
* leaders who are already counted with the dead tasks
*/
- first = tgidtsk;
- if (!first) {
- read_lock(&tasklist_lock);
+ rcu_read_lock();
+ if (!first)
first = find_task_by_pid(tgid);
- if (!first) {
- read_unlock(&tasklist_lock);
- return -ESRCH;
- }
- get_task_struct(first);
- read_unlock(&tasklist_lock);
- } else
- get_task_struct(first);
- /* Start with stats from dead tasks */
- spin_lock_irqsave(&first->signal->stats_lock, flags);
+ if (!first || !lock_task_sighand(first, &flags))
+ goto out;
+
if (first->signal->stats)
memcpy(stats, first->signal->stats, sizeof(*stats));
- spin_unlock_irqrestore(&first->signal->stats_lock, flags);
tsk = first;
- read_lock(&tasklist_lock);
do {
- if (tsk->exit_state == EXIT_ZOMBIE && thread_group_leader(tsk))
+ if (tsk->exit_state)
continue;
/*
* Accounting subsystem can call its functions here to
@@ -257,15 +247,18 @@ static int fill_tgid(pid_t tgid, struct task_struct *tgidtsk,
delayacct_add_tsk(stats, tsk);
} while_each_thread(first, tsk);
- read_unlock(&tasklist_lock);
- stats->version = TASKSTATS_VERSION;
+ unlock_task_sighand(first, &flags);
+ rc = 0;
+out:
+ rcu_read_unlock();
+
+ stats->version = TASKSTATS_VERSION;
/*
* Accounting subsytems can also add calls here to modify
* fields of taskstats.
*/
-
- return 0;
+ return rc;
}
@@ -273,7 +266,7 @@ static void fill_tgid_exit(struct task_struct *tsk)
{
unsigned long flags;
- spin_lock_irqsave(&tsk->signal->stats_lock, flags);
+ spin_lock_irqsave(&tsk->sighand->siglock, flags);
if (!tsk->signal->stats)
goto ret;
@@ -285,7 +278,7 @@ static void fill_tgid_exit(struct task_struct *tsk)
*/
delayacct_add_tsk(tsk->signal->stats, tsk);
ret:
- spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
+ spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
return;
}
@@ -419,7 +412,7 @@ static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
return send_reply(rep_skb, info->snd_pid);
nla_put_failure:
- return genlmsg_cancel(rep_skb, reply);
+ rc = genlmsg_cancel(rep_skb, reply);
err:
nlmsg_free(rep_skb);
return rc;
@@ -461,24 +454,26 @@ void taskstats_exit_send(struct task_struct *tsk, struct taskstats *tidstats,
size_t size;
int is_thread_group;
struct nlattr *na;
- unsigned long flags;
- if (!family_registered || !tidstats)
+ if (!family_registered)
return;
- spin_lock_irqsave(&tsk->signal->stats_lock, flags);
- is_thread_group = tsk->signal->stats ? 1 : 0;
- spin_unlock_irqrestore(&tsk->signal->stats_lock, flags);
-
- rc = 0;
/*
* Size includes space for nested attributes
*/
size = nla_total_size(sizeof(u32)) +
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
- if (is_thread_group)
- size = 2 * size; /* PID + STATS + TGID + STATS */
+ is_thread_group = (tsk->signal->stats != NULL);
+ 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)
@@ -498,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;
@@ -519,7 +511,6 @@ send:
nla_put_failure:
genlmsg_cancel(rep_skb, reply);
- goto ret;
err_skb:
nlmsg_free(rep_skb);
ret:
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 47195fa0ec4..3afeaa3a73f 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -161,9 +161,9 @@ void second_overflow(void)
time_adjust += MAX_TICKADJ;
tick_length -= MAX_TICKADJ_SCALED;
} else {
- time_adjust = 0;
tick_length += (s64)(time_adjust * NSEC_PER_USEC /
HZ) << TICK_LENGTH_SHIFT;
+ time_adjust = 0;
}
}
}
diff --git a/kernel/tsacct.c b/kernel/tsacct.c
index db443221ba5..96f77013d3f 100644
--- a/kernel/tsacct.c
+++ b/kernel/tsacct.c
@@ -36,7 +36,7 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
/* calculate task elapsed time in timespec */
do_posix_clock_monotonic_gettime(&uptime);
- ts = timespec_sub(uptime, current->group_leader->start_time);
+ ts = timespec_sub(uptime, tsk->start_time);
/* rebase elapsed time to usec */
ac_etime = timespec_to_ns(&ts);
do_div(ac_etime, NSEC_PER_USEC);
@@ -58,7 +58,10 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk)
stats->ac_uid = tsk->uid;
stats->ac_gid = tsk->gid;
stats->ac_pid = tsk->pid;
- stats->ac_ppid = (tsk->parent) ? tsk->parent->pid : 0;
+ rcu_read_lock();
+ stats->ac_ppid = pid_alive(tsk) ?
+ rcu_dereference(tsk->real_parent)->tgid : 0;
+ rcu_read_unlock();
stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC;
stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC;
stats->ac_minflt = tsk->min_flt;
@@ -77,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;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 3df9bfc7ff7..17c2f03d2c2 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -99,7 +99,7 @@ static void __queue_work(struct cpu_workqueue_struct *cwq,
* @wq: workqueue to use
* @work: work to queue
*
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
*
* We queue the work to the CPU it was submitted, but there is no
* guarantee that it will be processed by that CPU.
@@ -138,7 +138,7 @@ static void delayed_work_timer_fn(unsigned long __data)
* @work: work to queue
* @delay: number of jiffies to wait before queueing
*
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
*/
int fastcall queue_delayed_work(struct workqueue_struct *wq,
struct work_struct *work, unsigned long delay)
@@ -169,7 +169,7 @@ EXPORT_SYMBOL_GPL(queue_delayed_work);
* @work: work to queue
* @delay: number of jiffies to wait before queueing
*
- * Returns non-zero if it was successfully added.
+ * Returns 0 if @work was already on a queue, non-zero otherwise.
*/
int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
struct work_struct *work, unsigned long delay)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 77491e31179..d3679103a8e 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -341,7 +341,7 @@ config FRAME_POINTER
config UNWIND_INFO
bool "Compile the kernel with frame unwind information"
- depends on !IA64 && !PARISC
+ depends on !IA64 && !PARISC && !ARM
depends on !MODULES || !(MIPS || PPC || SUPERH || V850)
help
If you say Y here the resulting kernel image will be slightly larger
diff --git a/lib/string.c b/lib/string.c
index 63077267367..a485d75962a 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -320,7 +320,7 @@ char *strstrip(char *s)
return s;
end = s + size - 1;
- while (end != s && isspace(*end))
+ while (end >= s && isspace(*end))
end--;
*(end + 1) = '\0';
diff --git a/mm/filemap.c b/mm/filemap.c
index cb26e33fd0f..7b84dc81434 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -467,25 +467,15 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
}
#ifdef CONFIG_NUMA
-struct page *page_cache_alloc(struct address_space *x)
+struct page *__page_cache_alloc(gfp_t gfp)
{
if (cpuset_do_page_mem_spread()) {
int n = cpuset_mem_spread_node();
- return alloc_pages_node(n, mapping_gfp_mask(x), 0);
+ return alloc_pages_node(n, gfp, 0);
}
- return alloc_pages(mapping_gfp_mask(x), 0);
+ return alloc_pages(gfp, 0);
}
-EXPORT_SYMBOL(page_cache_alloc);
-
-struct page *page_cache_alloc_cold(struct address_space *x)
-{
- if (cpuset_do_page_mem_spread()) {
- int n = cpuset_mem_spread_node();
- return alloc_pages_node(n, mapping_gfp_mask(x)|__GFP_COLD, 0);
- }
- return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0);
-}
-EXPORT_SYMBOL(page_cache_alloc_cold);
+EXPORT_SYMBOL(__page_cache_alloc);
#endif
static int __sleep_on_page_lock(void *word)
@@ -826,7 +816,6 @@ struct page *
grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
{
struct page *page = find_get_page(mapping, index);
- gfp_t gfp_mask;
if (page) {
if (!TestSetPageLocked(page))
@@ -834,9 +823,8 @@ grab_cache_page_nowait(struct address_space *mapping, unsigned long index)
page_cache_release(page);
return NULL;
}
- gfp_mask = mapping_gfp_mask(mapping) & ~__GFP_FS;
- page = alloc_pages(gfp_mask, 0);
- if (page && add_to_page_cache_lru(page, mapping, index, gfp_mask)) {
+ page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~__GFP_FS);
+ if (page && add_to_page_cache_lru(page, mapping, index, GFP_KERNEL)) {
page_cache_release(page);
page = NULL;
}
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 2dbec90dc3b..a088f593a80 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -478,6 +478,9 @@ int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
retry:
page = find_lock_page(mapping, idx);
if (!page) {
+ size = i_size_read(mapping->host) >> HPAGE_SHIFT;
+ if (idx >= size)
+ goto out;
if (hugetlb_get_quota(mapping))
goto out;
page = alloc_huge_page(vma, address);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f5fc45472d5..b55bb358b83 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2261,7 +2261,7 @@ unsigned long __init __absent_pages_in_range(int nid,
/* Account for ranges past physical memory on this node */
if (range_end_pfn > prev_end_pfn)
- hole_pages = range_end_pfn -
+ hole_pages += range_end_pfn -
max(range_start_pfn, prev_end_pfn);
return hole_pages;
@@ -2407,7 +2407,7 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
zone->zone_pgdat = pgdat;
zone->free_pages = 0;
- zone->temp_priority = zone->prev_priority = DEF_PRIORITY;
+ zone->prev_priority = DEF_PRIORITY;
zone_pcp_init(zone);
INIT_LIST_HEAD(&zone->active_list);
diff --git a/mm/sparse.c b/mm/sparse.c
index 86c52ab8087..b3c82ba3001 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -211,7 +211,7 @@ static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
struct page *page, *ret;
unsigned long memmap_size = sizeof(struct page) * nr_pages;
- page = alloc_pages(GFP_KERNEL, get_order(memmap_size));
+ page = alloc_pages(GFP_KERNEL|__GFP_NOWARN, get_order(memmap_size));
if (page)
goto got_map_page;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1133dd3aafc..46606c133e8 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -160,13 +160,15 @@ int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
return err;
}
-struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
- unsigned long start, unsigned long end, int node)
+static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
+ unsigned long start, unsigned long end,
+ int node, gfp_t gfp_mask)
{
struct vm_struct **p, *tmp, *area;
unsigned long align = 1;
unsigned long addr;
+ BUG_ON(in_interrupt());
if (flags & VM_IOREMAP) {
int bit = fls(size);
@@ -180,7 +182,7 @@ struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long flags,
addr = ALIGN(start, align);
size = PAGE_ALIGN(size);
- area = kmalloc_node(sizeof(*area), GFP_KERNEL, node);
+ area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node);
if (unlikely(!area))
return NULL;
@@ -236,7 +238,7 @@ out:
struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
unsigned long start, unsigned long end)
{
- return __get_vm_area_node(size, flags, start, end, -1);
+ return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL);
}
/**
@@ -253,9 +255,11 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END);
}
-struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, int node)
+struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags,
+ int node, gfp_t gfp_mask)
{
- return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node);
+ return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node,
+ gfp_mask);
}
/* Caller must hold vmlist_lock */
@@ -487,7 +491,7 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
if (!size || (size >> PAGE_SHIFT) > num_physpages)
return NULL;
- area = get_vm_area_node(size, VM_ALLOC, node);
+ area = get_vm_area_node(size, VM_ALLOC, node, gfp_mask);
if (!area)
return NULL;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f05527bf792..518540a4a2a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -723,6 +723,20 @@ done:
return nr_reclaimed;
}
+/*
+ * We are about to scan this zone at a certain priority level. If that priority
+ * level is smaller (ie: more urgent) than the previous priority, then note
+ * that priority level within the zone. This is done so that when the next
+ * process comes in to scan this zone, it will immediately start out at this
+ * priority level rather than having to build up its own scanning priority.
+ * Here, this priority affects only the reclaim-mapped threshold.
+ */
+static inline void note_zone_scanning_priority(struct zone *zone, int priority)
+{
+ if (priority < zone->prev_priority)
+ zone->prev_priority = priority;
+}
+
static inline int zone_is_near_oom(struct zone *zone)
{
return zone->pages_scanned >= (zone->nr_active + zone->nr_inactive)*3;
@@ -746,7 +760,7 @@ static inline int zone_is_near_oom(struct zone *zone)
* But we had to alter page->flags anyway.
*/
static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
- struct scan_control *sc)
+ struct scan_control *sc, int priority)
{
unsigned long pgmoved;
int pgdeactivate = 0;
@@ -770,7 +784,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
* `distress' is a measure of how much trouble we're having
* reclaiming pages. 0 -> no problems. 100 -> great trouble.
*/
- distress = 100 >> zone->prev_priority;
+ distress = 100 >> min(zone->prev_priority, priority);
/*
* The point of this algorithm is to decide when to start
@@ -922,7 +936,7 @@ static unsigned long shrink_zone(int priority, struct zone *zone,
nr_to_scan = min(nr_active,
(unsigned long)sc->swap_cluster_max);
nr_active -= nr_to_scan;
- shrink_active_list(nr_to_scan, zone, sc);
+ shrink_active_list(nr_to_scan, zone, sc, priority);
}
if (nr_inactive) {
@@ -972,9 +986,7 @@ static unsigned long shrink_zones(int priority, struct zone **zones,
if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
continue;
- zone->temp_priority = priority;
- if (zone->prev_priority > priority)
- zone->prev_priority = priority;
+ note_zone_scanning_priority(zone, priority);
if (zone->all_unreclaimable && priority != DEF_PRIORITY)
continue; /* Let kswapd poll it */
@@ -1024,7 +1036,6 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
continue;
- zone->temp_priority = DEF_PRIORITY;
lru_pages += zone->nr_active + zone->nr_inactive;
}
@@ -1065,13 +1076,22 @@ unsigned long try_to_free_pages(struct zone **zones, gfp_t gfp_mask)
if (!sc.all_unreclaimable)
ret = 1;
out:
+ /*
+ * Now that we've scanned all the zones at this priority level, note
+ * that level within the zone so that the next thread which performs
+ * scanning of this zone will immediately start out at this priority
+ * level. This affects only the decision whether or not to bring
+ * mapped pages onto the inactive list.
+ */
+ if (priority < 0)
+ priority = 0;
for (i = 0; zones[i] != 0; i++) {
struct zone *zone = zones[i];
if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
continue;
- zone->prev_priority = zone->temp_priority;
+ zone->prev_priority = priority;
}
return ret;
}
@@ -1111,6 +1131,11 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order)
.swap_cluster_max = SWAP_CLUSTER_MAX,
.swappiness = vm_swappiness,
};
+ /*
+ * temp_priority is used to remember the scanning priority at which
+ * this zone was successfully refilled to free_pages == pages_high.
+ */
+ int temp_priority[MAX_NR_ZONES];
loop_again:
total_scanned = 0;
@@ -1118,11 +1143,8 @@ loop_again:
sc.may_writepage = !laptop_mode;
count_vm_event(PAGEOUTRUN);
- for (i = 0; i < pgdat->nr_zones; i++) {
- struct zone *zone = pgdat->node_zones + i;
-
- zone->temp_priority = DEF_PRIORITY;
- }
+ for (i = 0; i < pgdat->nr_zones; i++)
+ temp_priority[i] = DEF_PRIORITY;
for (priority = DEF_PRIORITY; priority >= 0; priority--) {
int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */
@@ -1183,10 +1205,9 @@ scan:
if (!zone_watermark_ok(zone, order, zone->pages_high,
end_zone, 0))
all_zones_ok = 0;
- zone->temp_priority = priority;
- if (zone->prev_priority > priority)
- zone->prev_priority = priority;
+ temp_priority[i] = priority;
sc.nr_scanned = 0;
+ note_zone_scanning_priority(zone, priority);
nr_reclaimed += shrink_zone(priority, zone, &sc);
reclaim_state->reclaimed_slab = 0;
nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
@@ -1226,10 +1247,15 @@ scan:
break;
}
out:
+ /*
+ * Note within each zone the priority level at which this zone was
+ * brought into a happy state. So that the next thread which scans this
+ * zone will start out at that priority level.
+ */
for (i = 0; i < pgdat->nr_zones; i++) {
struct zone *zone = pgdat->node_zones + i;
- zone->prev_priority = zone->temp_priority;
+ zone->prev_priority = temp_priority[i];
}
if (!all_zones_ok) {
cond_resched();
@@ -1358,7 +1384,7 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int pass,
if (zone->nr_scan_active >= nr_pages || pass > 3) {
zone->nr_scan_active = 0;
nr_to_scan = min(nr_pages, zone->nr_active);
- shrink_active_list(nr_to_scan, zone, sc);
+ shrink_active_list(nr_to_scan, zone, sc, prio);
}
}
@@ -1614,6 +1640,7 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
*/
priority = ZONE_RECLAIM_PRIORITY;
do {
+ note_zone_scanning_priority(zone, priority);
nr_reclaimed += shrink_zone(priority, zone, &sc);
priority--;
} while (priority >= 0 && nr_reclaimed < nr_pages);
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 45b124e012f..8614e8f6743 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -587,11 +587,9 @@ static int zoneinfo_show(struct seq_file *m, void *arg)
seq_printf(m,
"\n all_unreclaimable: %u"
"\n prev_priority: %i"
- "\n temp_priority: %i"
"\n start_pfn: %lu",
zone->all_unreclaimable,
zone->prev_priority,
- zone->temp_priority,
zone->zone_start_pfn);
spin_unlock_irqrestore(&zone->lock, flags);
seq_putc(m, '\n');
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 708e2e0371a..485e35c3b28 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -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;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3c23760c582..f735455dc5d 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -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;
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 2fbb84bf4e2..162032baeac 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -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.
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index e2077a3aa8c..6460233407c 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -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) {
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 8dabbfc3126..9f02917d6f4 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -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;
}
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 0849f1cced1..413c2d0a1f3 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -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;
}
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 4b90927619b..8a455439b12 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -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;
}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index b430cf2a4f6..5c31dead2bd 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -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));
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 1d672b0547f..6d4533b58dc 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -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;
}
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 4bc4e5b3379..d7c45a9c15f 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -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.
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 53bf977cca6..167c2ea88f6 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -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;
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d09329ca326..d6dedc4aec7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -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))
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 093b3ddc513..836541e509f 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -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;
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index d56e0d21f91..d527c8977b1 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -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:
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 27329ce9c31..ed0445fe85e 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -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.
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 35c49ff2d06..9b6b394b66f 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -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);
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 64f63010253..6d82f400d13 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -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();
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index fac7674438a..5b4f82fd98f 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -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;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9f34dec6ff8..935bc9187fd 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -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;
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index 8f2320aded5..0004c1f0ef0 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -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;
}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 96521f16342..64ca1f61dd9 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -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);
}
/*
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2b2e59d8ffb..b43e7647e12 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -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;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e9969a2fc84..8ab5679a37a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -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,
diff --git a/security/selinux/include/selinux_netlabel.h b/security/selinux/include/selinux_netlabel.h
index ecab4bddaaf..9de10cc2cef 100644
--- a/security/selinux/include/selinux_netlabel.h
+++ b/security/selinux/include/selinux_netlabel.h
@@ -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
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b1f6fb36c69..bfe122764c9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -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 */