aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/common/dmabounce.c18
-rw-r--r--arch/arm/common/sharpsl_param.c2
-rw-r--r--arch/arm/configs/enp2611_defconfig8
-rw-r--r--arch/arm/configs/ixdp2400_defconfig8
-rw-r--r--arch/arm/configs/ixdp2401_defconfig8
-rw-r--r--arch/arm/configs/ixdp2800_defconfig8
-rw-r--r--arch/arm/configs/ixdp2801_defconfig8
-rw-r--r--arch/arm/kernel/Makefile2
-rw-r--r--arch/arm/kernel/arch.c46
-rw-r--r--arch/arm/kernel/smp.c3
-rw-r--r--arch/arm/lib/ashldi3.c47
-rw-r--r--arch/arm/lib/ashrdi3.c48
-rw-r--r--arch/arm/lib/gcclib.h27
-rw-r--r--arch/arm/lib/longlong.h68
-rw-r--r--arch/arm/lib/lshrdi3.c47
-rw-r--r--arch/arm/lib/muldi3.c31
-rw-r--r--arch/arm/lib/ucmpdi2.c30
-rw-r--r--arch/arm/lib/udivdi3.c372
-rw-r--r--arch/arm/mach-aaec2000/Kconfig11
-rw-r--r--arch/arm/mach-aaec2000/Makefile9
-rw-r--r--arch/arm/mach-aaec2000/aaed2000.c48
-rw-r--r--arch/arm/mach-aaec2000/core.c157
-rw-r--r--arch/arm/mach-aaec2000/core.h16
-rw-r--r--arch/arm/mach-integrator/core.c1
-rw-r--r--arch/arm/mach-ixp2000/core.c34
-rw-r--r--arch/arm/mach-versatile/Makefile1
-rw-r--r--arch/arm/mach-versatile/core.c14
-rw-r--r--arch/arm/mach-versatile/pci.c360
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/arm/mm/copypage-v6.c6
-rw-r--r--arch/arm/mm/fault-armv.c31
-rw-r--r--arch/arm/mm/flush.c44
-rw-r--r--arch/arm/mm/ioremap.c47
-rw-r--r--arch/ppc64/kernel/iommu.c3
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c9
-rw-r--r--arch/ppc64/kernel/rtasd.c4
-rw-r--r--drivers/char/watchdog/ixp2000_wdt.c7
-rw-r--r--drivers/fc4/fc.c6
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c8
-rw-r--r--include/asm-arm/arch-aaec2000/aaec2000.h151
-rw-r--r--include/asm-arm/arch-aaec2000/debug-macro.S36
-rw-r--r--include/asm-arm/arch-aaec2000/dma.h17
-rw-r--r--include/asm-arm/arch-aaec2000/entry-macro.S33
-rw-r--r--include/asm-arm/arch-aaec2000/hardware.h49
-rw-r--r--include/asm-arm/arch-aaec2000/io.h19
-rw-r--r--include/asm-arm/arch-aaec2000/irqs.h46
-rw-r--r--include/asm-arm/arch-aaec2000/memory.h73
-rw-r--r--include/asm-arm/arch-aaec2000/param.h15
-rw-r--r--include/asm-arm/arch-aaec2000/system.h24
-rw-r--r--include/asm-arm/arch-aaec2000/timex.h18
-rw-r--r--include/asm-arm/arch-aaec2000/uncompress.h47
-rw-r--r--include/asm-arm/arch-aaec2000/vmalloc.h16
-rw-r--r--include/asm-arm/arch-ixp2000/ixp2000-regs.h1
-rw-r--r--include/asm-arm/arch-versatile/hardware.h27
-rw-r--r--include/asm-arm/arch-versatile/io.h2
-rw-r--r--include/asm-arm/arch-versatile/platform.h17
-rw-r--r--include/asm-arm/cacheflush.h3
-rw-r--r--include/asm-arm/io.h27
-rw-r--r--include/linux/atalk.h26
-rw-r--r--include/linux/netlink.h1
-rw-r--r--include/linux/pfkeyv2.h1
-rw-r--r--include/linux/xfrm.h1
-rw-r--r--include/net/ax25.h2
-rw-r--r--include/net/ip_fib.h14
-rw-r--r--include/net/sctp/command.h8
-rw-r--r--include/net/sctp/constants.h7
-rw-r--r--include/net/sctp/sctp.h17
-rw-r--r--include/net/sctp/sm.h8
-rw-r--r--include/net/sctp/structs.h41
-rw-r--r--include/net/sctp/user.h3
-rw-r--r--include/net/xfrm.h4
-rw-r--r--net/appletalk/aarp.c2
-rw-r--r--net/appletalk/ddp.c2
-rw-r--r--net/ipv4/ah4.c2
-rw-r--r--net/ipv4/esp4.c2
-rw-r--r--net/ipv4/fib_frontend.c55
-rw-r--r--net/ipv4/ipcomp.c11
-rw-r--r--net/ipv4/xfrm4_output.c8
-rw-r--r--net/ipv4/xfrm4_state.c9
-rw-r--r--net/ipv4/xfrm4_tunnel.c2
-rw-r--r--net/ipv6/ah6.c2
-rw-r--r--net/ipv6/esp6.c2
-rw-r--r--net/ipv6/ipcomp6.c9
-rw-r--r--net/ipv6/xfrm6_tunnel.c2
-rw-r--r--net/key/af_key.c16
-rw-r--r--net/sctp/associola.c151
-rw-r--r--net/sctp/endpointola.c1
-rw-r--r--net/sctp/input.c2
-rw-r--r--net/sctp/outqueue.c11
-rw-r--r--net/sctp/sm_make_chunk.c20
-rw-r--r--net/sctp/sm_sideeffect.c105
-rw-r--r--net/sctp/sm_statefuns.c148
-rw-r--r--net/sctp/sm_statetable.c6
-rw-r--r--net/sctp/socket.c405
-rw-r--r--net/sctp/transport.c4
-rw-r--r--net/xfrm/xfrm_policy.c1
-rw-r--r--net/xfrm/xfrm_state.c37
-rw-r--r--net/xfrm/xfrm_user.c9
100 files changed, 2562 insertions, 829 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 475950c8a831..ee8a9ad7bbd9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -67,10 +67,6 @@ config GENERIC_BUST_SPINLOCK
67config GENERIC_ISA_DMA 67config GENERIC_ISA_DMA
68 bool 68 bool
69 69
70config GENERIC_IOMAP
71 bool
72 default y
73
74config FIQ 70config FIQ
75 bool 71 bool
76 72
@@ -202,6 +198,11 @@ config ARCH_H720X
202 help 198 help
203 This enables support for systems based on the Hynix HMS720x 199 This enables support for systems based on the Hynix HMS720x
204 200
201config ARCH_AAEC2000
202 bool "Agilent AAEC-2000 based"
203 help
204 This enables support for systems based on the Agilent AAEC-2000
205
205endchoice 206endchoice
206 207
207source "arch/arm/mach-clps711x/Kconfig" 208source "arch/arm/mach-clps711x/Kconfig"
@@ -234,6 +235,8 @@ source "arch/arm/mach-h720x/Kconfig"
234 235
235source "arch/arm/mach-versatile/Kconfig" 236source "arch/arm/mach-versatile/Kconfig"
236 237
238source "arch/arm/mach-aaec2000/Kconfig"
239
237# Definitions to make life easier 240# Definitions to make life easier
238config ARCH_ACORN 241config ARCH_ACORN
239 bool 242 bool
@@ -277,7 +280,7 @@ config ISA_DMA_API
277 default y 280 default y
278 281
279config PCI 282config PCI
280 bool "PCI support" if ARCH_INTEGRATOR_AP 283 bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB
281 help 284 help
282 Find out whether you have a PCI motherboard. PCI is the name of a 285 Find out whether you have a PCI motherboard. PCI is the name of a
283 bus system, i.e. the way the CPU talks to the other stuff inside 286 bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2277e3d179cc..8330495e2448 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -97,6 +97,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000
97 machine-$(CONFIG_ARCH_VERSATILE) := versatile 97 machine-$(CONFIG_ARCH_VERSATILE) := versatile
98 machine-$(CONFIG_ARCH_IMX) := imx 98 machine-$(CONFIG_ARCH_IMX) := imx
99 machine-$(CONFIG_ARCH_H720X) := h720x 99 machine-$(CONFIG_ARCH_H720X) := h720x
100 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
100 101
101ifeq ($(CONFIG_ARCH_EBSA110),y) 102ifeq ($(CONFIG_ARCH_EBSA110),y)
102# This is what happens if you forget the IOCS16 line. 103# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 5797b1b100a1..9d63a01214eb 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -30,6 +30,8 @@
30#include <linux/dmapool.h> 30#include <linux/dmapool.h>
31#include <linux/list.h> 31#include <linux/list.h>
32 32
33#include <asm/cacheflush.h>
34
33#undef DEBUG 35#undef DEBUG
34 36
35#undef STATS 37#undef STATS
@@ -302,12 +304,24 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
302 304
303 DO_STATS ( device_info->bounce_count++ ); 305 DO_STATS ( device_info->bounce_count++ );
304 306
305 if ((dir == DMA_FROM_DEVICE) || 307 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
306 (dir == DMA_BIDIRECTIONAL)) { 308 unsigned long ptr;
309
307 dev_dbg(dev, 310 dev_dbg(dev,
308 "%s: copy back safe %p to unsafe %p size %d\n", 311 "%s: copy back safe %p to unsafe %p size %d\n",
309 __func__, buf->safe, buf->ptr, size); 312 __func__, buf->safe, buf->ptr, size);
310 memcpy(buf->ptr, buf->safe, size); 313 memcpy(buf->ptr, buf->safe, size);
314
315 /*
316 * DMA buffers must have the same cache properties
317 * as if they were really used for DMA - which means
318 * data must be written back to RAM. Note that
319 * we don't use dmac_flush_range() here for the
320 * bidirectional case because we know the cache
321 * lines will be coherent with the data written.
322 */
323 ptr = (unsigned long)buf->ptr;
324 dmac_clean_range(ptr, ptr + size);
311 } 325 }
312 free_safe_buffer(device_info, buf); 326 free_safe_buffer(device_info, buf);
313 } 327 }
diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c
index c2c557a224c2..c94864c5b1af 100644
--- a/arch/arm/common/sharpsl_param.c
+++ b/arch/arm/common/sharpsl_param.c
@@ -22,7 +22,7 @@
22 * them early in the boot process, then pass them to the appropriate drivers. 22 * them early in the boot process, then pass them to the appropriate drivers.
23 * Not all devices use all paramaters but the format is common to all. 23 * Not all devices use all paramaters but the format is common to all.
24 */ 24 */
25#ifdef ARCH_SA1100 25#ifdef CONFIG_ARCH_SA1100
26#define PARAM_BASE 0xe8ffc000 26#define PARAM_BASE 0xe8ffc000
27#else 27#else
28#define PARAM_BASE 0xa0000a00 28#define PARAM_BASE 0xa0000a00
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig
index e8f9fccffe84..06fae4b62774 100644
--- a/arch/arm/configs/enp2611_defconfig
+++ b/arch/arm/configs/enp2611_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
50# 50#
51# Loadable module support 51# Loadable module support
52# 52#
53# CONFIG_MODULES is not set 53CONFIG_MODULES=y
54CONFIG_MODULE_UNLOAD=y
55# CONFIG_MODULE_FORCE_UNLOAD is not set
56CONFIG_OBSOLETE_MODPARM=y
57# CONFIG_MODVERSIONS is not set
58# CONFIG_MODULE_SRCVERSION_ALL is not set
59CONFIG_KMOD=y
54 60
55# 61#
56# System Type 62# System Type
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig
index 4fd663ecbe39..810a450a55d2 100644
--- a/arch/arm/configs/ixdp2400_defconfig
+++ b/arch/arm/configs/ixdp2400_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
50# 50#
51# Loadable module support 51# Loadable module support
52# 52#
53# CONFIG_MODULES is not set 53CONFIG_MODULES=y
54CONFIG_MODULE_UNLOAD=y
55# CONFIG_MODULE_FORCE_UNLOAD is not set
56CONFIG_OBSOLETE_MODPARM=y
57# CONFIG_MODVERSIONS is not set
58# CONFIG_MODULE_SRCVERSION_ALL is not set
59CONFIG_KMOD=y
54 60
55# 61#
56# System Type 62# System Type
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig
index 6f51c98084a3..72e1b940e975 100644
--- a/arch/arm/configs/ixdp2401_defconfig
+++ b/arch/arm/configs/ixdp2401_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
50# 50#
51# Loadable module support 51# Loadable module support
52# 52#
53# CONFIG_MODULES is not set 53CONFIG_MODULES=y
54CONFIG_MODULE_UNLOAD=y
55# CONFIG_MODULE_FORCE_UNLOAD is not set
56CONFIG_OBSOLETE_MODPARM=y
57# CONFIG_MODVERSIONS is not set
58# CONFIG_MODULE_SRCVERSION_ALL is not set
59CONFIG_KMOD=y
54 60
55# 61#
56# System Type 62# System Type
diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig
index 7be3521f91fc..1592e45f0278 100644
--- a/arch/arm/configs/ixdp2800_defconfig
+++ b/arch/arm/configs/ixdp2800_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
50# 50#
51# Loadable module support 51# Loadable module support
52# 52#
53# CONFIG_MODULES is not set 53CONFIG_MODULES=y
54CONFIG_MODULE_UNLOAD=y
55# CONFIG_MODULE_FORCE_UNLOAD is not set
56CONFIG_OBSOLETE_MODPARM=y
57# CONFIG_MODVERSIONS is not set
58# CONFIG_MODULE_SRCVERSION_ALL is not set
59CONFIG_KMOD=y
54 60
55# 61#
56# System Type 62# System Type
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig
index cd84a20f30f1..f1afe3d09ec6 100644
--- a/arch/arm/configs/ixdp2801_defconfig
+++ b/arch/arm/configs/ixdp2801_defconfig
@@ -50,7 +50,13 @@ CONFIG_BASE_SMALL=0
50# 50#
51# Loadable module support 51# Loadable module support
52# 52#
53# CONFIG_MODULES is not set 53CONFIG_MODULES=y
54CONFIG_MODULE_UNLOAD=y
55# CONFIG_MODULE_FORCE_UNLOAD is not set
56CONFIG_OBSOLETE_MODPARM=y
57# CONFIG_MODVERSIONS is not set
58# CONFIG_MODULE_SRCVERSION_ALL is not set
59CONFIG_KMOD=y
54 60
55# 61#
56# System Type 62# System Type
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 4a2af55e134b..3e1b0327e4d7 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -6,7 +6,7 @@ AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
6 6
7# Object file lists. 7# Object file lists.
8 8
9obj-y := arch.o compat.o dma.o entry-armv.o entry-common.o irq.o \ 9obj-y := compat.o dma.o entry-armv.o entry-common.o irq.o \
10 process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \ 10 process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
11 time.o traps.o 11 time.o traps.o
12 12
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
deleted file mode 100644
index 4e02fbeb10a6..000000000000
--- a/arch/arm/kernel/arch.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * linux/arch/arm/kernel/arch.c
3 *
4 * Architecture specific fixups.
5 */
6#include <linux/config.h>
7#include <linux/init.h>
8#include <linux/types.h>
9
10#include <asm/elf.h>
11#include <asm/page.h>
12#include <asm/setup.h>
13#include <asm/mach/arch.h>
14
15unsigned int vram_size;
16
17#ifdef CONFIG_ARCH_ACORN
18
19unsigned int memc_ctrl_reg;
20unsigned int number_mfm_drives;
21
22static int __init parse_tag_acorn(const struct tag *tag)
23{
24 memc_ctrl_reg = tag->u.acorn.memc_control_reg;
25 number_mfm_drives = tag->u.acorn.adfsdrives;
26
27 switch (tag->u.acorn.vram_pages) {
28 case 512:
29 vram_size += PAGE_SIZE * 256;
30 case 256:
31 vram_size += PAGE_SIZE * 256;
32 default:
33 break;
34 }
35#if 0
36 if (vram_size) {
37 desc->video_start = 0x02000000;
38 desc->video_end = 0x02000000 + vram_size;
39 }
40#endif
41 return 0;
42}
43
44__tagtable(ATAG_ACORN, parse_tag_acorn);
45
46#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 45ed036336e0..34892758f098 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -145,7 +145,8 @@ int __init __cpu_up(unsigned int cpu)
145 pgd_free(pgd); 145 pgd_free(pgd);
146 146
147 if (ret) { 147 if (ret) {
148 printk(KERN_CRIT "cpu_up: processor %d failed to boot\n", cpu); 148 printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu);
149
149 /* 150 /*
150 * FIXME: We need to clean up the new idle thread. --rmk 151 * FIXME: We need to clean up the new idle thread. --rmk
151 */ 152 */
diff --git a/arch/arm/lib/ashldi3.c b/arch/arm/lib/ashldi3.c
index 130f5a839669..b62875cfd8f8 100644
--- a/arch/arm/lib/ashldi3.c
+++ b/arch/arm/lib/ashldi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34DItype 34s64 __ashldi3(s64 u, int b)
35__ashldi3 (DItype u, word_type b)
36{ 35{
37 DIunion w; 36 DIunion w;
38 word_type bm; 37 int bm;
39 DIunion uu; 38 DIunion uu;
40 39
41 if (b == 0) 40 if (b == 0)
42 return u; 41 return u;
43 42
44 uu.ll = u; 43 uu.ll = u;
45 44
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 45 bm = (sizeof(s32) * BITS_PER_UNIT) - b;
47 if (bm <= 0) 46 if (bm <= 0) {
48 { 47 w.s.low = 0;
49 w.s.low = 0; 48 w.s.high = (u32) uu.s.low << -bm;
50 w.s.high = (USItype)uu.s.low << -bm; 49 } else {
51 } 50 u32 carries = (u32) uu.s.low >> bm;
52 else 51 w.s.low = (u32) uu.s.low << b;
53 { 52 w.s.high = ((u32) uu.s.high << b) | carries;
54 USItype carries = (USItype)uu.s.low >> bm; 53 }
55 w.s.low = (USItype)uu.s.low << b; 54
56 w.s.high = ((USItype)uu.s.high << b) | carries; 55 return w.ll;
57 }
58
59 return w.ll;
60} 56}
61
diff --git a/arch/arm/lib/ashrdi3.c b/arch/arm/lib/ashrdi3.c
index 71625d218f8d..9a8600a7543f 100644
--- a/arch/arm/lib/ashrdi3.c
+++ b/arch/arm/lib/ashrdi3.c
@@ -31,31 +31,27 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34DItype 34s64 __ashrdi3(s64 u, int b)
35__ashrdi3 (DItype u, word_type b)
36{ 35{
37 DIunion w; 36 DIunion w;
38 word_type bm; 37 int bm;
39 DIunion uu; 38 DIunion uu;
40 39
41 if (b == 0) 40 if (b == 0)
42 return u; 41 return u;
43 42
44 uu.ll = u; 43 uu.ll = u;
45 44
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 45 bm = (sizeof(s32) * BITS_PER_UNIT) - b;
47 if (bm <= 0) 46 if (bm <= 0) {
48 { 47 /* w.s.high = 1..1 or 0..0 */
49 /* w.s.high = 1..1 or 0..0 */ 48 w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
50 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); 49 w.s.low = uu.s.high >> -bm;
51 w.s.low = uu.s.high >> -bm; 50 } else {
52 } 51 u32 carries = (u32) uu.s.high << bm;
53 else 52 w.s.high = uu.s.high >> b;
54 { 53 w.s.low = ((u32) uu.s.low >> b) | carries;
55 USItype carries = (USItype)uu.s.high << bm; 54 }
56 w.s.high = uu.s.high >> b; 55
57 w.s.low = ((USItype)uu.s.low >> b) | carries; 56 return w.ll;
58 }
59
60 return w.ll;
61} 57}
diff --git a/arch/arm/lib/gcclib.h b/arch/arm/lib/gcclib.h
index 65314a3d9e27..8b6dcc656de7 100644
--- a/arch/arm/lib/gcclib.h
+++ b/arch/arm/lib/gcclib.h
@@ -1,25 +1,22 @@
1/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */ 1/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
2/* I Molton 29/07/01 */ 2/* I Molton 29/07/01 */
3 3
4#define BITS_PER_UNIT 8 4#include <linux/types.h>
5#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
6 5
7typedef unsigned int UQItype __attribute__ ((mode (QI))); 6#define BITS_PER_UNIT 8
8typedef int SItype __attribute__ ((mode (SI))); 7#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
9typedef unsigned int USItype __attribute__ ((mode (SI)));
10typedef int DItype __attribute__ ((mode (DI)));
11typedef int word_type __attribute__ ((mode (__word__)));
12typedef unsigned int UDItype __attribute__ ((mode (DI)));
13 8
14#ifdef __ARMEB__ 9#ifdef __ARMEB__
15 struct DIstruct {SItype high, low;}; 10struct DIstruct {
11 s32 high, low;
12};
16#else 13#else
17 struct DIstruct {SItype low, high;}; 14struct DIstruct {
15 s32 low, high;
16};
18#endif 17#endif
19 18
20typedef union 19typedef union {
21{ 20 struct DIstruct s;
22 struct DIstruct s; 21 s64 ll;
23 DItype ll;
24} DIunion; 22} DIunion;
25
diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h
index 179eea4edc35..90ae647e4d76 100644
--- a/arch/arm/lib/longlong.h
+++ b/arch/arm/lib/longlong.h
@@ -26,18 +26,18 @@
26 26
27#define __BITS4 (SI_TYPE_SIZE / 4) 27#define __BITS4 (SI_TYPE_SIZE / 4)
28#define __ll_B (1L << (SI_TYPE_SIZE / 2)) 28#define __ll_B (1L << (SI_TYPE_SIZE / 2))
29#define __ll_lowpart(t) ((USItype) (t) % __ll_B) 29#define __ll_lowpart(t) ((u32) (t) % __ll_B)
30#define __ll_highpart(t) ((USItype) (t) / __ll_B) 30#define __ll_highpart(t) ((u32) (t) / __ll_B)
31 31
32/* Define auxiliary asm macros. 32/* Define auxiliary asm macros.
33 33
34 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) 34 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand)
35 multiplies two USItype integers MULTIPLER and MULTIPLICAND, 35 multiplies two u32 integers MULTIPLER and MULTIPLICAND,
36 and generates a two-part USItype product in HIGH_PROD and 36 and generates a two-part u32 product in HIGH_PROD and
37 LOW_PROD. 37 LOW_PROD.
38 38
39 2) __umulsidi3(a,b) multiplies two USItype integers A and B, 39 2) __umulsidi3(a,b) multiplies two u32 integers A and B,
40 and returns a UDItype product. This is just a variant of umul_ppmm. 40 and returns a u64 product. This is just a variant of umul_ppmm.
41 41
42 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, 42 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
43 denominator) divides a two-word unsigned integer, composed by the 43 denominator) divides a two-word unsigned integer, composed by the
@@ -77,23 +77,23 @@
77#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ 77#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
78 __asm__ ("adds %1, %4, %5 \n\ 78 __asm__ ("adds %1, %4, %5 \n\
79 adc %0, %2, %3" \ 79 adc %0, %2, %3" \
80 : "=r" ((USItype) (sh)), \ 80 : "=r" ((u32) (sh)), \
81 "=&r" ((USItype) (sl)) \ 81 "=&r" ((u32) (sl)) \
82 : "%r" ((USItype) (ah)), \ 82 : "%r" ((u32) (ah)), \
83 "rI" ((USItype) (bh)), \ 83 "rI" ((u32) (bh)), \
84 "%r" ((USItype) (al)), \ 84 "%r" ((u32) (al)), \
85 "rI" ((USItype) (bl))) 85 "rI" ((u32) (bl)))
86#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ 86#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
87 __asm__ ("subs %1, %4, %5 \n\ 87 __asm__ ("subs %1, %4, %5 \n\
88 sbc %0, %2, %3" \ 88 sbc %0, %2, %3" \
89 : "=r" ((USItype) (sh)), \ 89 : "=r" ((u32) (sh)), \
90 "=&r" ((USItype) (sl)) \ 90 "=&r" ((u32) (sl)) \
91 : "r" ((USItype) (ah)), \ 91 : "r" ((u32) (ah)), \
92 "rI" ((USItype) (bh)), \ 92 "rI" ((u32) (bh)), \
93 "r" ((USItype) (al)), \ 93 "r" ((u32) (al)), \
94 "rI" ((USItype) (bl))) 94 "rI" ((u32) (bl)))
95#define umul_ppmm(xh, xl, a, b) \ 95#define umul_ppmm(xh, xl, a, b) \
96{register USItype __t0, __t1, __t2; \ 96{register u32 __t0, __t1, __t2; \
97 __asm__ ("%@ Inlined umul_ppmm \n\ 97 __asm__ ("%@ Inlined umul_ppmm \n\
98 mov %2, %5, lsr #16 \n\ 98 mov %2, %5, lsr #16 \n\
99 mov %0, %6, lsr #16 \n\ 99 mov %0, %6, lsr #16 \n\
@@ -107,14 +107,14 @@
107 addcs %0, %0, #65536 \n\ 107 addcs %0, %0, #65536 \n\
108 adds %1, %1, %3, lsl #16 \n\ 108 adds %1, %1, %3, lsl #16 \n\
109 adc %0, %0, %3, lsr #16" \ 109 adc %0, %0, %3, lsr #16" \
110 : "=&r" ((USItype) (xh)), \ 110 : "=&r" ((u32) (xh)), \
111 "=r" ((USItype) (xl)), \ 111 "=r" ((u32) (xl)), \
112 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ 112 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
113 : "r" ((USItype) (a)), \ 113 : "r" ((u32) (a)), \
114 "r" ((USItype) (b)));} 114 "r" ((u32) (b)));}
115#define UMUL_TIME 20 115#define UMUL_TIME 20
116#define UDIV_TIME 100 116#define UDIV_TIME 100
117#endif /* __arm__ */ 117#endif /* __arm__ */
118 118
119#define __umulsidi3(u, v) \ 119#define __umulsidi3(u, v) \
120 ({DIunion __w; \ 120 ({DIunion __w; \
@@ -123,14 +123,14 @@
123 123
124#define __udiv_qrnnd_c(q, r, n1, n0, d) \ 124#define __udiv_qrnnd_c(q, r, n1, n0, d) \
125 do { \ 125 do { \
126 USItype __d1, __d0, __q1, __q0; \ 126 u32 __d1, __d0, __q1, __q0; \
127 USItype __r1, __r0, __m; \ 127 u32 __r1, __r0, __m; \
128 __d1 = __ll_highpart (d); \ 128 __d1 = __ll_highpart (d); \
129 __d0 = __ll_lowpart (d); \ 129 __d0 = __ll_lowpart (d); \
130 \ 130 \
131 __r1 = (n1) % __d1; \ 131 __r1 = (n1) % __d1; \
132 __q1 = (n1) / __d1; \ 132 __q1 = (n1) / __d1; \
133 __m = (USItype) __q1 * __d0; \ 133 __m = (u32) __q1 * __d0; \
134 __r1 = __r1 * __ll_B | __ll_highpart (n0); \ 134 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
135 if (__r1 < __m) \ 135 if (__r1 < __m) \
136 { \ 136 { \
@@ -143,7 +143,7 @@
143 \ 143 \
144 __r0 = __r1 % __d1; \ 144 __r0 = __r1 % __d1; \
145 __q0 = __r1 / __d1; \ 145 __q0 = __r1 / __d1; \
146 __m = (USItype) __q0 * __d0; \ 146 __m = (u32) __q0 * __d0; \
147 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ 147 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
148 if (__r0 < __m) \ 148 if (__r0 < __m) \
149 { \ 149 { \
@@ -154,7 +154,7 @@
154 } \ 154 } \
155 __r0 -= __m; \ 155 __r0 -= __m; \
156 \ 156 \
157 (q) = (USItype) __q1 * __ll_B | __q0; \ 157 (q) = (u32) __q1 * __ll_B | __q0; \
158 (r) = __r0; \ 158 (r) = __r0; \
159 } while (0) 159 } while (0)
160 160
@@ -163,14 +163,14 @@
163 163
164#define count_leading_zeros(count, x) \ 164#define count_leading_zeros(count, x) \
165 do { \ 165 do { \
166 USItype __xr = (x); \ 166 u32 __xr = (x); \
167 USItype __a; \ 167 u32 __a; \
168 \ 168 \
169 if (SI_TYPE_SIZE <= 32) \ 169 if (SI_TYPE_SIZE <= 32) \
170 { \ 170 { \
171 __a = __xr < ((USItype)1<<2*__BITS4) \ 171 __a = __xr < ((u32)1<<2*__BITS4) \
172 ? (__xr < ((USItype)1<<__BITS4) ? 0 : __BITS4) \ 172 ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \
173 : (__xr < ((USItype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ 173 : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
174 } \ 174 } \
175 else \ 175 else \
176 { \ 176 { \
diff --git a/arch/arm/lib/lshrdi3.c b/arch/arm/lib/lshrdi3.c
index b666f1bad451..3681f49d2b6e 100644
--- a/arch/arm/lib/lshrdi3.c
+++ b/arch/arm/lib/lshrdi3.c
@@ -31,31 +31,26 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34DItype 34s64 __lshrdi3(s64 u, int b)
35__lshrdi3 (DItype u, word_type b)
36{ 35{
37 DIunion w; 36 DIunion w;
38 word_type bm; 37 int bm;
39 DIunion uu; 38 DIunion uu;
40 39
41 if (b == 0) 40 if (b == 0)
42 return u; 41 return u;
43 42
44 uu.ll = u; 43 uu.ll = u;
45 44
46 bm = (sizeof (SItype) * BITS_PER_UNIT) - b; 45 bm = (sizeof(s32) * BITS_PER_UNIT) - b;
47 if (bm <= 0) 46 if (bm <= 0) {
48 { 47 w.s.high = 0;
49 w.s.high = 0; 48 w.s.low = (u32) uu.s.high >> -bm;
50 w.s.low = (USItype)uu.s.high >> -bm; 49 } else {
51 } 50 u32 carries = (u32) uu.s.high << bm;
52 else 51 w.s.high = (u32) uu.s.high >> b;
53 { 52 w.s.low = ((u32) uu.s.low >> b) | carries;
54 USItype carries = (USItype)uu.s.high << bm; 53 }
55 w.s.high = (USItype)uu.s.high >> b; 54
56 w.s.low = ((USItype)uu.s.low >> b) | carries; 55 return w.ll;
57 }
58
59 return w.ll;
60} 56}
61
diff --git a/arch/arm/lib/muldi3.c b/arch/arm/lib/muldi3.c
index 44d611b1cfdb..0a3b93313f18 100644
--- a/arch/arm/lib/muldi3.c
+++ b/arch/arm/lib/muldi3.c
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34#define umul_ppmm(xh, xl, a, b) \ 34#define umul_ppmm(xh, xl, a, b) \
35{register USItype __t0, __t1, __t2; \ 35{register u32 __t0, __t1, __t2; \
36 __asm__ ("%@ Inlined umul_ppmm \n\ 36 __asm__ ("%@ Inlined umul_ppmm \n\
37 mov %2, %5, lsr #16 \n\ 37 mov %2, %5, lsr #16 \n\
38 mov %0, %6, lsr #16 \n\ 38 mov %0, %6, lsr #16 \n\
@@ -46,32 +46,27 @@ Boston, MA 02111-1307, USA. */
46 addcs %0, %0, #65536 \n\ 46 addcs %0, %0, #65536 \n\
47 adds %1, %1, %3, lsl #16 \n\ 47 adds %1, %1, %3, lsl #16 \n\
48 adc %0, %0, %3, lsr #16" \ 48 adc %0, %0, %3, lsr #16" \
49 : "=&r" ((USItype) (xh)), \ 49 : "=&r" ((u32) (xh)), \
50 "=r" ((USItype) (xl)), \ 50 "=r" ((u32) (xl)), \
51 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ 51 "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
52 : "r" ((USItype) (a)), \ 52 : "r" ((u32) (a)), \
53 "r" ((USItype) (b)));} 53 "r" ((u32) (b)));}
54
55 54
56#define __umulsidi3(u, v) \ 55#define __umulsidi3(u, v) \
57 ({DIunion __w; \ 56 ({DIunion __w; \
58 umul_ppmm (__w.s.high, __w.s.low, u, v); \ 57 umul_ppmm (__w.s.high, __w.s.low, u, v); \
59 __w.ll; }) 58 __w.ll; })
60 59
61 60s64 __muldi3(s64 u, s64 v)
62DItype
63__muldi3 (DItype u, DItype v)
64{ 61{
65 DIunion w; 62 DIunion w;
66 DIunion uu, vv; 63 DIunion uu, vv;
67 64
68 uu.ll = u, 65 uu.ll = u, vv.ll = v;
69 vv.ll = v;
70 66
71 w.ll = __umulsidi3 (uu.s.low, vv.s.low); 67 w.ll = __umulsidi3(uu.s.low, vv.s.low);
72 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high 68 w.s.high += ((u32) uu.s.low * (u32) vv.s.high
73 + (USItype) uu.s.high * (USItype) vv.s.low); 69 + (u32) uu.s.high * (u32) vv.s.low);
74 70
75 return w.ll; 71 return w.ll;
76} 72}
77
diff --git a/arch/arm/lib/ucmpdi2.c b/arch/arm/lib/ucmpdi2.c
index 6c6ae63efa02..57f3f2df3850 100644
--- a/arch/arm/lib/ucmpdi2.c
+++ b/arch/arm/lib/ucmpdi2.c
@@ -31,21 +31,19 @@ Boston, MA 02111-1307, USA. */
31 31
32#include "gcclib.h" 32#include "gcclib.h"
33 33
34word_type 34int __ucmpdi2(s64 a, s64 b)
35__ucmpdi2 (DItype a, DItype b)
36{ 35{
37 DIunion au, bu; 36 DIunion au, bu;
38 37
39 au.ll = a, bu.ll = b; 38 au.ll = a, bu.ll = b;
40 39
41 if ((USItype) au.s.high < (USItype) bu.s.high) 40 if ((u32) au.s.high < (u32) bu.s.high)
42 return 0; 41 return 0;
43 else if ((USItype) au.s.high > (USItype) bu.s.high) 42 else if ((u32) au.s.high > (u32) bu.s.high)
44 return 2; 43 return 2;
45 if ((USItype) au.s.low < (USItype) bu.s.low) 44 if ((u32) au.s.low < (u32) bu.s.low)
46 return 0; 45 return 0;
47 else if ((USItype) au.s.low > (USItype) bu.s.low) 46 else if ((u32) au.s.low > (u32) bu.s.low)
48 return 2; 47 return 2;
49 return 1; 48 return 1;
50} 49}
51
diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c
index d25195f673f4..e343be4c6642 100644
--- a/arch/arm/lib/udivdi3.c
+++ b/arch/arm/lib/udivdi3.c
@@ -32,211 +32,191 @@ Boston, MA 02111-1307, USA. */
32#include "gcclib.h" 32#include "gcclib.h"
33#include "longlong.h" 33#include "longlong.h"
34 34
35static const UQItype __clz_tab[] = 35static const u8 __clz_tab[] = {
36{ 36 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
37 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 37 5, 5, 5, 5, 5, 5, 5, 5,
38 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 38 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
39 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 39 6, 6, 6, 6, 6, 6, 6, 6,
40 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 40 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
41 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 41 7, 7, 7, 7, 7, 7, 7, 7,
42 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 42 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
43 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 43 7, 7, 7, 7, 7, 7, 7, 7,
44 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 44 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
45 8, 8, 8, 8, 8, 8, 8, 8,
46 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
47 8, 8, 8, 8, 8, 8, 8, 8,
48 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
49 8, 8, 8, 8, 8, 8, 8, 8,
50 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
51 8, 8, 8, 8, 8, 8, 8, 8,
45}; 52};
46 53
47UDItype 54u64 __udivmoddi4(u64 n, u64 d, u64 * rp)
48__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
49{ 55{
50 DIunion ww; 56 DIunion ww;
51 DIunion nn, dd; 57 DIunion nn, dd;
52 DIunion rr; 58 DIunion rr;
53 USItype d0, d1, n0, n1, n2; 59 u32 d0, d1, n0, n1, n2;
54 USItype q0, q1; 60 u32 q0, q1;
55 USItype b, bm; 61 u32 b, bm;
56 62
57 nn.ll = n; 63 nn.ll = n;
58 dd.ll = d; 64 dd.ll = d;
59 65
60 d0 = dd.s.low; 66 d0 = dd.s.low;
61 d1 = dd.s.high; 67 d1 = dd.s.high;
62 n0 = nn.s.low; 68 n0 = nn.s.low;
63 n1 = nn.s.high; 69 n1 = nn.s.high;
64 70
65 if (d1 == 0) 71 if (d1 == 0) {
66 { 72 if (d0 > n1) {
67 if (d0 > n1) 73 /* 0q = nn / 0D */
68 { 74
69 /* 0q = nn / 0D */ 75 count_leading_zeros(bm, d0);
70 76
71 count_leading_zeros (bm, d0); 77 if (bm != 0) {
72 78 /* Normalize, i.e. make the most significant bit of the
73 if (bm != 0) 79 denominator set. */
74 { 80
75 /* Normalize, i.e. make the most significant bit of the 81 d0 = d0 << bm;
76 denominator set. */ 82 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
77 83 n0 = n0 << bm;
78 d0 = d0 << bm; 84 }
79 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); 85
80 n0 = n0 << bm; 86 udiv_qrnnd(q0, n0, n1, n0, d0);
81 } 87 q1 = 0;
82 88
83 udiv_qrnnd (q0, n0, n1, n0, d0); 89 /* Remainder in n0 >> bm. */
84 q1 = 0; 90 } else {
85 91 /* qq = NN / 0d */
86 /* Remainder in n0 >> bm. */ 92
87 } 93 if (d0 == 0)
88 else 94 d0 = 1 / d0; /* Divide intentionally by zero. */
89 { 95
90 /* qq = NN / 0d */ 96 count_leading_zeros(bm, d0);
91 97
92 if (d0 == 0) 98 if (bm == 0) {
93 d0 = 1 / d0; /* Divide intentionally by zero. */ 99 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
94 100 conclude (the most significant bit of n1 is set) /\ (the
95 count_leading_zeros (bm, d0); 101 leading quotient digit q1 = 1).
96 102
97 if (bm == 0) 103 This special case is necessary, not an optimization.
98 { 104 (Shifts counts of SI_TYPE_SIZE are undefined.) */
99 /* From (n1 >= d0) /\ (the most significant bit of d0 is set), 105
100 conclude (the most significant bit of n1 is set) /\ (the 106 n1 -= d0;
101 leading quotient digit q1 = 1). 107 q1 = 1;
102 108 } else {
103 This special case is necessary, not an optimization. 109 /* Normalize. */
104 (Shifts counts of SI_TYPE_SIZE are undefined.) */ 110
105 111 b = SI_TYPE_SIZE - bm;
106 n1 -= d0; 112
107 q1 = 1; 113 d0 = d0 << bm;
108 } 114 n2 = n1 >> b;
109 else 115 n1 = (n1 << bm) | (n0 >> b);
110 { 116 n0 = n0 << bm;
111 /* Normalize. */ 117
112 118 udiv_qrnnd(q1, n1, n2, n1, d0);
113 b = SI_TYPE_SIZE - bm; 119 }
114 120
115 d0 = d0 << bm; 121 /* n1 != d0... */
116 n2 = n1 >> b; 122
117 n1 = (n1 << bm) | (n0 >> b); 123 udiv_qrnnd(q0, n0, n1, n0, d0);
118 n0 = n0 << bm; 124
119 125 /* Remainder in n0 >> bm. */
120 udiv_qrnnd (q1, n1, n2, n1, d0); 126 }
121 } 127
122 128 if (rp != 0) {
123 /* n1 != d0... */ 129 rr.s.low = n0 >> bm;
124 130 rr.s.high = 0;
125 udiv_qrnnd (q0, n0, n1, n0, d0); 131 *rp = rr.ll;
126 132 }
127 /* Remainder in n0 >> bm. */ 133 } else {
128 } 134 if (d1 > n1) {
129 135 /* 00 = nn / DD */
130 if (rp != 0) 136
131 { 137 q0 = 0;
132 rr.s.low = n0 >> bm; 138 q1 = 0;
133 rr.s.high = 0; 139
134 *rp = rr.ll; 140 /* Remainder in n1n0. */
135 } 141 if (rp != 0) {
136 } 142 rr.s.low = n0;
137 else 143 rr.s.high = n1;
138 { 144 *rp = rr.ll;
139 if (d1 > n1) 145 }
140 { 146 } else {
141 /* 00 = nn / DD */ 147 /* 0q = NN / dd */
142 148
143 q0 = 0; 149 count_leading_zeros(bm, d1);
144 q1 = 0; 150 if (bm == 0) {
145 151 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
146 /* Remainder in n1n0. */ 152 conclude (the most significant bit of n1 is set) /\ (the
147 if (rp != 0) 153 quotient digit q0 = 0 or 1).
148 { 154
149 rr.s.low = n0; 155 This special case is necessary, not an optimization. */
150 rr.s.high = n1; 156
151 *rp = rr.ll; 157 /* The condition on the next line takes advantage of that
152 } 158 n1 >= d1 (true due to program flow). */
153 } 159 if (n1 > d1 || n0 >= d0) {
154 else 160 q0 = 1;
155 { 161 sub_ddmmss(n1, n0, n1, n0, d1, d0);
156 /* 0q = NN / dd */ 162 } else
157 163 q0 = 0;
158 count_leading_zeros (bm, d1); 164
159 if (bm == 0) 165 q1 = 0;
160 { 166
161 /* From (n1 >= d1) /\ (the most significant bit of d1 is set), 167 if (rp != 0) {
162 conclude (the most significant bit of n1 is set) /\ (the 168 rr.s.low = n0;
163 quotient digit q0 = 0 or 1). 169 rr.s.high = n1;
164 170 *rp = rr.ll;
165 This special case is necessary, not an optimization. */ 171 }
166 172 } else {
167 /* The condition on the next line takes advantage of that 173 u32 m1, m0;
168 n1 >= d1 (true due to program flow). */ 174 /* Normalize. */
169 if (n1 > d1 || n0 >= d0) 175
170 { 176 b = SI_TYPE_SIZE - bm;
171 q0 = 1; 177
172 sub_ddmmss (n1, n0, n1, n0, d1, d0); 178 d1 = (d1 << bm) | (d0 >> b);
173 } 179 d0 = d0 << bm;
174 else 180 n2 = n1 >> b;
175 q0 = 0; 181 n1 = (n1 << bm) | (n0 >> b);
176 182 n0 = n0 << bm;
177 q1 = 0; 183
178 184 udiv_qrnnd(q0, n1, n2, n1, d1);
179 if (rp != 0) 185 umul_ppmm(m1, m0, q0, d0);
180 { 186
181 rr.s.low = n0; 187 if (m1 > n1 || (m1 == n1 && m0 > n0)) {
182 rr.s.high = n1; 188 q0--;
183 *rp = rr.ll; 189 sub_ddmmss(m1, m0, m1, m0, d1, d0);
184 } 190 }
185 } 191
186 else 192 q1 = 0;
187 { 193
188 USItype m1, m0; 194 /* Remainder in (n1n0 - m1m0) >> bm. */
189 /* Normalize. */ 195 if (rp != 0) {
190 196 sub_ddmmss(n1, n0, n1, n0, m1, m0);
191 b = SI_TYPE_SIZE - bm; 197 rr.s.low = (n1 << b) | (n0 >> bm);
192 198 rr.s.high = n1 >> bm;
193 d1 = (d1 << bm) | (d0 >> b); 199 *rp = rr.ll;
194 d0 = d0 << bm; 200 }
195 n2 = n1 >> b; 201 }
196 n1 = (n1 << bm) | (n0 >> b); 202 }
197 n0 = n0 << bm; 203 }
198 204
199 udiv_qrnnd (q0, n1, n2, n1, d1); 205 ww.s.low = q0;
200 umul_ppmm (m1, m0, q0, d0); 206 ww.s.high = q1;
201 207 return ww.ll;
202 if (m1 > n1 || (m1 == n1 && m0 > n0))
203 {
204 q0--;
205 sub_ddmmss (m1, m0, m1, m0, d1, d0);
206 }
207
208 q1 = 0;
209
210 /* Remainder in (n1n0 - m1m0) >> bm. */
211 if (rp != 0)
212 {
213 sub_ddmmss (n1, n0, n1, n0, m1, m0);
214 rr.s.low = (n1 << b) | (n0 >> bm);
215 rr.s.high = n1 >> bm;
216 *rp = rr.ll;
217 }
218 }
219 }
220 }
221
222 ww.s.low = q0;
223 ww.s.high = q1;
224 return ww.ll;
225} 208}
226 209
227UDItype 210u64 __udivdi3(u64 n, u64 d)
228__udivdi3 (UDItype n, UDItype d)
229{ 211{
230 return __udivmoddi4 (n, d, (UDItype *) 0); 212 return __udivmoddi4(n, d, (u64 *) 0);
231} 213}
232 214
233UDItype 215u64 __umoddi3(u64 u, u64 v)
234__umoddi3 (UDItype u, UDItype v)
235{ 216{
236 UDItype w; 217 u64 w;
237 218
238 (void) __udivmoddi4 (u ,v, &w); 219 (void)__udivmoddi4(u, v, &w);
239 220
240 return w; 221 return w;
241} 222}
242
diff --git a/arch/arm/mach-aaec2000/Kconfig b/arch/arm/mach-aaec2000/Kconfig
new file mode 100644
index 000000000000..5e4bef93754c
--- /dev/null
+++ b/arch/arm/mach-aaec2000/Kconfig
@@ -0,0 +1,11 @@
1if ARCH_AAEC2000
2
3menu "Agilent AAEC-2000 Implementations"
4
5config MACH_AAED2000
6 bool "Agilent AAED-2000 Development Platform"
7 select CPU_ARM920T
8
9endmenu
10
11endif
diff --git a/arch/arm/mach-aaec2000/Makefile b/arch/arm/mach-aaec2000/Makefile
new file mode 100644
index 000000000000..20ec83896c37
--- /dev/null
+++ b/arch/arm/mach-aaec2000/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Common support (must be linked before board specific support)
6obj-y += core.o
7
8# Specific board support
9obj-$(CONFIG_MACH_AAED2000) += aaed2000.o
diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c
new file mode 100644
index 000000000000..5417ca3f4621
--- /dev/null
+++ b/arch/arm/mach-aaec2000/aaed2000.c
@@ -0,0 +1,48 @@
1/*
2 * linux/arch/arm/mach-aaec2000/aaed2000.c
3 *
4 * Support for the Agilent AAED-2000 Development Platform.
5 *
6 * Copyright (c) 2005 Nicolas Bellido Y Ortega
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <linux/major.h>
18#include <linux/interrupt.h>
19
20#include <asm/setup.h>
21#include <asm/memory.h>
22#include <asm/mach-types.h>
23#include <asm/hardware.h>
24#include <asm/irq.h>
25
26#include <asm/mach/arch.h>
27#include <asm/mach/map.h>
28#include <asm/mach/irq.h>
29
30#include "core.h"
31
32static void __init aaed2000_init_irq(void)
33{
34 aaec2000_init_irq();
35}
36
37static void __init aaed2000_map_io(void)
38{
39 aaec2000_map_io();
40}
41
42MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform")
43 MAINTAINER("Nicolas Bellido Y Ortega")
44 BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE)
45 MAPIO(aaed2000_map_io)
46 INITIRQ(aaed2000_init_irq)
47 .timer = &aaec2000_timer,
48MACHINE_END
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
new file mode 100644
index 000000000000..fc145b3768fa
--- /dev/null
+++ b/arch/arm/mach-aaec2000/core.c
@@ -0,0 +1,157 @@
1/*
2 * linux/arch/arm/mach-aaec2000/core.c
3 *
4 * Code common to all AAEC-2000 machines
5 *
6 * Copyright (c) 2005 Nicolas Bellido Y Ortega
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/config.h>
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/interrupt.h>
19#include <linux/timex.h>
20#include <linux/signal.h>
21
22#include <asm/hardware.h>
23#include <asm/irq.h>
24
25#include <asm/mach/irq.h>
26#include <asm/mach/time.h>
27#include <asm/mach/map.h>
28
29/*
30 * Common I/O mapping:
31 *
32 * Static virtual address mappings are as follow:
33 *
34 * 0xf8000000-0xf8001ffff: Devices connected to APB bus
35 * 0xf8002000-0xf8003ffff: Devices connected to AHB bus
36 *
37 * Below 0xe8000000 is reserved for vm allocation.
38 *
39 * The machine specific code must provide the extra mapping beside the
40 * default mapping provided here.
41 */
42static struct map_desc standard_io_desc[] __initdata = {
43 /* virtual physical length type */
44 { VIO_APB_BASE, PIO_APB_BASE, IO_APB_LENGTH, MT_DEVICE },
45 { VIO_AHB_BASE, PIO_AHB_BASE, IO_AHB_LENGTH, MT_DEVICE }
46};
47
48void __init aaec2000_map_io(void)
49{
50 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
51}
52
53/*
54 * Interrupt handling routines
55 */
56static void aaec2000_int_ack(unsigned int irq)
57{
58 IRQ_INTSR = 1 << irq;
59}
60
61static void aaec2000_int_mask(unsigned int irq)
62{
63 IRQ_INTENC |= (1 << irq);
64}
65
66static void aaec2000_int_unmask(unsigned int irq)
67{
68 IRQ_INTENS |= (1 << irq);
69}
70
71static struct irqchip aaec2000_irq_chip = {
72 .ack = aaec2000_int_ack,
73 .mask = aaec2000_int_mask,
74 .unmask = aaec2000_int_unmask,
75};
76
77void __init aaec2000_init_irq(void)
78{
79 unsigned int i;
80
81 for (i = 0; i < NR_IRQS; i++) {
82 set_irq_handler(i, do_level_IRQ);
83 set_irq_chip(i, &aaec2000_irq_chip);
84 set_irq_flags(i, IRQF_VALID);
85 }
86
87 /* Disable all interrupts */
88 IRQ_INTENC = 0xffffffff;
89
90 /* Clear any pending interrupts */
91 IRQ_INTSR = IRQ_INTSR;
92}
93
94/*
95 * Time keeping
96 */
97/* IRQs are disabled before entering here from do_gettimeofday() */
98static unsigned long aaec2000_gettimeoffset(void)
99{
100 unsigned long ticks_to_match, elapsed, usec;
101
102 /* Get ticks before next timer match */
103 ticks_to_match = TIMER1_LOAD - TIMER1_VAL;
104
105 /* We need elapsed ticks since last match */
106 elapsed = LATCH - ticks_to_match;
107
108 /* Now, convert them to usec */
109 usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
110
111 return usec;
112}
113
114/* We enter here with IRQs enabled */
115static irqreturn_t
116aaec2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
117{
118 /* TODO: Check timer accuracy */
119 write_seqlock(&xtime_lock);
120
121 timer_tick(regs);
122 TIMER1_CLEAR = 1;
123
124 write_sequnlock(&xtime_lock);
125
126 return IRQ_HANDLED;
127}
128
129static struct irqaction aaec2000_timer_irq = {
130 .name = "AAEC-2000 Timer Tick",
131 .flags = SA_INTERRUPT,
132 .handler = aaec2000_timer_interrupt
133};
134
135static void __init aaec2000_timer_init(void)
136{
137 /* Disable timer 1 */
138 TIMER1_CTRL = 0;
139
140 /* We have somehow to generate a 100Hz clock.
141 * We then use the 508KHz timer in periodic mode.
142 */
143 TIMER1_LOAD = LATCH;
144 TIMER1_CLEAR = 1; /* Clear interrupt */
145
146 setup_irq(INT_TMR1_OFL, &aaec2000_timer_irq);
147
148 TIMER1_CTRL = TIMER_CTRL_ENABLE |
149 TIMER_CTRL_PERIODIC |
150 TIMER_CTRL_CLKSEL_508K;
151}
152
153struct sys_timer aaec2000_timer = {
154 .init = aaec2000_timer_init,
155 .offset = aaec2000_gettimeoffset,
156};
157
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
new file mode 100644
index 000000000000..91893d848c16
--- /dev/null
+++ b/arch/arm/mach-aaec2000/core.h
@@ -0,0 +1,16 @@
1/*
2 * linux/arch/arm/mach-aaec2000/core.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11
12struct sys_timer;
13
14extern struct sys_timer aaec2000_timer;
15extern void __init aaec2000_map_io(void);
16extern void __init aaec2000_init_irq(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index d302f0405fd2..bd1e5e3c9d34 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -227,7 +227,6 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
227 * primary CPU 227 * primary CPU
228 */ 228 */
229 if (hard_smp_processor_id() == 0) { 229 if (hard_smp_processor_id() == 0) {
230 nmi_tick();
231 timer_tick(regs); 230 timer_tick(regs);
232#ifdef CONFIG_SMP 231#ifdef CONFIG_SMP
233 smp_send_timer(); 232 smp_send_timer();
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 4f3c3d5c781c..fc0555596d6d 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -162,12 +162,13 @@ void __init ixp2000_map_io(void)
162static unsigned ticks_per_jiffy; 162static unsigned ticks_per_jiffy;
163static unsigned ticks_per_usec; 163static unsigned ticks_per_usec;
164static unsigned next_jiffy_time; 164static unsigned next_jiffy_time;
165static volatile unsigned long *missing_jiffy_timer_csr;
165 166
166unsigned long ixp2000_gettimeoffset (void) 167unsigned long ixp2000_gettimeoffset (void)
167{ 168{
168 unsigned long offset; 169 unsigned long offset;
169 170
170 offset = next_jiffy_time - *IXP2000_T4_CSR; 171 offset = next_jiffy_time - *missing_jiffy_timer_csr;
171 172
172 return offset / ticks_per_usec; 173 return offset / ticks_per_usec;
173} 174}
@@ -179,7 +180,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
179 /* clear timer 1 */ 180 /* clear timer 1 */
180 ixp2000_reg_write(IXP2000_T1_CLR, 1); 181 ixp2000_reg_write(IXP2000_T1_CLR, 1);
181 182
182 while ((next_jiffy_time - *IXP2000_T4_CSR) > ticks_per_jiffy) { 183 while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
183 timer_tick(regs); 184 timer_tick(regs);
184 next_jiffy_time -= ticks_per_jiffy; 185 next_jiffy_time -= ticks_per_jiffy;
185 } 186 }
@@ -197,20 +198,37 @@ static struct irqaction ixp2000_timer_irq = {
197 198
198void __init ixp2000_init_time(unsigned long tick_rate) 199void __init ixp2000_init_time(unsigned long tick_rate)
199{ 200{
200 ixp2000_reg_write(IXP2000_T1_CLR, 0);
201 ixp2000_reg_write(IXP2000_T4_CLR, 0);
202
203 ticks_per_jiffy = (tick_rate + HZ/2) / HZ; 201 ticks_per_jiffy = (tick_rate + HZ/2) / HZ;
204 ticks_per_usec = tick_rate / 1000000; 202 ticks_per_usec = tick_rate / 1000000;
205 203
204 /*
205 * We use timer 1 as our timer interrupt.
206 */
207 ixp2000_reg_write(IXP2000_T1_CLR, 0);
206 ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1); 208 ixp2000_reg_write(IXP2000_T1_CLD, ticks_per_jiffy - 1);
207 ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7)); 209 ixp2000_reg_write(IXP2000_T1_CTL, (1 << 7));
208 210
209 /* 211 /*
210 * We use T4 as a monotonic counter to track missed jiffies 212 * We use a second timer as a monotonic counter for tracking
213 * missed jiffies. The IXP2000 has four timers, but if we're
214 * on an A-step IXP2800, timer 2 and 3 don't work, so on those
215 * chips we use timer 4. Timer 4 is the only timer that can
216 * be used for the watchdog, so we use timer 2 if we're on a
217 * non-buggy chip.
211 */ 218 */
212 ixp2000_reg_write(IXP2000_T4_CLD, -1); 219 if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
213 ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7)); 220 printk(KERN_INFO "Enabling IXP2800 erratum #25 workaround\n");
221
222 ixp2000_reg_write(IXP2000_T4_CLR, 0);
223 ixp2000_reg_write(IXP2000_T4_CLD, -1);
224 ixp2000_reg_write(IXP2000_T4_CTL, (1 << 7));
225 missing_jiffy_timer_csr = IXP2000_T4_CSR;
226 } else {
227 ixp2000_reg_write(IXP2000_T2_CLR, 0);
228 ixp2000_reg_write(IXP2000_T2_CLD, -1);
229 ixp2000_reg_write(IXP2000_T2_CTL, (1 << 7));
230 missing_jiffy_timer_csr = IXP2000_T2_CSR;
231 }
214 next_jiffy_time = 0xffffffff; 232 next_jiffy_time = 0xffffffff;
215 233
216 /* register for interrupt */ 234 /* register for interrupt */
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
index 5d608837757a..ba81e70ed813 100644
--- a/arch/arm/mach-versatile/Makefile
+++ b/arch/arm/mach-versatile/Makefile
@@ -5,3 +5,4 @@
5obj-y := core.o clock.o 5obj-y := core.o clock.o
6obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o 6obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o
7obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o 7obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o
8obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 302c2a7b9b63..6a7cbea5e098 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -196,11 +196,15 @@ static struct map_desc versatile_io_desc[] __initdata = {
196#ifdef CONFIG_DEBUG_LL 196#ifdef CONFIG_DEBUG_LL
197 { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE }, 197 { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE },
198#endif 198#endif
199#ifdef FIXME 199#ifdef CONFIG_PCI
200 { PCI_MEMORY_VADDR, PHYS_PCI_MEM_BASE, SZ_16M, MT_DEVICE }, 200 { IO_ADDRESS(VERSATILE_PCI_CORE_BASE), VERSATILE_PCI_CORE_BASE, SZ_4K, MT_DEVICE },
201 { PCI_CONFIG_VADDR, PHYS_PCI_CONFIG_BASE, SZ_16M, MT_DEVICE }, 201 { VERSATILE_PCI_VIRT_BASE, VERSATILE_PCI_BASE, VERSATILE_PCI_BASE_SIZE, MT_DEVICE },
202 { PCI_V3_VADDR, PHYS_PCI_V3_BASE, SZ_512K, MT_DEVICE }, 202 { VERSATILE_PCI_CFG_VIRT_BASE, VERSATILE_PCI_CFG_BASE, VERSATILE_PCI_CFG_BASE_SIZE, MT_DEVICE },
203 { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE }, 203#if 0
204 { VERSATILE_PCI_VIRT_MEM_BASE0, VERSATILE_PCI_MEM_BASE0, SZ_16M, MT_DEVICE },
205 { VERSATILE_PCI_VIRT_MEM_BASE1, VERSATILE_PCI_MEM_BASE1, SZ_16M, MT_DEVICE },
206 { VERSATILE_PCI_VIRT_MEM_BASE2, VERSATILE_PCI_MEM_BASE2, SZ_16M, MT_DEVICE },
207#endif
204#endif 208#endif
205}; 209};
206 210
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
new file mode 100644
index 000000000000..d1565e851f0e
--- /dev/null
+++ b/arch/arm/mach-versatile/pci.c
@@ -0,0 +1,360 @@
1/*
2 * linux/arch/arm/mach-versatile/pci.c
3 *
4 * (C) Copyright Koninklijke Philips Electronics NV 2004. All rights reserved.
5 * You can redistribute and/or modify this software under the terms of version 2
6 * of the GNU General Public License as published by the Free Software Foundation.
7 * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
8 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 * General Public License for more details.
10 * Koninklijke Philips Electronics nor its subsidiaries is obligated to provide any support for this software.
11 *
12 * ARM Versatile PCI driver.
13 *
14 * 14/04/2005 Initial version, colin.king@philips.com
15 *
16 */
17#include <linux/config.h>
18#include <linux/kernel.h>
19#include <linux/pci.h>
20#include <linux/ptrace.h>
21#include <linux/slab.h>
22#include <linux/ioport.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/init.h>
26
27#include <asm/hardware.h>
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/system.h>
31#include <asm/mach/pci.h>
32#include <asm/mach-types.h>
33
34/*
35 * these spaces are mapped using the following base registers:
36 *
37 * Usage Local Bus Memory Base/Map registers used
38 *
39 * Mem 50000000 - 5FFFFFFF LB_BASE0/LB_MAP0, non prefetch
40 * Mem 60000000 - 6FFFFFFF LB_BASE1/LB_MAP1, prefetch
41 * IO 44000000 - 4FFFFFFF LB_BASE2/LB_MAP2, IO
42 * Cfg 42000000 - 42FFFFFF PCI config
43 *
44 */
45#define SYS_PCICTL IO_ADDRESS(VERSATILE_SYS_PCICTL)
46#define PCI_IMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
47#define PCI_IMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
48#define PCI_IMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
49#define PCI_SMAP0 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
50#define PCI_SMAP1 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
51#define PCI_SMAP2 IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
52#define PCI_SELFID IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
53
54#define DEVICE_ID_OFFSET 0x00
55#define CSR_OFFSET 0x04
56#define CLASS_ID_OFFSET 0x08
57
58#define VP_PCI_DEVICE_ID 0x030010ee
59#define VP_PCI_CLASS_ID 0x0b400000
60
61static unsigned long pci_slot_ignore = 0;
62
63static int __init versatile_pci_slot_ignore(char *str)
64{
65 int retval;
66 int slot;
67
68 while ((retval = get_option(&str,&slot))) {
69 if ((slot < 0) || (slot > 31)) {
70 printk("Illegal slot value: %d\n",slot);
71 } else {
72 pci_slot_ignore |= (1 << slot);
73 }
74 }
75 return 1;
76}
77
78__setup("pci_slot_ignore=", versatile_pci_slot_ignore);
79
80
81static unsigned long __pci_addr(struct pci_bus *bus,
82 unsigned int devfn, int offset)
83{
84 unsigned int busnr = bus->number;
85
86 /*
87 * Trap out illegal values
88 */
89 if (offset > 255)
90 BUG();
91 if (busnr > 255)
92 BUG();
93 if (devfn > 255)
94 BUG();
95
96 return (VERSATILE_PCI_CFG_VIRT_BASE | (busnr << 16) |
97 (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) | offset);
98}
99
100static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int where,
101 int size, u32 *val)
102{
103 unsigned long addr = __pci_addr(bus, devfn, where);
104 u32 v;
105 int slot = PCI_SLOT(devfn);
106
107 if (pci_slot_ignore & (1 << slot)) {
108 /* Ignore this slot */
109 switch (size) {
110 case 1:
111 v = 0xff;
112 break;
113 case 2:
114 v = 0xffff;
115 break;
116 default:
117 v = 0xffffffff;
118 }
119 } else {
120 switch (size) {
121 case 1:
122 addr &= ~3;
123 v = __raw_readb(addr);
124 break;
125
126 case 2:
127 v = __raw_readl(addr & ~3);
128 if (addr & 2) v >>= 16;
129 v &= 0xffff;
130 break;
131
132 default:
133 addr &= ~3;
134 v = __raw_readl(addr);
135 break;
136 }
137 }
138
139 *val = v;
140 return PCIBIOS_SUCCESSFUL;
141}
142
143static int versatile_write_config(struct pci_bus *bus, unsigned int devfn, int where,
144 int size, u32 val)
145{
146 unsigned long addr = __pci_addr(bus, devfn, where);
147 int slot = PCI_SLOT(devfn);
148
149 if (pci_slot_ignore & (1 << slot)) {
150 return PCIBIOS_SUCCESSFUL;
151 }
152
153 switch (size) {
154 case 1:
155 __raw_writeb((u8)val, addr);
156 break;
157
158 case 2:
159 __raw_writew((u16)val, addr);
160 break;
161
162 case 4:
163 __raw_writel(val, addr);
164 break;
165 }
166
167 return PCIBIOS_SUCCESSFUL;
168}
169
170static struct pci_ops pci_versatile_ops = {
171 .read = versatile_read_config,
172 .write = versatile_write_config,
173};
174
175static struct resource io_mem = {
176 .name = "PCI I/O space",
177 .start = VERSATILE_PCI_MEM_BASE0,
178 .end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
179 .flags = IORESOURCE_IO,
180};
181
182static struct resource non_mem = {
183 .name = "PCI non-prefetchable",
184 .start = VERSATILE_PCI_MEM_BASE1,
185 .end = VERSATILE_PCI_MEM_BASE1+VERSATILE_PCI_MEM_BASE1_SIZE-1,
186 .flags = IORESOURCE_MEM,
187};
188
189static struct resource pre_mem = {
190 .name = "PCI prefetchable",
191 .start = VERSATILE_PCI_MEM_BASE2,
192 .end = VERSATILE_PCI_MEM_BASE2+VERSATILE_PCI_MEM_BASE2_SIZE-1,
193 .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,
194};
195
196static int __init pci_versatile_setup_resources(struct resource **resource)
197{
198 int ret = 0;
199
200 ret = request_resource(&iomem_resource, &io_mem);
201 if (ret) {
202 printk(KERN_ERR "PCI: unable to allocate I/O "
203 "memory region (%d)\n", ret);
204 goto out;
205 }
206 ret = request_resource(&iomem_resource, &non_mem);
207 if (ret) {
208 printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
209 "memory region (%d)\n", ret);
210 goto release_io_mem;
211 }
212 ret = request_resource(&iomem_resource, &pre_mem);
213 if (ret) {
214 printk(KERN_ERR "PCI: unable to allocate prefetchable "
215 "memory region (%d)\n", ret);
216 goto release_non_mem;
217 }
218
219 /*
220 * bus->resource[0] is the IO resource for this bus
221 * bus->resource[1] is the mem resource for this bus
222 * bus->resource[2] is the prefetch mem resource for this bus
223 */
224 resource[0] = &io_mem;
225 resource[1] = &non_mem;
226 resource[2] = &pre_mem;
227
228 goto out;
229
230 release_non_mem:
231 release_resource(&non_mem);
232 release_io_mem:
233 release_resource(&io_mem);
234 out:
235 return ret;
236}
237
238int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
239{
240 int ret = 0;
241 int i;
242 int myslot = -1;
243 unsigned long val;
244
245 if (nr == 0) {
246 sys->mem_offset = 0;
247 ret = pci_versatile_setup_resources(sys->resource);
248 if (ret < 0) {
249 printk("pci_versatile_setup: resources... oops?\n");
250 goto out;
251 }
252 } else {
253 printk("pci_versatile_setup: resources... nr == 0??\n");
254 goto out;
255 }
256
257 __raw_writel(VERSATILE_PCI_MEM_BASE0 >> 28,PCI_IMAP0);
258 __raw_writel(VERSATILE_PCI_MEM_BASE1 >> 28,PCI_IMAP1);
259 __raw_writel(VERSATILE_PCI_MEM_BASE2 >> 28,PCI_IMAP2);
260
261 __raw_writel(1, SYS_PCICTL);
262
263 val = __raw_readl(SYS_PCICTL);
264 if (!(val & 1)) {
265 printk("Not plugged into PCI backplane!\n");
266 ret = -EIO;
267 goto out;
268 }
269
270 /*
271 * We need to discover the PCI core first to configure itself
272 * before the main PCI probing is performed
273 */
274 for (i=0; i<32; i++) {
275 if ((__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+DEVICE_ID_OFFSET) == VP_PCI_DEVICE_ID) &&
276 (__raw_readl(VERSATILE_PCI_VIRT_BASE+(i<<11)+CLASS_ID_OFFSET) == VP_PCI_CLASS_ID)) {
277 myslot = i;
278
279 __raw_writel(myslot, PCI_SELFID);
280 val = __raw_readl(VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
281 val |= (1<<2);
282 __raw_writel(val, VERSATILE_PCI_CFG_VIRT_BASE+(myslot<<11)+CSR_OFFSET);
283 break;
284 }
285 }
286
287 if (myslot == -1) {
288 printk("Cannot find PCI core!\n");
289 ret = -EIO;
290 } else {
291 printk("PCI core found (slot %d)\n",myslot);
292 /* Do not to map Versatile FPGA PCI device
293 into memory space as we are short of
294 mappable memory */
295 pci_slot_ignore |= (1 << myslot);
296 ret = 1;
297 }
298
299 out:
300 return ret;
301}
302
303
304struct pci_bus *pci_versatile_scan_bus(int nr, struct pci_sys_data *sys)
305{
306 return pci_scan_bus(sys->busnr, &pci_versatile_ops, sys);
307}
308
309/*
310 * V3_LB_BASE? - local bus address
311 * V3_LB_MAP? - pci bus address
312 */
313void __init pci_versatile_preinit(void)
314{
315}
316
317void __init pci_versatile_postinit(void)
318{
319}
320
321
322/*
323 * map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this.
324 */
325static int __init versatile_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
326{
327 int irq;
328 int devslot = PCI_SLOT(dev->devfn);
329
330 /* slot, pin, irq
331 24 1 27
332 25 1 28 untested
333 26 1 29
334 27 1 30 untested
335 */
336
337 irq = 27 + ((slot + pin + 2) % 3); /* Fudged */
338
339 printk("map irq: slot %d, pin %d, devslot %d, irq: %d\n",slot,pin,devslot,irq);
340
341 return irq;
342}
343
344static struct hw_pci versatile_pci __initdata = {
345 .swizzle = NULL,
346 .map_irq = versatile_map_irq,
347 .nr_controllers = 1,
348 .setup = pci_versatile_setup,
349 .scan = pci_versatile_scan_bus,
350 .preinit = pci_versatile_preinit,
351 .postinit = pci_versatile_postinit,
352};
353
354static int __init versatile_pci_init(void)
355{
356 pci_common_init(&versatile_pci);
357 return 0;
358}
359
360subsys_initcall(versatile_pci_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 3fefb43c67f7..95606b4a3ba6 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -62,7 +62,7 @@ config CPU_ARM720T
62# ARM920T 62# ARM920T
63config CPU_ARM920T 63config CPU_ARM920T
64 bool "Support ARM920T processor" if !ARCH_S3C2410 64 bool "Support ARM920T processor" if !ARCH_S3C2410
65 depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX 65 depends on ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000
66 default y if ARCH_S3C2410 66 default y if ARCH_S3C2410
67 select CPU_32v4 67 select CPU_32v4
68 select CPU_ABRT_EV4T 68 select CPU_ABRT_EV4T
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index a8c00236bd3d..27d041574ea7 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -30,8 +30,6 @@
30 30
31static DEFINE_SPINLOCK(v6_lock); 31static DEFINE_SPINLOCK(v6_lock);
32 32
33#define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
34
35/* 33/*
36 * Copy the user page. No aliasing to deal with so we can just 34 * Copy the user page. No aliasing to deal with so we can just
37 * attack the kernel's existing mapping of these pages. 35 * attack the kernel's existing mapping of these pages.
@@ -55,7 +53,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
55 */ 53 */
56void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr) 54void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
57{ 55{
58 unsigned int offset = DCACHE_COLOUR(vaddr); 56 unsigned int offset = CACHE_COLOUR(vaddr);
59 unsigned long from, to; 57 unsigned long from, to;
60 58
61 /* 59 /*
@@ -95,7 +93,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
95 */ 93 */
96void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr) 94void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
97{ 95{
98 unsigned int offset = DCACHE_COLOUR(vaddr); 96 unsigned int offset = CACHE_COLOUR(vaddr);
99 unsigned long to = to_address + (offset << PAGE_SHIFT); 97 unsigned long to = to_address + (offset << PAGE_SHIFT);
100 98
101 /* 99 /*
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 01967ddeef53..be4ab3d73c91 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -77,9 +77,8 @@ no_pmd:
77} 77}
78 78
79static void 79static void
80make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty) 80make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigned long addr, unsigned long pfn)
81{ 81{
82 struct address_space *mapping = page_mapping(page);
83 struct mm_struct *mm = vma->vm_mm; 82 struct mm_struct *mm = vma->vm_mm;
84 struct vm_area_struct *mpnt; 83 struct vm_area_struct *mpnt;
85 struct prio_tree_iter iter; 84 struct prio_tree_iter iter;
@@ -87,9 +86,6 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
87 pgoff_t pgoff; 86 pgoff_t pgoff;
88 int aliases = 0; 87 int aliases = 0;
89 88
90 if (!mapping)
91 return;
92
93 pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT); 89 pgoff = vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT);
94 90
95 /* 91 /*
@@ -115,9 +111,11 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
115 if (aliases) 111 if (aliases)
116 adjust_pte(vma, addr); 112 adjust_pte(vma, addr);
117 else 113 else
118 flush_cache_page(vma, addr, page_to_pfn(page)); 114 flush_cache_page(vma, addr, pfn);
119} 115}
120 116
117void __flush_dcache_page(struct address_space *mapping, struct page *page);
118
121/* 119/*
122 * Take care of architecture specific things when placing a new PTE into 120 * Take care of architecture specific things when placing a new PTE into
123 * a page table, or changing an existing PTE. Basically, there are two 121 * a page table, or changing an existing PTE. Basically, there are two
@@ -134,29 +132,22 @@ make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page,
134void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) 132void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
135{ 133{
136 unsigned long pfn = pte_pfn(pte); 134 unsigned long pfn = pte_pfn(pte);
135 struct address_space *mapping;
137 struct page *page; 136 struct page *page;
138 137
139 if (!pfn_valid(pfn)) 138 if (!pfn_valid(pfn))
140 return; 139 return;
140
141 page = pfn_to_page(pfn); 141 page = pfn_to_page(pfn);
142 if (page_mapping(page)) { 142 mapping = page_mapping(page);
143 if (mapping) {
143 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); 144 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
144 145
145 if (dirty) { 146 if (dirty)
146 /* 147 __flush_dcache_page(mapping, page);
147 * This is our first userspace mapping of this page.
148 * Ensure that the physical page is coherent with
149 * the kernel mapping.
150 *
151 * FIXME: only need to do this on VIVT and aliasing
152 * VIPT cache architectures. We can do that
153 * by choosing whether to set this bit...
154 */
155 __cpuc_flush_dcache_page(page_address(page));
156 }
157 148
158 if (cache_is_vivt()) 149 if (cache_is_vivt())
159 make_coherent(vma, addr, page, dirty); 150 make_coherent(mapping, vma, addr, pfn);
160 } 151 }
161} 152}
162 153
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 4085ed983e46..191788fb18d1 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -37,13 +37,8 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
37#define flush_pfn_alias(pfn,vaddr) do { } while (0) 37#define flush_pfn_alias(pfn,vaddr) do { } while (0)
38#endif 38#endif
39 39
40static void __flush_dcache_page(struct address_space *mapping, struct page *page) 40void __flush_dcache_page(struct address_space *mapping, struct page *page)
41{ 41{
42 struct mm_struct *mm = current->active_mm;
43 struct vm_area_struct *mpnt;
44 struct prio_tree_iter iter;
45 pgoff_t pgoff;
46
47 /* 42 /*
48 * Writeback any data associated with the kernel mapping of this 43 * Writeback any data associated with the kernel mapping of this
49 * page. This ensures that data in the physical page is mutually 44 * page. This ensures that data in the physical page is mutually
@@ -52,24 +47,21 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
52 __cpuc_flush_dcache_page(page_address(page)); 47 __cpuc_flush_dcache_page(page_address(page));
53 48
54 /* 49 /*
55 * If there's no mapping pointer here, then this page isn't 50 * If this is a page cache page, and we have an aliasing VIPT cache,
56 * visible to userspace yet, so there are no cache lines 51 * we only need to do one flush - which would be at the relevant
57 * associated with any other aliases.
58 */
59 if (!mapping)
60 return;
61
62 /*
63 * This is a page cache page. If we have a VIPT cache, we
64 * only need to do one flush - which would be at the relevant
65 * userspace colour, which is congruent with page->index. 52 * userspace colour, which is congruent with page->index.
66 */ 53 */
67 if (cache_is_vipt()) { 54 if (mapping && cache_is_vipt_aliasing())
68 if (cache_is_vipt_aliasing()) 55 flush_pfn_alias(page_to_pfn(page),
69 flush_pfn_alias(page_to_pfn(page), 56 page->index << PAGE_CACHE_SHIFT);
70 page->index << PAGE_CACHE_SHIFT); 57}
71 return; 58
72 } 59static void __flush_dcache_aliases(struct address_space *mapping, struct page *page)
60{
61 struct mm_struct *mm = current->active_mm;
62 struct vm_area_struct *mpnt;
63 struct prio_tree_iter iter;
64 pgoff_t pgoff;
73 65
74 /* 66 /*
75 * There are possible user space mappings of this page: 67 * There are possible user space mappings of this page:
@@ -116,12 +108,12 @@ void flush_dcache_page(struct page *page)
116{ 108{
117 struct address_space *mapping = page_mapping(page); 109 struct address_space *mapping = page_mapping(page);
118 110
119 if (cache_is_vipt_nonaliasing())
120 return;
121
122 if (mapping && !mapping_mapped(mapping)) 111 if (mapping && !mapping_mapped(mapping))
123 set_bit(PG_dcache_dirty, &page->flags); 112 set_bit(PG_dcache_dirty, &page->flags);
124 else 113 else {
125 __flush_dcache_page(mapping, page); 114 __flush_dcache_page(mapping, page);
115 if (mapping && cache_is_vivt())
116 __flush_dcache_aliases(mapping, page);
117 }
126} 118}
127EXPORT_SYMBOL(flush_dcache_page); 119EXPORT_SYMBOL(flush_dcache_page);
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 00bb8fd37a59..7110e54182b1 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -170,3 +170,50 @@ void __iounmap(void __iomem *addr)
170 vfree((void *) (PAGE_MASK & (unsigned long) addr)); 170 vfree((void *) (PAGE_MASK & (unsigned long) addr));
171} 171}
172EXPORT_SYMBOL(__iounmap); 172EXPORT_SYMBOL(__iounmap);
173
174#ifdef __io
175void __iomem *ioport_map(unsigned long port, unsigned int nr)
176{
177 return __io(port);
178}
179EXPORT_SYMBOL(ioport_map);
180
181void ioport_unmap(void __iomem *addr)
182{
183}
184EXPORT_SYMBOL(ioport_unmap);
185#endif
186
187#ifdef CONFIG_PCI
188#include <linux/pci.h>
189#include <linux/ioport.h>
190
191void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
192{
193 unsigned long start = pci_resource_start(dev, bar);
194 unsigned long len = pci_resource_len(dev, bar);
195 unsigned long flags = pci_resource_flags(dev, bar);
196
197 if (!len || !start)
198 return NULL;
199 if (maxlen && len > maxlen)
200 len = maxlen;
201 if (flags & IORESOURCE_IO)
202 return ioport_map(start, len);
203 if (flags & IORESOURCE_MEM) {
204 if (flags & IORESOURCE_CACHEABLE)
205 return ioremap(start, len);
206 return ioremap_nocache(start, len);
207 }
208 return NULL;
209}
210EXPORT_SYMBOL(pci_iomap);
211
212void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
213{
214 if ((unsigned long)addr >= VMALLOC_START &&
215 (unsigned long)addr < VMALLOC_END)
216 iounmap(addr);
217}
218EXPORT_SYMBOL(pci_iounmap);
219#endif
diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c
index 344164681d2c..8316426ccaf6 100644
--- a/arch/ppc64/kernel/iommu.c
+++ b/arch/ppc64/kernel/iommu.c
@@ -423,6 +423,9 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl)
423 tbl->it_largehint = tbl->it_halfpoint; 423 tbl->it_largehint = tbl->it_halfpoint;
424 spin_lock_init(&tbl->it_lock); 424 spin_lock_init(&tbl->it_lock);
425 425
426 /* Clear the hardware table in case firmware left allocations in it */
427 ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
428
426 if (!welcomed) { 429 if (!welcomed) {
427 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", 430 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
428 novmerge ? "disabled" : "enabled"); 431 novmerge ? "disabled" : "enabled");
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index fbad349ec58c..4203bd020c82 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -375,7 +375,7 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
375 * cpus are assumed to be secondary threads. 375 * cpus are assumed to be secondary threads.
376 */ 376 */
377 if (system_state < SYSTEM_RUNNING && 377 if (system_state < SYSTEM_RUNNING &&
378 cur_cpu_spec->cpu_features & CPU_FTR_SMT && 378 cpu_has_feature(CPU_FTR_SMT) &&
379 !smt_enabled_at_boot && nr % 2 != 0) 379 !smt_enabled_at_boot && nr % 2 != 0)
380 return 0; 380 return 0;
381 381
@@ -419,8 +419,8 @@ void __init smp_init_pSeries(void)
419#endif 419#endif
420 420
421 /* Mark threads which are still spinning in hold loops. */ 421 /* Mark threads which are still spinning in hold loops. */
422 if (cur_cpu_spec->cpu_features & CPU_FTR_SMT) 422 if (cpu_has_feature(CPU_FTR_SMT)) {
423 for_each_present_cpu(i) { 423 for_each_present_cpu(i) {
424 if (i % 2 == 0) 424 if (i % 2 == 0)
425 /* 425 /*
426 * Even-numbered logical cpus correspond to 426 * Even-numbered logical cpus correspond to
@@ -428,8 +428,9 @@ void __init smp_init_pSeries(void)
428 */ 428 */
429 cpu_set(i, of_spin_map); 429 cpu_set(i, of_spin_map);
430 } 430 }
431 else 431 } else {
432 of_spin_map = cpu_present_map; 432 of_spin_map = cpu_present_map;
433 }
433 434
434 cpu_clear(boot_cpuid, of_spin_map); 435 cpu_clear(boot_cpuid, of_spin_map);
435 436
diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
index ff65dc33320e..b0c3b829fe47 100644
--- a/arch/ppc64/kernel/rtasd.c
+++ b/arch/ppc64/kernel/rtasd.c
@@ -440,7 +440,7 @@ static int rtasd(void *unused)
440 goto error; 440 goto error;
441 } 441 }
442 442
443 printk(KERN_ERR "RTAS daemon started\n"); 443 printk(KERN_INFO "RTAS daemon started\n");
444 444
445 DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2); 445 DEBUG("will sleep for %d jiffies\n", (HZ*60/rtas_event_scan_rate) / 2);
446 446
@@ -485,7 +485,7 @@ static int __init rtas_init(void)
485 /* No RTAS, only warn if we are on a pSeries box */ 485 /* No RTAS, only warn if we are on a pSeries box */
486 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { 486 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
487 if (systemcfg->platform & PLATFORM_PSERIES) 487 if (systemcfg->platform & PLATFORM_PSERIES)
488 printk(KERN_ERR "rtasd: no event-scan on system\n"); 488 printk(KERN_INFO "rtasd: no event-scan on system\n");
489 return 1; 489 return 1;
490 } 490 }
491 491
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index ab659d37b4d2..4e98c215e5b1 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -192,7 +192,12 @@ static struct miscdevice ixp2000_wdt_miscdev =
192 192
193static int __init ixp2000_wdt_init(void) 193static int __init ixp2000_wdt_init(void)
194{ 194{
195 wdt_tick_rate = (*IXP2000_T1_CLD * HZ)/ 256;; 195 if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) {
196 printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n");
197 return -EIO;
198 }
199
200 wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256;
196 201
197 return misc_register(&ixp2000_wdt_miscdev); 202 return misc_register(&ixp2000_wdt_miscdev);
198} 203}
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index fbd9ff79b7b8..e3c958823533 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -765,8 +765,6 @@ void fcp_release(fc_channel *fcchain, int count) /* count must > 0 */
765 765
766static void fcp_scsi_done (Scsi_Cmnd *SCpnt) 766static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
767{ 767{
768 unsigned long flags;
769
770 if (FCP_CMND(SCpnt)->done) 768 if (FCP_CMND(SCpnt)->done)
771 FCP_CMND(SCpnt)->done(SCpnt); 769 FCP_CMND(SCpnt)->done(SCpnt);
772} 770}
@@ -907,8 +905,6 @@ int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
907 */ 905 */
908 906
909 if (++fc->abort_count < (fc->can_queue >> 1)) { 907 if (++fc->abort_count < (fc->can_queue >> 1)) {
910 unsigned long flags;
911
912 SCpnt->result = DID_ABORT; 908 SCpnt->result = DID_ABORT;
913 fcmd->done(SCpnt); 909 fcmd->done(SCpnt);
914 printk("FC: soft abort\n"); 910 printk("FC: soft abort\n");
@@ -931,6 +927,7 @@ void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt)
931 927
932int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) 928int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
933{ 929{
930 unsigned long flags;
934 fcp_cmd *cmd; 931 fcp_cmd *cmd;
935 fcp_cmnd *fcmd; 932 fcp_cmnd *fcmd;
936 fc_channel *fc = FC_SCMND(SCpnt); 933 fc_channel *fc = FC_SCMND(SCpnt);
@@ -1028,6 +1025,7 @@ static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
1028 1025
1029int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) 1026int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
1030{ 1027{
1028 unsigned long flags;
1031 int rc; 1029 int rc;
1032 1030
1033 spin_lock_irqsave(SCpnt->device->host->host_lock, flags); 1031 spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index c4eaaad2c69b..5f526dd0aaa1 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -941,7 +941,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
941 */ 941 */
942 cmd->scsi_done = scsi_done; 942 cmd->scsi_done = scsi_done;
943 943
944 ahd_lock(ahd, &flags); 944 ahd_midlayer_entrypoint_lock(ahd, &flags);
945 945
946 /* 946 /*
947 * Close the race of a command that was in the process of 947 * Close the race of a command that was in the process of
@@ -955,7 +955,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
955 ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); 955 ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ);
956 ahd_linux_queue_cmd_complete(ahd, cmd); 956 ahd_linux_queue_cmd_complete(ahd, cmd);
957 ahd_schedule_completeq(ahd); 957 ahd_schedule_completeq(ahd);
958 ahd_unlock(ahd, &flags); 958 ahd_midlayer_entrypoint_unlock(ahd, &flags);
959 return (0); 959 return (0);
960 } 960 }
961 dev = ahd_linux_get_device(ahd, cmd->device->channel, 961 dev = ahd_linux_get_device(ahd, cmd->device->channel,
@@ -965,7 +965,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
965 ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL); 965 ahd_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL);
966 ahd_linux_queue_cmd_complete(ahd, cmd); 966 ahd_linux_queue_cmd_complete(ahd, cmd);
967 ahd_schedule_completeq(ahd); 967 ahd_schedule_completeq(ahd);
968 ahd_unlock(ahd, &flags); 968 ahd_midlayer_entrypoint_unlock(ahd, &flags);
969 printf("%s: aic79xx_linux_queue - Unable to allocate device!\n", 969 printf("%s: aic79xx_linux_queue - Unable to allocate device!\n",
970 ahd_name(ahd)); 970 ahd_name(ahd));
971 return (0); 971 return (0);
@@ -979,7 +979,7 @@ ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *))
979 dev->flags |= AHD_DEV_ON_RUN_LIST; 979 dev->flags |= AHD_DEV_ON_RUN_LIST;
980 ahd_linux_run_device_queues(ahd); 980 ahd_linux_run_device_queues(ahd);
981 } 981 }
982 ahd_unlock(ahd, &flags); 982 ahd_midlayer_entrypoint_unlock(ahd, &flags);
983 return (0); 983 return (0);
984} 984}
985 985
diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
new file mode 100644
index 000000000000..0e9b7e18af05
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/aaec2000.h
@@ -0,0 +1,151 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/aaec2000.h
3 *
4 * AAEC-2000 registers definition
5 *
6 * Copyright (c) 2005 Nicolas Bellido Y Ortega
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ASM_ARCH_AAEC2000_H
14#define __ASM_ARCH_AAEC2000_H
15
16#ifndef __ASM_ARCH_HARDWARE_H
17#error You must include hardware.h not this file
18#endif /* __ASM_ARCH_HARDWARE_H */
19
20/* Interrupt controller */
21#define IRQ_BASE __REG(0x80000500)
22#define IRQ_INTSR __REG(0x80000500) /* Int Status Register */
23#define IRQ_INTRSR __REG(0x80000504) /* Int Raw (unmasked) Status */
24#define IRQ_INTENS __REG(0x80000508) /* Int Enable Set */
25#define IRQ_INTENC __REG(0x8000050c) /* Int Enable Clear */
26
27/* UART 1 */
28#define UART1_BASE __REG(0x80000600)
29#define UART1_DR __REG(0x80000600) /* Data/FIFO Register */
30#define UART1_LCR __REG(0x80000604) /* Link Control Register */
31#define UART1_BRCR __REG(0x80000608) /* Baud Rate Control Register */
32#define UART1_CR __REG(0x8000060c) /* Control Register */
33#define UART1_SR __REG(0x80000610) /* Status Register */
34#define UART1_INT __REG(0x80000614) /* Interrupt Status Register */
35#define UART1_INTM __REG(0x80000618) /* Interrupt Mask Register */
36#define UART1_INTRES __REG(0x8000061c) /* Int Result (masked status) Register */
37
38/* UART 2 */
39#define UART2_BASE __REG(0x80000700)
40#define UART2_DR __REG(0x80000700) /* Data/FIFO Register */
41#define UART2_LCR __REG(0x80000704) /* Link Control Register */
42#define UART2_BRCR __REG(0x80000708) /* Baud Rate Control Register */
43#define UART2_CR __REG(0x8000070c) /* Control Register */
44#define UART2_SR __REG(0x80000710) /* Status Register */
45#define UART2_INT __REG(0x80000714) /* Interrupt Status Register */
46#define UART2_INTM __REG(0x80000718) /* Interrupt Mask Register */
47#define UART2_INTRES __REG(0x8000071c) /* Int Result (masked status) Register */
48
49/* UART 3 */
50#define UART3_BASE __REG(0x80000800)
51#define UART3_DR __REG(0x80000800) /* Data/FIFO Register */
52#define UART3_LCR __REG(0x80000804) /* Link Control Register */
53#define UART3_BRCR __REG(0x80000808) /* Baud Rate Control Register */
54#define UART3_CR __REG(0x8000080c) /* Control Register */
55#define UART3_SR __REG(0x80000810) /* Status Register */
56#define UART3_INT __REG(0x80000814) /* Interrupt Status Register */
57#define UART3_INTM __REG(0x80000818) /* Interrupt Mask Register */
58#define UART3_INTRES __REG(0x8000081c) /* Int Result (masked status) Register */
59
60/* These are used in some places */
61#define _UART1_BASE __PREG(UART1_BASE)
62#define _UART2_BASE __PREG(UART2_BASE)
63#define _UART3_BASE __PREG(UART3_BASE)
64
65/* UART Registers Offsets */
66#define UART_DR 0x00
67#define UART_LCR 0x04
68#define UART_BRCR 0x08
69#define UART_CR 0x0c
70#define UART_SR 0x10
71#define UART_INT 0x14
72#define UART_INTM 0x18
73#define UART_INTRES 0x1c
74
75/* UART_LCR Bitmask */
76#define UART_LCR_BRK (1 << 0) /* Send Break */
77#define UART_LCR_PEN (1 << 1) /* Parity Enable */
78#define UART_LCR_EP (1 << 2) /* Even/Odd Parity */
79#define UART_LCR_S2 (1 << 3) /* One/Two Stop bits */
80#define UART_LCR_FIFO (1 << 4) /* FIFO Enable */
81#define UART_LCR_WL5 (0 << 5) /* Word Length - 5 bits */
82#define UART_LCR_WL6 (1 << 5) /* Word Length - 6 bits */
83#define UART_LCR_WL7 (1 << 6) /* Word Length - 7 bits */
84#define UART_LCR_WL8 (1 << 7) /* Word Length - 8 bits */
85
86/* UART_CR Bitmask */
87#define UART_CR_EN (1 << 0) /* UART Enable */
88#define UART_CR_SIR (1 << 1) /* IrDA SIR Enable */
89#define UART_CR_SIRLP (1 << 2) /* Low Power IrDA Enable */
90#define UART_CR_RXP (1 << 3) /* Receive Pin Polarity */
91#define UART_CR_TXP (1 << 4) /* Transmit Pin Polarity */
92#define UART_CR_MXP (1 << 5) /* Modem Pin Polarity */
93#define UART_CR_LOOP (1 << 6) /* Loopback Mode */
94
95/* UART_SR Bitmask */
96#define UART_SR_CTS (1 << 0) /* Clear To Send Status */
97#define UART_SR_DSR (1 << 1) /* Data Set Ready Status */
98#define UART_SR_DCD (1 << 2) /* Data Carrier Detect Status */
99#define UART_SR_TxBSY (1 << 3) /* Transmitter Busy Status */
100#define UART_SR_RxFE (1 << 4) /* Receive FIFO Empty Status */
101#define UART_SR_TxFF (1 << 5) /* Transmit FIFO Full Status */
102#define UART_SR_RxFF (1 << 6) /* Receive FIFO Full Status */
103#define UART_SR_TxFE (1 << 7) /* Transmit FIFO Empty Status */
104
105/* UART_INT Bitmask */
106#define UART_INT_RIS (1 << 0) /* Rx Interrupt */
107#define UART_INT_TIS (1 << 1) /* Tx Interrupt */
108#define UART_INT_MIS (1 << 2) /* Modem Interrupt */
109#define UART_INT_RTIS (1 << 3) /* Receive Timeout Interrupt */
110
111/* Timer 1 */
112#define TIMER1_BASE __REG(0x80000c00)
113#define TIMER1_LOAD __REG(0x80000c00) /* Timer 1 Load Register */
114#define TIMER1_VAL __REG(0x80000c04) /* Timer 1 Value Register */
115#define TIMER1_CTRL __REG(0x80000c08) /* Timer 1 Control Register */
116#define TIMER1_CLEAR __REG(0x80000c0c) /* Timer 1 Clear Register */
117
118/* Timer 2 */
119#define TIMER2_BASE __REG(0x80000d00)
120#define TIMER2_LOAD __REG(0x80000d00) /* Timer 2 Load Register */
121#define TIMER2_VAL __REG(0x80000d04) /* Timer 2 Value Register */
122#define TIMER2_CTRL __REG(0x80000d08) /* Timer 2 Control Register */
123#define TIMER2_CLEAR __REG(0x80000d0c) /* Timer 2 Clear Register */
124
125/* Timer 3 */
126#define TIMER3_BASE __REG(0x80000e00)
127#define TIMER3_LOAD __REG(0x80000e00) /* Timer 3 Load Register */
128#define TIMER3_VAL __REG(0x80000e04) /* Timer 3 Value Register */
129#define TIMER3_CTRL __REG(0x80000e08) /* Timer 3 Control Register */
130#define TIMER3_CLEAR __REG(0x80000e0c) /* Timer 3 Clear Register */
131
132/* Timer Control register bits */
133#define TIMER_CTRL_ENABLE (1 << 7) /* Enable (Start° Timer */
134#define TIMER_CTRL_PERIODIC (1 << 6) /* Periodic Running Mode */
135#define TIMER_CTRL_FREE_RUNNING (0 << 6) /* Normal Running Mode */
136#define TIMER_CTRL_CLKSEL_508K (1 << 3) /* 508KHz Clock select (Timer 1, 2) */
137#define TIMER_CTRL_CLKSEL_2K (0 << 3) /* 2KHz Clock Select (Timer 1, 2)*/
138
139/* Power and State Control */
140#define POWER_BASE __REG(0x80000400)
141#define POWER_PWRSR __REG(0x80000400) /* Power Status Register */
142#define POWER_PWRCNT __REG(0x80000404) /* Power/Clock control */
143#define POWER_HALT __REG(0x80000408) /* Power Idle Mode */
144#define POWER_STDBY __REG(0x8000040c) /* Power Standby Mode */
145#define POWER_BLEOI __REG(0x80000410) /* Battery Low End of Interrupt */
146#define POWER_MCEOI __REG(0x80000414) /* Media Changed EoI */
147#define POWER_TEOI __REG(0x80000418) /* Tick EoI */
148#define POWER_STFCLR __REG(0x8000041c) /* NbFlg, RSTFlg, PFFlg, CLDFlg Clear */
149#define POWER_CLKSET __REG(0x80000420) /* Clock Speed Control */
150
151#endif /* __ARM_ARCH_AAEC2000_H */
diff --git a/include/asm-arm/arch-aaec2000/debug-macro.S b/include/asm-arm/arch-aaec2000/debug-macro.S
new file mode 100644
index 000000000000..e4f1fa539a74
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/debug-macro.S
@@ -0,0 +1,36 @@
1/* linux/include/asm-arm/arch-aaec2000/debug-macro.S
2 *
3 * Debugging macro include header
4 *
5 * Copyright (c) 2005 Nicolas Bellido Y Ortega
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12 .macro addruart,rx
13 mrc p15, 0, \rx, c1, c0
14 tst \rx, #1 @ MMU enabled?
15 moveq \rx, #0x80000000 @ physical
16 movne \rx, #io_p2v(0x80000000) @ virtual
17 orr \rx, \rx, #0x00000800
18 .endm
19
20 .macro senduart,rd,rx
21 str \rd, [\rx, #0]
22 .endm
23
24 .macro busyuart,rd,rx
251002: ldr \rd, [\rx, #0x10]
26 tst \rd, #(1 << 7)
27 beq 1002b
28 .endm
29
30 .macro waituart,rd,rx
31#if 0
321001: ldr \rd, [\rx, #0x10]
33 tst \rd, #(1 << 5)
34 beq 1001b
35#endif
36 .endm
diff --git a/include/asm-arm/arch-aaec2000/dma.h b/include/asm-arm/arch-aaec2000/dma.h
new file mode 100644
index 000000000000..28c890b4a1d3
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/dma.h
@@ -0,0 +1,17 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/dma.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_DMA_H
12#define __ASM_ARCH_DMA_H
13
14#define MAX_DMA_ADDRESS 0xffffffff
15#define MAX_DMA_CHANNELS 0
16
17#endif
diff --git a/include/asm-arm/arch-aaec2000/entry-macro.S b/include/asm-arm/arch-aaec2000/entry-macro.S
new file mode 100644
index 000000000000..df31313ab07e
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/entry-macro.S
@@ -0,0 +1,33 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/entry-macro.S
3 *
4 * Low-level IRQ helper for aaec-2000 based platforms
5 *
6 * Copyright (c) 2005 Nicolas Bellido Y Ortega
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14 .macro disable_fiq
15 .endm
16
17 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
18 mov r4, #0xf8000000
19 add r4, r4, #0x00000500
20 mov \base, r4
21 ldr \irqstat, [\base, #0]
22 cmp \irqstat, #0
23 bne 1001f
24 ldr \irqnr, =NR_IRQS+1
25 b 1003f
261001: mov \irqnr, #0
271002: ands \tmp, \irqstat, #1
28 mov \irqstat, \irqstat, LSR #1
29 add \irqnr, \irqnr, #1
30 beq 1002b
31 sub \irqnr, \irqnr, #1
321003:
33 .endm
diff --git a/include/asm-arm/arch-aaec2000/hardware.h b/include/asm-arm/arch-aaec2000/hardware.h
new file mode 100644
index 000000000000..4c37219e030e
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/hardware.h
@@ -0,0 +1,49 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/hardware.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_HARDWARE_H
12#define __ASM_ARCH_HARDWARE_H
13
14#include <linux/config.h>
15
16/* The kernel is loaded at physical address 0xf8000000.
17 * We map the IO space a bit after
18 */
19#define PIO_APB_BASE 0x80000000
20#define VIO_APB_BASE 0xf8000000
21#define IO_APB_LENGTH 0x2000
22#define PIO_AHB_BASE 0x80002000
23#define VIO_AHB_BASE 0xf8002000
24#define IO_AHB_LENGTH 0x2000
25
26#define VIO_BASE VIO_APB_BASE
27#define PIO_BASE PIO_APB_BASE
28
29#define io_p2v(x) ( (x) - PIO_BASE + VIO_BASE )
30#define io_v2p(x) ( (x) + PIO_BASE - VIO_BASE )
31
32#ifndef __ASSEMBLY__
33
34#include <asm/types.h>
35
36/* FIXME: Is it needed to optimize this a la pxa ?? */
37#define __REG(x) (*((volatile u32 *)io_p2v(x)))
38#define __PREG(x) (io_v2p((u32)&(x)))
39
40#else /* __ASSEMBLY__ */
41
42#define __REG(x) io_p2v(x)
43#define __PREG(x) io_v2p(x)
44
45#endif
46
47#include "aaec2000.h"
48
49#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h
new file mode 100644
index 000000000000..c58a8d10425a
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/io.h
@@ -0,0 +1,19 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/io.h
3 *
4 * Copied from asm/arch/sa1100/io.h
5 */
6#ifndef __ASM_ARM_ARCH_IO_H
7#define __ASM_ARM_ARCH_IO_H
8
9#define IO_SPACE_LIMIT 0xffffffff
10
11/*
12 * We don't actually have real ISA nor PCI buses, but there is so many
13 * drivers out there that might just work if we fake them...
14 */
15#define __io(a) ((void __iomem *)(a))
16#define __mem_pci(a) (a)
17#define __mem_isa(a) (a)
18
19#endif
diff --git a/include/asm-arm/arch-aaec2000/irqs.h b/include/asm-arm/arch-aaec2000/irqs.h
new file mode 100644
index 000000000000..de252220e806
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/irqs.h
@@ -0,0 +1,46 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/irqs.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_IRQS_H
12#define __ASM_ARCH_IRQS_H
13
14
15#define INT_GPIOF0_FIQ 0 /* External GPIO Port F O Fast Interrupt Input */
16#define INT_BL_FIQ 1 /* Battery Low Fast Interrupt */
17#define INT_WE_FIQ 2 /* Watchdog Expired Fast Interrupt */
18#define INT_MV_FIQ 3 /* Media Changed Interrupt */
19#define INT_SC 4 /* Sound Codec Interrupt */
20#define INT_GPIO1 5 /* GPIO Port F Configurable Int 1 */
21#define INT_GPIO2 6 /* GPIO Port F Configurable Int 2 */
22#define INT_GPIO3 7 /* GPIO Port F Configurable Int 3 */
23#define INT_TMR1_OFL 8 /* Timer 1 Overflow Interrupt */
24#define INT_TMR2_OFL 9 /* Timer 2 Overflow Interrupt */
25#define INT_RTC_CM 10 /* RTC Compare Match Interrupt */
26#define INT_TICK 11 /* 64Hz Tick Interrupt */
27#define INT_UART1 12 /* UART1 Interrupt */
28#define INT_UART2 13 /* UART2 & Modem State Changed Interrupt */
29#define INT_LCD 14 /* LCD Interrupt */
30#define INT_SSI 15 /* SSI End of Transfer Interrupt */
31#define INT_UART3 16 /* UART3 Interrupt */
32#define INT_SCI 17 /* SCI Interrupt */
33#define INT_AAC 18 /* Advanced Audio Codec Interrupt */
34#define INT_MMC 19 /* MMC Interrupt */
35#define INT_USB 20 /* USB Interrupt */
36#define INT_DMA 21 /* DMA Interrupt */
37#define INT_TMR3_UOFL 22 /* Timer 3 Underflow Interrupt */
38#define INT_GPIO4 23 /* GPIO Port F Configurable Int 4 */
39#define INT_GPIO5 24 /* GPIO Port F Configurable Int 4 */
40#define INT_GPIO6 25 /* GPIO Port F Configurable Int 4 */
41#define INT_GPIO7 26 /* GPIO Port F Configurable Int 4 */
42#define INT_BMI 27 /* BMI Interrupt */
43
44#define NR_IRQS (INT_BMI + 1)
45
46#endif /* __ASM_ARCH_IRQS_H */
diff --git a/include/asm-arm/arch-aaec2000/memory.h b/include/asm-arm/arch-aaec2000/memory.h
new file mode 100644
index 000000000000..681b6a6171a1
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/memory.h
@@ -0,0 +1,73 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/memory.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_MEMORY_H
12#define __ASM_ARCH_MEMORY_H
13
14#include <linux/config.h>
15
16#define PHYS_OFFSET (0xf0000000UL)
17
18#define __virt_to_bus(x) __virt_to_phys(x)
19#define __bus_to_virt(x) __phys_to_virt(x)
20
21#ifdef CONFIG_DISCONTIGMEM
22
23/*
24 * The nodes are the followings:
25 *
26 * node 0: 0xf000.0000 - 0xf3ff.ffff
27 * node 1: 0xf400.0000 - 0xf7ff.ffff
28 * node 2: 0xf800.0000 - 0xfbff.ffff
29 * node 3: 0xfc00.0000 - 0xffff.ffff
30 */
31
32/*
33 * Given a kernel address, find the home node of the underlying memory.
34 */
35#define KVADDR_TO_NID(addr) \
36 (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MAX_MEM_SHIFT)
37
38/*
39 * Given a page frame number, convert it to a node id.
40 */
41#define PFN_TO_NID(pfn) \
42 (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MAX_MEM_SHIFT - PAGE_SHIFT))
43
44/*
45 * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
46 * and return the mem_map of that node.
47 */
48#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
49
50/*
51 * Given a page frame number, find the owning node of the memory
52 * and return the mem_map of that node.
53 */
54#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
55
56/*
57 * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
58 * and returns the index corresponding to the appropriate page in the
59 * node's mem_map.
60 */
61#define LOCAL_MAP_NR(addr) \
62 (((unsigned long)(addr) & (NODE_MAX_MEM_SIZE - 1)) >> PAGE_SHIFT)
63
64#define NODE_MAX_MEM_SHIFT 26
65#define NODE_MAX_MEM_SIZE (1 << NODE_MAX_MEM_SHIFT)
66
67#else
68
69#define PFN_TO_NID(addr) (0)
70
71#endif /* CONFIG_DISCONTIGMEM */
72
73#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/include/asm-arm/arch-aaec2000/param.h b/include/asm-arm/arch-aaec2000/param.h
new file mode 100644
index 000000000000..139936c2faf2
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/param.h
@@ -0,0 +1,15 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/param.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_PARAM_H
12#define __ASM_ARCH_PARAM_H
13
14#endif /* __ASM_ARCH_PARAM_H */
15
diff --git a/include/asm-arm/arch-aaec2000/system.h b/include/asm-arm/arch-aaec2000/system.h
new file mode 100644
index 000000000000..08de97b407a8
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/system.h
@@ -0,0 +1,24 @@
1/*
2 * linux/include/asm-arm/arch-aaed2000/system.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_SYSTEM_H
12#define __ASM_ARCH_SYSTEM_H
13
14static inline void arch_idle(void)
15{
16 cpu_do_idle();
17}
18
19static inline void arch_reset(char mode)
20{
21 cpu_reset(0);
22}
23
24#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/include/asm-arm/arch-aaec2000/timex.h b/include/asm-arm/arch-aaec2000/timex.h
new file mode 100644
index 000000000000..f5708b38fb7f
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/timex.h
@@ -0,0 +1,18 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/timex.h
3 *
4 * AAEC-2000 Architecture timex specification
5 *
6 * Copyright (c) 2005 Nicolas Bellido Y Ortega
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __ASM_ARCH_TIMEX_H
14#define __ASM_ARCH_TIMEX_H
15
16#define CLOCK_TICK_RATE 508000
17
18#endif /* __ASM_ARCH_TIMEX_H */
diff --git a/include/asm-arm/arch-aaec2000/uncompress.h b/include/asm-arm/arch-aaec2000/uncompress.h
new file mode 100644
index 000000000000..fff0c94b75c4
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/uncompress.h
@@ -0,0 +1,47 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/uncompress.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_UNCOMPRESS_H
12#define __ASM_ARCH_UNCOMPRESS_H
13
14#include "hardware.h"
15
16#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
17
18static void putstr( const char *s )
19{
20 unsigned long serial_port;
21 do {
22 serial_port = _UART3_BASE;
23 if (UART(UART_CR) & UART_CR_EN) break;
24 serial_port = _UART1_BASE;
25 if (UART(UART_CR) & UART_CR_EN) break;
26 serial_port = _UART2_BASE;
27 if (UART(UART_CR) & UART_CR_EN) break;
28 return;
29 } while (0);
30
31 for (; *s; s++) {
32 /* wait for space in the UART's transmitter */
33 while ((UART(UART_SR) & UART_SR_TxFF));
34 /* send the character out. */
35 UART(UART_DR) = *s;
36 /* if a LF, also do CR... */
37 if (*s == 10) {
38 while ((UART(UART_SR) & UART_SR_TxFF));
39 UART(UART_DR) = 13;
40 }
41 }
42}
43
44#define arch_decomp_setup()
45#define arch_decomp_wdog()
46
47#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/include/asm-arm/arch-aaec2000/vmalloc.h b/include/asm-arm/arch-aaec2000/vmalloc.h
new file mode 100644
index 000000000000..ecb991e2e4ff
--- /dev/null
+++ b/include/asm-arm/arch-aaec2000/vmalloc.h
@@ -0,0 +1,16 @@
1/*
2 * linux/include/asm-arm/arch-aaec2000/vmalloc.h
3 *
4 * Copyright (c) 2005 Nicolas Bellido Y Ortega
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __ASM_ARCH_VMALLOC_H
12#define __ASM_ARCH_VMALLOC_H
13
14#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
15
16#endif /* __ASM_ARCH_VMALLOC_H */
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
index 6c56708d0ff0..a1d9e181b10f 100644
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -363,6 +363,7 @@
363#define IXP2000_MIN_REV_MASK 0x0000000F 363#define IXP2000_MIN_REV_MASK 0x0000000F
364#define IXP2000_PROD_ID_MASK 0xFFFFFFFF 364#define IXP2000_PROD_ID_MASK 0xFFFFFFFF
365 365
366#define IXP2000_PRODUCT_ID GLOBAL_REG(0x00)
366#define IXP2000_MISC_CONTROL GLOBAL_REG(0x04) 367#define IXP2000_MISC_CONTROL GLOBAL_REG(0x04)
367#define IXP2000_MSF_CLK_CNTRL GLOBAL_REG(0x08) 368#define IXP2000_MSF_CLK_CNTRL GLOBAL_REG(0x08)
368#define IXP2000_RESET0 GLOBAL_REG(0x0c) 369#define IXP2000_RESET0 GLOBAL_REG(0x0c)
diff --git a/include/asm-arm/arch-versatile/hardware.h b/include/asm-arm/arch-versatile/hardware.h
index d5fb4a251e7f..41c1bee342ad 100644
--- a/include/asm-arm/arch-versatile/hardware.h
+++ b/include/asm-arm/arch-versatile/hardware.h
@@ -25,19 +25,26 @@
25#include <asm/sizes.h> 25#include <asm/sizes.h>
26#include <asm/arch/platform.h> 26#include <asm/arch/platform.h>
27 27
28// FIXME = PCI settings need to be fixed!!!!!
29
30/* 28/*
31 * Similar to above, but for PCI addresses (memory, IO, Config and the 29 * PCI space virtual addresses
32 * V3 chip itself). WARNING: this has to mirror definitions in platform.h
33 */ 30 */
34#define PCI_MEMORY_VADDR 0xe8000000 31#define VERSATILE_PCI_VIRT_BASE 0xe8000000
35#define PCI_CONFIG_VADDR 0xec000000 32#define VERSATILE_PCI_CFG_VIRT_BASE 0xe9000000
36#define PCI_V3_VADDR 0xed000000 33
37#define PCI_IO_VADDR 0xee000000 34#if 0
35#define VERSATILE_PCI_VIRT_MEM_BASE0 0xf4000000
36#define VERSATILE_PCI_VIRT_MEM_BASE1 0xf5000000
37#define VERSATILE_PCI_VIRT_MEM_BASE2 0xf6000000
38
39#define PCIO_BASE VERSATILE_PCI_VIRT_MEM_BASE0
40#define PCIMEM_BASE VERSATILE_PCI_VIRT_MEM_BASE1
41#endif
42
43/* CIK guesswork */
44#define PCIBIOS_MIN_IO 0x44000000
45#define PCIBIOS_MIN_MEM 0x50000000
38 46
39#define PCIO_BASE PCI_IO_VADDR 47#define pcibios_assign_all_busses() 1
40#define PCIMEM_BASE PCI_MEMORY_VADDR
41 48
42/* macro to get at IO space when running virtually */ 49/* macro to get at IO space when running virtually */
43#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) 50#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h
index dbb7158788fc..9f895bf61494 100644
--- a/include/asm-arm/arch-versatile/io.h
+++ b/include/asm-arm/arch-versatile/io.h
@@ -20,7 +20,7 @@
20#ifndef __ASM_ARM_ARCH_IO_H 20#ifndef __ASM_ARM_ARCH_IO_H
21#define __ASM_ARM_ARCH_IO_H 21#define __ASM_ARM_ARCH_IO_H
22 22
23#define IO_SPACE_LIMIT 0xffff 23#define IO_SPACE_LIMIT 0xffffffff
24 24
25#define __io(a) ((void __iomem *)(a)) 25#define __io(a) ((void __iomem *)(a))
26#define __mem_pci(a) (a) 26#define __mem_pci(a) (a)
diff --git a/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h
index a71093e44c58..cbdd9fb96332 100644
--- a/include/asm-arm/arch-versatile/platform.h
+++ b/include/asm-arm/arch-versatile/platform.h
@@ -76,7 +76,7 @@
76#define VERSATILE_SYS_NVFLAGSSET_OFFSET 0x38 76#define VERSATILE_SYS_NVFLAGSSET_OFFSET 0x38
77#define VERSATILE_SYS_NVFLAGSCLR_OFFSET 0x3C 77#define VERSATILE_SYS_NVFLAGSCLR_OFFSET 0x3C
78#define VERSATILE_SYS_RESETCTL_OFFSET 0x40 78#define VERSATILE_SYS_RESETCTL_OFFSET 0x40
79#define VERSATILE_SYS_PICCTL_OFFSET 0x44 79#define VERSATILE_SYS_PCICTL_OFFSET 0x44
80#define VERSATILE_SYS_MCI_OFFSET 0x48 80#define VERSATILE_SYS_MCI_OFFSET 0x48
81#define VERSATILE_SYS_FLASH_OFFSET 0x4C 81#define VERSATILE_SYS_FLASH_OFFSET 0x4C
82#define VERSATILE_SYS_CLCD_OFFSET 0x50 82#define VERSATILE_SYS_CLCD_OFFSET 0x50
@@ -114,7 +114,7 @@
114#define VERSATILE_SYS_NVFLAGSSET (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET) 114#define VERSATILE_SYS_NVFLAGSSET (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
115#define VERSATILE_SYS_NVFLAGSCLR (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET) 115#define VERSATILE_SYS_NVFLAGSCLR (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
116#define VERSATILE_SYS_RESETCTL (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET) 116#define VERSATILE_SYS_RESETCTL (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
117#define VERSATILE_SYS_PICCTL (VERSATILE_SYS_BASE + VERSATILE_SYS_PICCTL_OFFSET) 117#define VERSATILE_SYS_PCICTL (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
118#define VERSATILE_SYS_MCI (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET) 118#define VERSATILE_SYS_MCI (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
119#define VERSATILE_SYS_FLASH (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET) 119#define VERSATILE_SYS_FLASH (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
120#define VERSATILE_SYS_CLCD (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET) 120#define VERSATILE_SYS_CLCD (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
@@ -225,7 +225,20 @@
225#define VERSATILE_SSMC_BASE 0x20000000 /* SSMC */ 225#define VERSATILE_SSMC_BASE 0x20000000 /* SSMC */
226#define VERSATILE_IB2_BASE 0x24000000 /* IB2 module */ 226#define VERSATILE_IB2_BASE 0x24000000 /* IB2 module */
227#define VERSATILE_MBX_BASE 0x40000000 /* MBX */ 227#define VERSATILE_MBX_BASE 0x40000000 /* MBX */
228
229/* PCI space */
228#define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */ 230#define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */
231#define VERSATILE_PCI_CFG_BASE 0x42000000
232#define VERSATILE_PCI_MEM_BASE0 0x44000000
233#define VERSATILE_PCI_MEM_BASE1 0x50000000
234#define VERSATILE_PCI_MEM_BASE2 0x60000000
235/* Sizes of above maps */
236#define VERSATILE_PCI_BASE_SIZE 0x01000000
237#define VERSATILE_PCI_CFG_BASE_SIZE 0x02000000
238#define VERSATILE_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
239#define VERSATILE_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
240#define VERSATILE_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
241
229#define VERSATILE_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */ 242#define VERSATILE_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
230#define VERSATILE_LT_BASE 0x80000000 /* Logic Tile expansion */ 243#define VERSATILE_LT_BASE 0x80000000 /* Logic Tile expansion */
231 244
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 09ffeed507c2..035cdcff43d2 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -16,6 +16,9 @@
16 16
17#include <asm/mman.h> 17#include <asm/mman.h>
18#include <asm/glue.h> 18#include <asm/glue.h>
19#include <asm/shmparam.h>
20
21#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
19 22
20/* 23/*
21 * Cache Model 24 * Cache Model
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index 658ffa384fda..08a46302d265 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -273,6 +273,33 @@ extern void __iounmap(void __iomem *addr);
273#endif 273#endif
274 274
275/* 275/*
276 * io{read,write}{8,16,32} macros
277 */
278#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; })
279#define ioread16(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
280#define ioread32(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
281
282#define iowrite8(v,p) __raw_writeb(v, p)
283#define iowrite16(v,p) __raw_writew(cpu_to_le16(v), p)
284#define iowrite32(v,p) __raw_writel(cpu_to_le32(v), p)
285
286#define ioread8_rep(p,d,c) __raw_readsb(p,d,c)
287#define ioread16_rep(p,d,c) __raw_readsw(p,d,c)
288#define ioread32_rep(p,d,c) __raw_readsl(p,d,c)
289
290#define iowrite8_rep(p,s,c) __raw_writesb(p,s,c)
291#define iowrite16_rep(p,s,c) __raw_writesw(p,s,c)
292#define iowrite32_rep(p,s,c) __raw_writesl(p,s,c)
293
294extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
295extern void ioport_unmap(void __iomem *addr);
296
297struct pci_dev;
298
299extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen);
300extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
301
302/*
276 * can the hardware map this into one segment or not, given no other 303 * can the hardware map this into one segment or not, given no other
277 * constraints. 304 * constraints.
278 */ 305 */
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index 31d3fc25ccbd..09a1451c1159 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -20,7 +20,7 @@
20#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0) 20#define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0)
21 21
22struct atalk_addr { 22struct atalk_addr {
23 __u16 s_net; 23 __be16 s_net;
24 __u8 s_node; 24 __u8 s_node;
25}; 25};
26 26
@@ -33,8 +33,8 @@ struct sockaddr_at {
33 33
34struct atalk_netrange { 34struct atalk_netrange {
35 __u8 nr_phase; 35 __u8 nr_phase;
36 __u16 nr_firstnet; 36 __be16 nr_firstnet;
37 __u16 nr_lastnet; 37 __be16 nr_lastnet;
38}; 38};
39 39
40#ifdef __KERNEL__ 40#ifdef __KERNEL__
@@ -70,8 +70,8 @@ struct atalk_iface {
70struct atalk_sock { 70struct atalk_sock {
71 /* struct sock has to be the first member of atalk_sock */ 71 /* struct sock has to be the first member of atalk_sock */
72 struct sock sk; 72 struct sock sk;
73 unsigned short dest_net; 73 __be16 dest_net;
74 unsigned short src_net; 74 __be16 src_net;
75 unsigned char dest_node; 75 unsigned char dest_node;
76 unsigned char src_node; 76 unsigned char src_node;
77 unsigned char dest_port; 77 unsigned char dest_port;
@@ -95,9 +95,9 @@ struct ddpehdr {
95 deh_hops:4, 95 deh_hops:4,
96 deh_len:10; 96 deh_len:10;
97#endif 97#endif
98 __u16 deh_sum; 98 __be16 deh_sum;
99 __u16 deh_dnet; 99 __be16 deh_dnet;
100 __u16 deh_snet; 100 __be16 deh_snet;
101 __u8 deh_dnode; 101 __u8 deh_dnode;
102 __u8 deh_snode; 102 __u8 deh_snode;
103 __u8 deh_dport; 103 __u8 deh_dport;
@@ -142,24 +142,24 @@ struct ddpshdr {
142 142
143/* AppleTalk AARP headers */ 143/* AppleTalk AARP headers */
144struct elapaarp { 144struct elapaarp {
145 __u16 hw_type; 145 __be16 hw_type;
146#define AARP_HW_TYPE_ETHERNET 1 146#define AARP_HW_TYPE_ETHERNET 1
147#define AARP_HW_TYPE_TOKENRING 2 147#define AARP_HW_TYPE_TOKENRING 2
148 __u16 pa_type; 148 __be16 pa_type;
149 __u8 hw_len; 149 __u8 hw_len;
150 __u8 pa_len; 150 __u8 pa_len;
151#define AARP_PA_ALEN 4 151#define AARP_PA_ALEN 4
152 __u16 function; 152 __be16 function;
153#define AARP_REQUEST 1 153#define AARP_REQUEST 1
154#define AARP_REPLY 2 154#define AARP_REPLY 2
155#define AARP_PROBE 3 155#define AARP_PROBE 3
156 __u8 hw_src[ETH_ALEN] __attribute__ ((packed)); 156 __u8 hw_src[ETH_ALEN] __attribute__ ((packed));
157 __u8 pa_src_zero __attribute__ ((packed)); 157 __u8 pa_src_zero __attribute__ ((packed));
158 __u16 pa_src_net __attribute__ ((packed)); 158 __be16 pa_src_net __attribute__ ((packed));
159 __u8 pa_src_node __attribute__ ((packed)); 159 __u8 pa_src_node __attribute__ ((packed));
160 __u8 hw_dst[ETH_ALEN] __attribute__ ((packed)); 160 __u8 hw_dst[ETH_ALEN] __attribute__ ((packed));
161 __u8 pa_dst_zero __attribute__ ((packed)); 161 __u8 pa_dst_zero __attribute__ ((packed));
162 __u16 pa_dst_net __attribute__ ((packed)); 162 __be16 pa_dst_net __attribute__ ((packed));
163 __u8 pa_dst_node __attribute__ ((packed)); 163 __u8 pa_dst_node __attribute__ ((packed));
164}; 164};
165 165
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index e38407a23d04..561d4dc75836 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -14,6 +14,7 @@
14#define NETLINK_SELINUX 7 /* SELinux event notifications */ 14#define NETLINK_SELINUX 7 /* SELinux event notifications */
15#define NETLINK_ARPD 8 15#define NETLINK_ARPD 8
16#define NETLINK_AUDIT 9 /* auditing */ 16#define NETLINK_AUDIT 9 /* auditing */
17#define NETLINK_FIB_LOOKUP 10
17#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */ 18#define NETLINK_ROUTE6 11 /* af_inet6 route comm channel */
18#define NETLINK_IP6_FW 13 19#define NETLINK_IP6_FW 13
19#define NETLINK_DNRTMSG 14 /* DECnet routing messages */ 20#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
index e6b519220245..724066778aff 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -245,6 +245,7 @@ struct sadb_x_nat_t_port {
245 245
246/* Security Association flags */ 246/* Security Association flags */
247#define SADB_SAFLAGS_PFS 1 247#define SADB_SAFLAGS_PFS 1
248#define SADB_SAFLAGS_NOPMTUDISC 0x20000000
248#define SADB_SAFLAGS_DECAP_DSCP 0x40000000 249#define SADB_SAFLAGS_DECAP_DSCP 0x40000000
249#define SADB_SAFLAGS_NOECN 0x80000000 250#define SADB_SAFLAGS_NOECN 0x80000000
250 251
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index d68391a9b9f3..f0d423300d84 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -196,6 +196,7 @@ struct xfrm_usersa_info {
196 __u8 flags; 196 __u8 flags;
197#define XFRM_STATE_NOECN 1 197#define XFRM_STATE_NOECN 1
198#define XFRM_STATE_DECAP_DSCP 2 198#define XFRM_STATE_DECAP_DSCP 2
199#define XFRM_STATE_NOPMTUDISC 4
199}; 200};
200 201
201struct xfrm_usersa_id { 202struct xfrm_usersa_id {
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 9e6368a54547..828a3a93dda1 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -220,7 +220,7 @@ static __inline__ void ax25_cb_put(ax25_cb *ax25)
220 } 220 }
221} 221}
222 222
223static inline unsigned short ax25_type_trans(struct sk_buff *skb, struct net_device *dev) 223static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
224{ 224{
225 skb->dev = dev; 225 skb->dev = dev;
226 skb->pkt_type = PACKET_HOST; 226 skb->pkt_type = PACKET_HOST;
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e5a5f6b62f88..a4208a336ac0 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -109,6 +109,20 @@ struct fib_result {
109#endif 109#endif
110}; 110};
111 111
112struct fib_result_nl {
113 u32 fl_addr; /* To be looked up*/
114 u32 fl_fwmark;
115 unsigned char fl_tos;
116 unsigned char fl_scope;
117 unsigned char tb_id_in;
118
119 unsigned char tb_id; /* Results */
120 unsigned char prefixlen;
121 unsigned char nh_sel;
122 unsigned char type;
123 unsigned char scope;
124 int err;
125};
112 126
113#ifdef CONFIG_IP_ROUTE_MULTIPATH 127#ifdef CONFIG_IP_ROUTE_MULTIPATH
114 128
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index ebc5282e6d58..dc107ffad483 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -65,9 +65,11 @@ typedef enum {
65 SCTP_CMD_TIMER_START, /* Start a timer. */ 65 SCTP_CMD_TIMER_START, /* Start a timer. */
66 SCTP_CMD_TIMER_RESTART, /* Restart a timer. */ 66 SCTP_CMD_TIMER_RESTART, /* Restart a timer. */
67 SCTP_CMD_TIMER_STOP, /* Stop a timer. */ 67 SCTP_CMD_TIMER_STOP, /* Stop a timer. */
68 SCTP_CMD_COUNTER_RESET, /* Reset a counter. */ 68 SCTP_CMD_INIT_CHOOSE_TRANSPORT, /* Choose transport for an INIT. */
69 SCTP_CMD_COUNTER_INC, /* Increment a counter. */ 69 SCTP_CMD_INIT_COUNTER_RESET, /* Reset init counter. */
70 SCTP_CMD_INIT_COUNTER_INC, /* Increment init counter. */
70 SCTP_CMD_INIT_RESTART, /* High level, do init timer work. */ 71 SCTP_CMD_INIT_RESTART, /* High level, do init timer work. */
72 SCTP_CMD_COOKIEECHO_RESTART, /* High level, do cookie-echo timer work. */
71 SCTP_CMD_INIT_FAILED, /* High level, do init failure work. */ 73 SCTP_CMD_INIT_FAILED, /* High level, do init failure work. */
72 SCTP_CMD_REPORT_DUP, /* Report a duplicate TSN. */ 74 SCTP_CMD_REPORT_DUP, /* Report a duplicate TSN. */
73 SCTP_CMD_STRIKE, /* Mark a strike against a transport. */ 75 SCTP_CMD_STRIKE, /* Mark a strike against a transport. */
@@ -118,7 +120,6 @@ typedef union {
118 int error; 120 int error;
119 sctp_state_t state; 121 sctp_state_t state;
120 sctp_event_timeout_t to; 122 sctp_event_timeout_t to;
121 sctp_counter_t counter;
122 void *ptr; 123 void *ptr;
123 struct sctp_chunk *chunk; 124 struct sctp_chunk *chunk;
124 struct sctp_association *asoc; 125 struct sctp_association *asoc;
@@ -165,7 +166,6 @@ SCTP_ARG_CONSTRUCTOR(U16, __u16, u16)
165SCTP_ARG_CONSTRUCTOR(U8, __u8, u8) 166SCTP_ARG_CONSTRUCTOR(U8, __u8, u8)
166SCTP_ARG_CONSTRUCTOR(ERROR, int, error) 167SCTP_ARG_CONSTRUCTOR(ERROR, int, error)
167SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state) 168SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state)
168SCTP_ARG_CONSTRUCTOR(COUNTER, sctp_counter_t, counter)
169SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to) 169SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to)
170SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr) 170SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr)
171SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk) 171SCTP_ARG_CONSTRUCTOR(CHUNK, struct sctp_chunk *, chunk)
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 2b76c0f4babc..4868c7f7749d 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -263,13 +263,6 @@ enum { SCTP_MIN_PMTU = 576 };
263enum { SCTP_MAX_DUP_TSNS = 16 }; 263enum { SCTP_MAX_DUP_TSNS = 16 };
264enum { SCTP_MAX_GABS = 16 }; 264enum { SCTP_MAX_GABS = 16 };
265 265
266typedef enum {
267 SCTP_COUNTER_INIT_ERROR,
268} sctp_counter_t;
269
270/* How many counters does an association need? */
271#define SCTP_NUMBER_COUNTERS 5
272
273/* Here we define the default timers. */ 266/* Here we define the default timers. */
274 267
275/* cookie timer def = ? seconds */ 268/* cookie timer def = ? seconds */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 960abfa48d68..ef2738159ab3 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -223,6 +223,22 @@ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics);
223extern int sctp_debug_flag; 223extern int sctp_debug_flag;
224#define SCTP_DEBUG_PRINTK(whatever...) \ 224#define SCTP_DEBUG_PRINTK(whatever...) \
225 ((void) (sctp_debug_flag && printk(KERN_DEBUG whatever))) 225 ((void) (sctp_debug_flag && printk(KERN_DEBUG whatever)))
226#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \
227 if (sctp_debug_flag) { \
228 if (saddr->sa.sa_family == AF_INET6) { \
229 printk(KERN_DEBUG \
230 lead "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" trail, \
231 leadparm, \
232 NIP6(saddr->v6.sin6_addr), \
233 otherparms); \
234 } else { \
235 printk(KERN_DEBUG \
236 lead "%u.%u.%u.%u" trail, \
237 leadparm, \
238 NIPQUAD(saddr->v4.sin_addr.s_addr), \
239 otherparms); \
240 } \
241 }
226#define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; } 242#define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; }
227#define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; } 243#define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; }
228 244
@@ -236,6 +252,7 @@ extern int sctp_debug_flag;
236#else /* SCTP_DEBUG */ 252#else /* SCTP_DEBUG */
237 253
238#define SCTP_DEBUG_PRINTK(whatever...) 254#define SCTP_DEBUG_PRINTK(whatever...)
255#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
239#define SCTP_ENABLE_DEBUG 256#define SCTP_ENABLE_DEBUG
240#define SCTP_DISABLE_DEBUG 257#define SCTP_DISABLE_DEBUG
241#define SCTP_ASSERT(expr, str, func) 258#define SCTP_ASSERT(expr, str, func)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index f4fcee104707..a53e08a45e32 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -116,7 +116,8 @@ sctp_state_fn_t sctp_sf_eat_data_fast_4_4;
116sctp_state_fn_t sctp_sf_eat_sack_6_2; 116sctp_state_fn_t sctp_sf_eat_sack_6_2;
117sctp_state_fn_t sctp_sf_tabort_8_4_8; 117sctp_state_fn_t sctp_sf_tabort_8_4_8;
118sctp_state_fn_t sctp_sf_operr_notify; 118sctp_state_fn_t sctp_sf_operr_notify;
119sctp_state_fn_t sctp_sf_t1_timer_expire; 119sctp_state_fn_t sctp_sf_t1_init_timer_expire;
120sctp_state_fn_t sctp_sf_t1_cookie_timer_expire;
120sctp_state_fn_t sctp_sf_t2_timer_expire; 121sctp_state_fn_t sctp_sf_t2_timer_expire;
121sctp_state_fn_t sctp_sf_t4_timer_expire; 122sctp_state_fn_t sctp_sf_t4_timer_expire;
122sctp_state_fn_t sctp_sf_t5_timer_expire; 123sctp_state_fn_t sctp_sf_t5_timer_expire;
@@ -258,7 +259,10 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
258void sctp_chunk_assign_tsn(struct sctp_chunk *); 259void sctp_chunk_assign_tsn(struct sctp_chunk *);
259void sctp_chunk_assign_ssn(struct sctp_chunk *); 260void sctp_chunk_assign_ssn(struct sctp_chunk *);
260 261
261void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error); 262sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
263 __u16 error,
264 const struct sctp_association *asoc,
265 struct sctp_transport *transport);
262 266
263/* Prototypes for statetable processing. */ 267/* Prototypes for statetable processing. */
264 268
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 6c24d9cd3d66..dfad4d3c581c 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -867,10 +867,13 @@ struct sctp_transport {
867 */ 867 */
868 unsigned long last_time_ecne_reduced; 868 unsigned long last_time_ecne_reduced;
869 869
870 /* active : The current active state of this destination, 870 /* The number of times INIT has been sent on this transport. */
871 * : i.e. DOWN, UP, etc. 871 int init_sent_count;
872
873 /* state : The current state of this destination,
874 * : i.e. SCTP_ACTIVE, SCTP_INACTIVE, SCTP_UNKOWN.
872 */ 875 */
873 int active; 876 int state;
874 877
875 /* hb_allowed : The current heartbeat state of this destination, 878 /* hb_allowed : The current heartbeat state of this destination,
876 * : i.e. ALLOW-HB, NO-HEARTBEAT, etc. 879 * : i.e. ALLOW-HB, NO-HEARTBEAT, etc.
@@ -1222,9 +1225,6 @@ struct sctp_endpoint {
1222 1225
1223 /* sendbuf acct. policy. */ 1226 /* sendbuf acct. policy. */
1224 __u32 sndbuf_policy; 1227 __u32 sndbuf_policy;
1225
1226 /* Name for debugging output... */
1227 char *debug_name;
1228}; 1228};
1229 1229
1230/* Recover the outter endpoint structure. */ 1230/* Recover the outter endpoint structure. */
@@ -1314,11 +1314,23 @@ struct sctp_association {
1314 * : association. Normally this information is 1314 * : association. Normally this information is
1315 * : hashed or keyed for quick lookup and access 1315 * : hashed or keyed for quick lookup and access
1316 * : of the TCB. 1316 * : of the TCB.
1317 * : The list is also initialized with the list
1318 * : of addresses passed with the sctp_connectx()
1319 * : call.
1317 * 1320 *
1318 * It is a list of SCTP_transport's. 1321 * It is a list of SCTP_transport's.
1319 */ 1322 */
1320 struct list_head transport_addr_list; 1323 struct list_head transport_addr_list;
1321 1324
1325 /* transport_count
1326 *
1327 * Peer : A count of the number of peer addresses
1328 * Transport : in the Peer Transport Address List.
1329 * Address :
1330 * Count :
1331 */
1332 __u16 transport_count;
1333
1322 /* port 1334 /* port
1323 * The transport layer port number. 1335 * The transport layer port number.
1324 */ 1336 */
@@ -1486,6 +1498,9 @@ struct sctp_association {
1486 /* Transport to which SHUTDOWN chunk was last sent. */ 1498 /* Transport to which SHUTDOWN chunk was last sent. */
1487 struct sctp_transport *shutdown_last_sent_to; 1499 struct sctp_transport *shutdown_last_sent_to;
1488 1500
1501 /* Transport to which INIT chunk was last sent. */
1502 struct sctp_transport *init_last_sent_to;
1503
1489 /* Next TSN : The next TSN number to be assigned to a new 1504 /* Next TSN : The next TSN number to be assigned to a new
1490 * : DATA chunk. This is sent in the INIT or INIT 1505 * : DATA chunk. This is sent in the INIT or INIT
1491 * : ACK chunk to the peer and incremented each 1506 * : ACK chunk to the peer and incremented each
@@ -1549,8 +1564,11 @@ struct sctp_association {
1549 /* The message size at which SCTP fragmentation will occur. */ 1564 /* The message size at which SCTP fragmentation will occur. */
1550 __u32 frag_point; 1565 __u32 frag_point;
1551 1566
1552 /* Currently only one counter is used to count INIT errors. */ 1567 /* Counter used to count INIT errors. */
1553 int counters[SCTP_NUMBER_COUNTERS]; 1568 int init_err_counter;
1569
1570 /* Count the number of INIT cycles (for doubling timeout). */
1571 int init_cycle;
1554 1572
1555 /* Default send parameters. */ 1573 /* Default send parameters. */
1556 __u16 default_stream; 1574 __u16 default_stream;
@@ -1708,6 +1726,8 @@ void sctp_association_free(struct sctp_association *);
1708void sctp_association_put(struct sctp_association *); 1726void sctp_association_put(struct sctp_association *);
1709void sctp_association_hold(struct sctp_association *); 1727void sctp_association_hold(struct sctp_association *);
1710 1728
1729struct sctp_transport *sctp_assoc_choose_init_transport(
1730 struct sctp_association *);
1711struct sctp_transport *sctp_assoc_choose_shutdown_transport( 1731struct sctp_transport *sctp_assoc_choose_shutdown_transport(
1712 struct sctp_association *); 1732 struct sctp_association *);
1713void sctp_assoc_update_retran_path(struct sctp_association *); 1733void sctp_assoc_update_retran_path(struct sctp_association *);
@@ -1717,9 +1737,12 @@ int sctp_assoc_lookup_laddr(struct sctp_association *asoc,
1717 const union sctp_addr *laddr); 1737 const union sctp_addr *laddr);
1718struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *, 1738struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *,
1719 const union sctp_addr *address, 1739 const union sctp_addr *address,
1720 const int gfp); 1740 const int gfp,
1741 const int peer_state);
1721void sctp_assoc_del_peer(struct sctp_association *asoc, 1742void sctp_assoc_del_peer(struct sctp_association *asoc,
1722 const union sctp_addr *addr); 1743 const union sctp_addr *addr);
1744void sctp_assoc_rm_peer(struct sctp_association *asoc,
1745 struct sctp_transport *peer);
1723void sctp_assoc_control_transport(struct sctp_association *, 1746void sctp_assoc_control_transport(struct sctp_association *,
1724 struct sctp_transport *, 1747 struct sctp_transport *,
1725 sctp_transport_cmd_t, sctp_sn_error_t); 1748 sctp_transport_cmd_t, sctp_sn_error_t);
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 2758e8ce4f25..f6328aeddcce 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -111,6 +111,8 @@ enum sctp_optname {
111#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM 111#define SCTP_GET_LOCAL_ADDRS_NUM SCTP_GET_LOCAL_ADDRS_NUM
112 SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */ 112 SCTP_GET_LOCAL_ADDRS, /* Get all local addresss. */
113#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS 113#define SCTP_GET_LOCAL_ADDRS SCTP_GET_LOCAL_ADDRS
114 SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
115#define SCTP_SOCKOPT_CONNECTX SCTP_SOCKOPT_CONNECTX
114}; 116};
115 117
116/* 118/*
@@ -527,6 +529,7 @@ struct sctp_paddrinfo {
527enum sctp_spinfo_state { 529enum sctp_spinfo_state {
528 SCTP_INACTIVE, 530 SCTP_INACTIVE,
529 SCTP_ACTIVE, 531 SCTP_ACTIVE,
532 SCTP_UNKNOWN = 0xffff /* Value used for transport state unknown */
530}; 533};
531 534
532/* 535/*
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0e65e02b7a1d..029522a4ceda 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -204,6 +204,7 @@ struct xfrm_state_afinfo {
204 rwlock_t lock; 204 rwlock_t lock;
205 struct list_head *state_bydst; 205 struct list_head *state_bydst;
206 struct list_head *state_byspi; 206 struct list_head *state_byspi;
207 int (*init_flags)(struct xfrm_state *x);
207 void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl, 208 void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl,
208 struct xfrm_tmpl *tmpl, 209 struct xfrm_tmpl *tmpl,
209 xfrm_address_t *daddr, xfrm_address_t *saddr); 210 xfrm_address_t *daddr, xfrm_address_t *saddr);
@@ -225,7 +226,7 @@ struct xfrm_type
225 struct module *owner; 226 struct module *owner;
226 __u8 proto; 227 __u8 proto;
227 228
228 int (*init_state)(struct xfrm_state *x, void *args); 229 int (*init_state)(struct xfrm_state *x);
229 void (*destructor)(struct xfrm_state *); 230 void (*destructor)(struct xfrm_state *);
230 int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); 231 int (*input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
231 int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb); 232 int (*post_input)(struct xfrm_state *, struct xfrm_decap_state *, struct sk_buff *skb);
@@ -839,6 +840,7 @@ extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
839extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq); 840extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
840extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb); 841extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
841extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); 842extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
843extern int xfrm_init_state(struct xfrm_state *x);
842extern int xfrm4_rcv(struct sk_buff *skb); 844extern int xfrm4_rcv(struct sk_buff *skb);
843extern int xfrm4_output(struct sk_buff *skb); 845extern int xfrm4_output(struct sk_buff *skb);
844extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); 846extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index 54640c01b50c..10d040461021 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -565,7 +565,7 @@ int aarp_send_ddp(struct net_device *dev, struct sk_buff *skb,
565 * numbers we just happen to need. Now put the 565 * numbers we just happen to need. Now put the
566 * length in the lower two. 566 * length in the lower two.
567 */ 567 */
568 *((__u16 *)skb->data) = htons(skb->len); 568 *((__be16 *)skb->data) = htons(skb->len);
569 ft = 1; 569 ft = 1;
570 } 570 }
571 /* 571 /*
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 876dbac71060..192b529f86a4 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -401,7 +401,7 @@ out_err:
401} 401}
402 402
403/* Find a match for a specific network:node pair */ 403/* Find a match for a specific network:node pair */
404static struct atalk_iface *atalk_find_interface(int net, int node) 404static struct atalk_iface *atalk_find_interface(__be16 net, int node)
405{ 405{
406 struct atalk_iface *iface; 406 struct atalk_iface *iface;
407 407
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 0e98f2235b6e..514c85b2631a 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -200,7 +200,7 @@ static void ah4_err(struct sk_buff *skb, u32 info)
200 xfrm_state_put(x); 200 xfrm_state_put(x);
201} 201}
202 202
203static int ah_init_state(struct xfrm_state *x, void *args) 203static int ah_init_state(struct xfrm_state *x)
204{ 204{
205 struct ah_data *ahp = NULL; 205 struct ah_data *ahp = NULL;
206 struct xfrm_algo_desc *aalg_desc; 206 struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index eae84cc39d3f..ba57446d5d1f 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -362,7 +362,7 @@ static void esp_destroy(struct xfrm_state *x)
362 kfree(esp); 362 kfree(esp);
363} 363}
364 364
365static int esp_init_state(struct xfrm_state *x, void *args) 365static int esp_init_state(struct xfrm_state *x)
366{ 366{
367 struct esp_data *esp = NULL; 367 struct esp_data *esp = NULL;
368 368
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 563e7d612706..cd8e45ab9580 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -516,6 +516,60 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
516#undef BRD1_OK 516#undef BRD1_OK
517} 517}
518 518
519static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
520{
521
522 struct fib_result res;
523 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
524 .fwmark = frn->fl_fwmark,
525 .tos = frn->fl_tos,
526 .scope = frn->fl_scope } } };
527 if (tb) {
528 local_bh_disable();
529
530 frn->tb_id = tb->tb_id;
531 frn->err = tb->tb_lookup(tb, &fl, &res);
532
533 if (!frn->err) {
534 frn->prefixlen = res.prefixlen;
535 frn->nh_sel = res.nh_sel;
536 frn->type = res.type;
537 frn->scope = res.scope;
538 }
539 local_bh_enable();
540 }
541}
542
543static void nl_fib_input(struct sock *sk, int len)
544{
545 struct sk_buff *skb = NULL;
546 struct nlmsghdr *nlh = NULL;
547 struct fib_result_nl *frn;
548 int err;
549 u32 pid;
550 struct fib_table *tb;
551
552 skb = skb_recv_datagram(sk, 0, 0, &err);
553 nlh = (struct nlmsghdr *)skb->data;
554
555 frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
556 tb = fib_get_table(frn->tb_id_in);
557
558 nl_fib_lookup(frn, tb);
559
560 pid = nlh->nlmsg_pid; /*pid of sending process */
561 NETLINK_CB(skb).groups = 0; /* not in mcast group */
562 NETLINK_CB(skb).pid = 0; /* from kernel */
563 NETLINK_CB(skb).dst_pid = pid;
564 NETLINK_CB(skb).dst_groups = 0; /* unicast */
565 netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
566}
567
568static void nl_fib_lookup_init(void)
569{
570 netlink_kernel_create(NETLINK_FIB_LOOKUP, nl_fib_input);
571}
572
519static void fib_disable_ip(struct net_device *dev, int force) 573static void fib_disable_ip(struct net_device *dev, int force)
520{ 574{
521 if (fib_sync_down(0, dev, force)) 575 if (fib_sync_down(0, dev, force))
@@ -604,6 +658,7 @@ void __init ip_fib_init(void)
604 658
605 register_netdevice_notifier(&fib_netdev_notifier); 659 register_netdevice_notifier(&fib_netdev_notifier);
606 register_inetaddr_notifier(&fib_inetaddr_notifier); 660 register_inetaddr_notifier(&fib_inetaddr_notifier);
661 nl_fib_lookup_init();
607} 662}
608 663
609EXPORT_SYMBOL(inet_addr_type); 664EXPORT_SYMBOL(inet_addr_type);
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 1a23c5263b99..2065944fd9e5 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -236,15 +236,10 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x)
236 t->props.mode = 1; 236 t->props.mode = 1;
237 t->props.saddr.a4 = x->props.saddr.a4; 237 t->props.saddr.a4 = x->props.saddr.a4;
238 t->props.flags = x->props.flags; 238 t->props.flags = x->props.flags;
239 239
240 t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family); 240 if (xfrm_init_state(t))
241 if (t->type == NULL)
242 goto error;
243
244 if (t->type->init_state(t, NULL))
245 goto error; 241 goto error;
246 242
247 t->km.state = XFRM_STATE_VALID;
248 atomic_set(&t->tunnel_users, 1); 243 atomic_set(&t->tunnel_users, 1);
249out: 244out:
250 return t; 245 return t;
@@ -422,7 +417,7 @@ static void ipcomp_destroy(struct xfrm_state *x)
422 kfree(ipcd); 417 kfree(ipcd);
423} 418}
424 419
425static int ipcomp_init_state(struct xfrm_state *x, void *args) 420static int ipcomp_init_state(struct xfrm_state *x)
426{ 421{
427 int err; 422 int err;
428 struct ipcomp_data *ipcd; 423 struct ipcomp_data *ipcd;
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index af2392ae5769..66620a95942a 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -33,6 +33,7 @@ static void xfrm4_encap(struct sk_buff *skb)
33 struct dst_entry *dst = skb->dst; 33 struct dst_entry *dst = skb->dst;
34 struct xfrm_state *x = dst->xfrm; 34 struct xfrm_state *x = dst->xfrm;
35 struct iphdr *iph, *top_iph; 35 struct iphdr *iph, *top_iph;
36 int flags;
36 37
37 iph = skb->nh.iph; 38 iph = skb->nh.iph;
38 skb->h.ipiph = iph; 39 skb->h.ipiph = iph;
@@ -51,10 +52,13 @@ static void xfrm4_encap(struct sk_buff *skb)
51 52
52 /* DS disclosed */ 53 /* DS disclosed */
53 top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos); 54 top_iph->tos = INET_ECN_encapsulate(iph->tos, iph->tos);
54 if (x->props.flags & XFRM_STATE_NOECN) 55
56 flags = x->props.flags;
57 if (flags & XFRM_STATE_NOECN)
55 IP_ECN_clear(top_iph); 58 IP_ECN_clear(top_iph);
56 59
57 top_iph->frag_off = iph->frag_off & htons(IP_DF); 60 top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ?
61 0 : (iph->frag_off & htons(IP_DF));
58 if (!top_iph->frag_off) 62 if (!top_iph->frag_off)
59 __ip_select_ident(top_iph, dst, 0); 63 __ip_select_ident(top_iph, dst, 0);
60 64
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c
index 223a2e83853f..050611d7a967 100644
--- a/net/ipv4/xfrm4_state.c
+++ b/net/ipv4/xfrm4_state.c
@@ -7,12 +7,20 @@
7 * 7 *
8 */ 8 */
9 9
10#include <net/ip.h>
10#include <net/xfrm.h> 11#include <net/xfrm.h>
11#include <linux/pfkeyv2.h> 12#include <linux/pfkeyv2.h>
12#include <linux/ipsec.h> 13#include <linux/ipsec.h>
13 14
14static struct xfrm_state_afinfo xfrm4_state_afinfo; 15static struct xfrm_state_afinfo xfrm4_state_afinfo;
15 16
17static int xfrm4_init_flags(struct xfrm_state *x)
18{
19 if (ipv4_config.no_pmtu_disc)
20 x->props.flags |= XFRM_STATE_NOPMTUDISC;
21 return 0;
22}
23
16static void 24static void
17__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, 25__xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
18 struct xfrm_tmpl *tmpl, 26 struct xfrm_tmpl *tmpl,
@@ -109,6 +117,7 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto,
109static struct xfrm_state_afinfo xfrm4_state_afinfo = { 117static struct xfrm_state_afinfo xfrm4_state_afinfo = {
110 .family = AF_INET, 118 .family = AF_INET,
111 .lock = RW_LOCK_UNLOCKED, 119 .lock = RW_LOCK_UNLOCKED,
120 .init_flags = xfrm4_init_flags,
112 .init_tempsel = __xfrm4_init_tempsel, 121 .init_tempsel = __xfrm4_init_tempsel,
113 .state_lookup = __xfrm4_state_lookup, 122 .state_lookup = __xfrm4_state_lookup,
114 .find_acq = __xfrm4_find_acq, 123 .find_acq = __xfrm4_find_acq,
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 413191f585f6..e1fe360ed27a 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -84,7 +84,7 @@ static void ipip_err(struct sk_buff *skb, u32 info)
84 handler->err_handler(skb, &arg); 84 handler->err_handler(skb, &arg);
85} 85}
86 86
87static int ipip_init_state(struct xfrm_state *x, void *args) 87static int ipip_init_state(struct xfrm_state *x)
88{ 88{
89 if (!x->props.mode) 89 if (!x->props.mode)
90 return -EINVAL; 90 return -EINVAL;
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index e3ecf626cbf7..986fdfdccbcd 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -339,7 +339,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
339 xfrm_state_put(x); 339 xfrm_state_put(x);
340} 340}
341 341
342static int ah6_init_state(struct xfrm_state *x, void *args) 342static int ah6_init_state(struct xfrm_state *x)
343{ 343{
344 struct ah_data *ahp = NULL; 344 struct ah_data *ahp = NULL;
345 struct xfrm_algo_desc *aalg_desc; 345 struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index be7095d6babe..324db62515a2 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -296,7 +296,7 @@ static void esp6_destroy(struct xfrm_state *x)
296 kfree(esp); 296 kfree(esp);
297} 297}
298 298
299static int esp6_init_state(struct xfrm_state *x, void *args) 299static int esp6_init_state(struct xfrm_state *x)
300{ 300{
301 struct esp_data *esp = NULL; 301 struct esp_data *esp = NULL;
302 302
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 6cde5310cd76..423feb46ccc0 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -234,14 +234,9 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
234 t->props.mode = 1; 234 t->props.mode = 1;
235 memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); 235 memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr));
236 236
237 t->type = xfrm_get_type(IPPROTO_IPV6, t->props.family); 237 if (xfrm_init_state(t))
238 if (t->type == NULL)
239 goto error; 238 goto error;
240 239
241 if (t->type->init_state(t, NULL))
242 goto error;
243
244 t->km.state = XFRM_STATE_VALID;
245 atomic_set(&t->tunnel_users, 1); 240 atomic_set(&t->tunnel_users, 1);
246 241
247out: 242out:
@@ -420,7 +415,7 @@ static void ipcomp6_destroy(struct xfrm_state *x)
420 xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr); 415 xfrm6_tunnel_free_spi((xfrm_address_t *)&x->props.saddr);
421} 416}
422 417
423static int ipcomp6_init_state(struct xfrm_state *x, void *args) 418static int ipcomp6_init_state(struct xfrm_state *x)
424{ 419{
425 int err; 420 int err;
426 struct ipcomp_data *ipcd; 421 struct ipcomp_data *ipcd;
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index ffcadd68b951..60c26c87277e 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -466,7 +466,7 @@ static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
466 return; 466 return;
467} 467}
468 468
469static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args) 469static int xfrm6_tunnel_init_state(struct xfrm_state *x)
470{ 470{
471 if (!x->props.mode) 471 if (!x->props.mode)
472 return -EINVAL; 472 return -EINVAL;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 98b72f2024ff..4879743b945a 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -690,6 +690,8 @@ static struct sk_buff * pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys,
690 sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN; 690 sa->sadb_sa_flags |= SADB_SAFLAGS_NOECN;
691 if (x->props.flags & XFRM_STATE_DECAP_DSCP) 691 if (x->props.flags & XFRM_STATE_DECAP_DSCP)
692 sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP; 692 sa->sadb_sa_flags |= SADB_SAFLAGS_DECAP_DSCP;
693 if (x->props.flags & XFRM_STATE_NOPMTUDISC)
694 sa->sadb_sa_flags |= SADB_SAFLAGS_NOPMTUDISC;
693 695
694 /* hard time */ 696 /* hard time */
695 if (hsc & 2) { 697 if (hsc & 2) {
@@ -974,6 +976,8 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
974 x->props.flags |= XFRM_STATE_NOECN; 976 x->props.flags |= XFRM_STATE_NOECN;
975 if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP) 977 if (sa->sadb_sa_flags & SADB_SAFLAGS_DECAP_DSCP)
976 x->props.flags |= XFRM_STATE_DECAP_DSCP; 978 x->props.flags |= XFRM_STATE_DECAP_DSCP;
979 if (sa->sadb_sa_flags & SADB_SAFLAGS_NOPMTUDISC)
980 x->props.flags |= XFRM_STATE_NOPMTUDISC;
977 981
978 lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1]; 982 lifetime = (struct sadb_lifetime*) ext_hdrs[SADB_EXT_LIFETIME_HARD-1];
979 if (lifetime != NULL) { 983 if (lifetime != NULL) {
@@ -1096,17 +1100,11 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
1096 } 1100 }
1097 } 1101 }
1098 1102
1099 x->type = xfrm_get_type(proto, x->props.family); 1103 err = xfrm_init_state(x);
1100 if (x->type == NULL) { 1104 if (err)
1101 err = -ENOPROTOOPT;
1102 goto out;
1103 }
1104 if (x->type->init_state(x, NULL)) {
1105 err = -EINVAL;
1106 goto out; 1105 goto out;
1107 } 1106
1108 x->km.seq = hdr->sadb_msg_seq; 1107 x->km.seq = hdr->sadb_msg_seq;
1109 x->km.state = XFRM_STATE_VALID;
1110 return x; 1108 return x;
1111 1109
1112out: 1110out:
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 663843d97a92..7ae6aa772dab 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -191,10 +191,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
191 asoc->last_cwr_tsn = asoc->ctsn_ack_point; 191 asoc->last_cwr_tsn = asoc->ctsn_ack_point;
192 asoc->unack_data = 0; 192 asoc->unack_data = 0;
193 193
194 SCTP_DEBUG_PRINTK("myctsnap for %s INIT as 0x%x.\n",
195 asoc->ep->debug_name,
196 asoc->ctsn_ack_point);
197
198 /* ADDIP Section 4.1 Asconf Chunk Procedures 194 /* ADDIP Section 4.1 Asconf Chunk Procedures
199 * 195 *
200 * When an endpoint has an ASCONF signaled change to be sent to the 196 * When an endpoint has an ASCONF signaled change to be sent to the
@@ -211,6 +207,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
211 207
212 /* Make an empty list of remote transport addresses. */ 208 /* Make an empty list of remote transport addresses. */
213 INIT_LIST_HEAD(&asoc->peer.transport_addr_list); 209 INIT_LIST_HEAD(&asoc->peer.transport_addr_list);
210 asoc->peer.transport_count = 0;
214 211
215 /* RFC 2960 5.1 Normal Establishment of an Association 212 /* RFC 2960 5.1 Normal Establishment of an Association
216 * 213 *
@@ -288,6 +285,7 @@ struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep,
288 285
289 asoc->base.malloced = 1; 286 asoc->base.malloced = 1;
290 SCTP_DBG_OBJCNT_INC(assoc); 287 SCTP_DBG_OBJCNT_INC(assoc);
288 SCTP_DEBUG_PRINTK("Created asoc %p\n", asoc);
291 289
292 return asoc; 290 return asoc;
293 291
@@ -356,6 +354,8 @@ void sctp_association_free(struct sctp_association *asoc)
356 sctp_transport_free(transport); 354 sctp_transport_free(transport);
357 } 355 }
358 356
357 asoc->peer.transport_count = 0;
358
359 /* Free any cached ASCONF_ACK chunk. */ 359 /* Free any cached ASCONF_ACK chunk. */
360 if (asoc->addip_last_asconf_ack) 360 if (asoc->addip_last_asconf_ack)
361 sctp_chunk_free(asoc->addip_last_asconf_ack); 361 sctp_chunk_free(asoc->addip_last_asconf_ack);
@@ -400,7 +400,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
400 /* If the primary path is changing, assume that the 400 /* If the primary path is changing, assume that the
401 * user wants to use this new path. 401 * user wants to use this new path.
402 */ 402 */
403 if (transport->active) 403 if (transport->state != SCTP_INACTIVE)
404 asoc->peer.active_path = transport; 404 asoc->peer.active_path = transport;
405 405
406 /* 406 /*
@@ -428,10 +428,58 @@ void sctp_assoc_set_primary(struct sctp_association *asoc,
428 transport->cacc.next_tsn_at_change = asoc->next_tsn; 428 transport->cacc.next_tsn_at_change = asoc->next_tsn;
429} 429}
430 430
431/* Remove a transport from an association. */
432void sctp_assoc_rm_peer(struct sctp_association *asoc,
433 struct sctp_transport *peer)
434{
435 struct list_head *pos;
436 struct sctp_transport *transport;
437
438 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_rm_peer:association %p addr: ",
439 " port: %d\n",
440 asoc,
441 (&peer->ipaddr),
442 peer->ipaddr.v4.sin_port);
443
444 /* If we are to remove the current retran_path, update it
445 * to the next peer before removing this peer from the list.
446 */
447 if (asoc->peer.retran_path == peer)
448 sctp_assoc_update_retran_path(asoc);
449
450 /* Remove this peer from the list. */
451 list_del(&peer->transports);
452
453 /* Get the first transport of asoc. */
454 pos = asoc->peer.transport_addr_list.next;
455 transport = list_entry(pos, struct sctp_transport, transports);
456
457 /* Update any entries that match the peer to be deleted. */
458 if (asoc->peer.primary_path == peer)
459 sctp_assoc_set_primary(asoc, transport);
460 if (asoc->peer.active_path == peer)
461 asoc->peer.active_path = transport;
462 if (asoc->peer.last_data_from == peer)
463 asoc->peer.last_data_from = transport;
464
465 /* If we remove the transport an INIT was last sent to, set it to
466 * NULL. Combined with the update of the retran path above, this
467 * will cause the next INIT to be sent to the next available
468 * transport, maintaining the cycle.
469 */
470 if (asoc->init_last_sent_to == peer)
471 asoc->init_last_sent_to = NULL;
472
473 asoc->peer.transport_count--;
474
475 sctp_transport_free(peer);
476}
477
431/* Add a transport address to an association. */ 478/* Add a transport address to an association. */
432struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, 479struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
433 const union sctp_addr *addr, 480 const union sctp_addr *addr,
434 int gfp) 481 const int gfp,
482 const int peer_state)
435{ 483{
436 struct sctp_transport *peer; 484 struct sctp_transport *peer;
437 struct sctp_sock *sp; 485 struct sctp_sock *sp;
@@ -442,14 +490,25 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
442 /* AF_INET and AF_INET6 share common port field. */ 490 /* AF_INET and AF_INET6 share common port field. */
443 port = addr->v4.sin_port; 491 port = addr->v4.sin_port;
444 492
493 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ",
494 " port: %d state:%s\n",
495 asoc,
496 addr,
497 addr->v4.sin_port,
498 peer_state == SCTP_UNKNOWN?"UNKNOWN":"ACTIVE");
499
445 /* Set the port if it has not been set yet. */ 500 /* Set the port if it has not been set yet. */
446 if (0 == asoc->peer.port) 501 if (0 == asoc->peer.port)
447 asoc->peer.port = port; 502 asoc->peer.port = port;
448 503
449 /* Check to see if this is a duplicate. */ 504 /* Check to see if this is a duplicate. */
450 peer = sctp_assoc_lookup_paddr(asoc, addr); 505 peer = sctp_assoc_lookup_paddr(asoc, addr);
451 if (peer) 506 if (peer) {
507 if (peer_state == SCTP_ACTIVE &&
508 peer->state == SCTP_UNKNOWN)
509 peer->state = SCTP_ACTIVE;
452 return peer; 510 return peer;
511 }
453 512
454 peer = sctp_transport_new(addr, gfp); 513 peer = sctp_transport_new(addr, gfp);
455 if (!peer) 514 if (!peer)
@@ -516,8 +575,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
516 /* Set the transport's RTO.initial value */ 575 /* Set the transport's RTO.initial value */
517 peer->rto = asoc->rto_initial; 576 peer->rto = asoc->rto_initial;
518 577
578 /* Set the peer's active state. */
579 peer->state = peer_state;
580
519 /* Attach the remote transport to our asoc. */ 581 /* Attach the remote transport to our asoc. */
520 list_add_tail(&peer->transports, &asoc->peer.transport_addr_list); 582 list_add_tail(&peer->transports, &asoc->peer.transport_addr_list);
583 asoc->peer.transport_count++;
521 584
522 /* If we do not yet have a primary path, set one. */ 585 /* If we do not yet have a primary path, set one. */
523 if (!asoc->peer.primary_path) { 586 if (!asoc->peer.primary_path) {
@@ -525,8 +588,9 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
525 asoc->peer.retran_path = peer; 588 asoc->peer.retran_path = peer;
526 } 589 }
527 590
528 if (asoc->peer.active_path == asoc->peer.retran_path) 591 if (asoc->peer.active_path == asoc->peer.retran_path) {
529 asoc->peer.retran_path = peer; 592 asoc->peer.retran_path = peer;
593 }
530 594
531 return peer; 595 return peer;
532} 596}
@@ -537,37 +601,16 @@ void sctp_assoc_del_peer(struct sctp_association *asoc,
537{ 601{
538 struct list_head *pos; 602 struct list_head *pos;
539 struct list_head *temp; 603 struct list_head *temp;
540 struct sctp_transport *peer = NULL;
541 struct sctp_transport *transport; 604 struct sctp_transport *transport;
542 605
543 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 606 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
544 transport = list_entry(pos, struct sctp_transport, transports); 607 transport = list_entry(pos, struct sctp_transport, transports);
545 if (sctp_cmp_addr_exact(addr, &transport->ipaddr)) { 608 if (sctp_cmp_addr_exact(addr, &transport->ipaddr)) {
546 peer = transport; 609 /* Do book keeping for removing the peer and free it. */
547 list_del(pos); 610 sctp_assoc_rm_peer(asoc, transport);
548 break; 611 break;
549 } 612 }
550 } 613 }
551
552 /* The address we want delete is not in the association. */
553 if (!peer)
554 return;
555
556 /* Get the first transport of asoc. */
557 pos = asoc->peer.transport_addr_list.next;
558 transport = list_entry(pos, struct sctp_transport, transports);
559
560 /* Update any entries that match the peer to be deleted. */
561 if (asoc->peer.primary_path == peer)
562 sctp_assoc_set_primary(asoc, transport);
563 if (asoc->peer.active_path == peer)
564 asoc->peer.active_path = transport;
565 if (asoc->peer.retran_path == peer)
566 asoc->peer.retran_path = transport;
567 if (asoc->peer.last_data_from == peer)
568 asoc->peer.last_data_from = transport;
569
570 sctp_transport_free(peer);
571} 614}
572 615
573/* Lookup a transport by address. */ 616/* Lookup a transport by address. */
@@ -608,12 +651,12 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
608 /* Record the transition on the transport. */ 651 /* Record the transition on the transport. */
609 switch (command) { 652 switch (command) {
610 case SCTP_TRANSPORT_UP: 653 case SCTP_TRANSPORT_UP:
611 transport->active = SCTP_ACTIVE; 654 transport->state = SCTP_ACTIVE;
612 spc_state = SCTP_ADDR_AVAILABLE; 655 spc_state = SCTP_ADDR_AVAILABLE;
613 break; 656 break;
614 657
615 case SCTP_TRANSPORT_DOWN: 658 case SCTP_TRANSPORT_DOWN:
616 transport->active = SCTP_INACTIVE; 659 transport->state = SCTP_INACTIVE;
617 spc_state = SCTP_ADDR_UNREACHABLE; 660 spc_state = SCTP_ADDR_UNREACHABLE;
618 break; 661 break;
619 662
@@ -643,7 +686,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
643 list_for_each(pos, &asoc->peer.transport_addr_list) { 686 list_for_each(pos, &asoc->peer.transport_addr_list) {
644 t = list_entry(pos, struct sctp_transport, transports); 687 t = list_entry(pos, struct sctp_transport, transports);
645 688
646 if (!t->active) 689 if (t->state == SCTP_INACTIVE)
647 continue; 690 continue;
648 if (!first || t->last_time_heard > first->last_time_heard) { 691 if (!first || t->last_time_heard > first->last_time_heard) {
649 second = first; 692 second = first;
@@ -663,7 +706,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
663 * [If the primary is active but not most recent, bump the most 706 * [If the primary is active but not most recent, bump the most
664 * recently used transport.] 707 * recently used transport.]
665 */ 708 */
666 if (asoc->peer.primary_path->active && 709 if (asoc->peer.primary_path->state != SCTP_INACTIVE &&
667 first != asoc->peer.primary_path) { 710 first != asoc->peer.primary_path) {
668 second = first; 711 second = first;
669 first = asoc->peer.primary_path; 712 first = asoc->peer.primary_path;
@@ -958,7 +1001,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
958 transports); 1001 transports);
959 if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr)) 1002 if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr))
960 sctp_assoc_add_peer(asoc, &trans->ipaddr, 1003 sctp_assoc_add_peer(asoc, &trans->ipaddr,
961 GFP_ATOMIC); 1004 GFP_ATOMIC, SCTP_ACTIVE);
962 } 1005 }
963 1006
964 asoc->ctsn_ack_point = asoc->next_tsn - 1; 1007 asoc->ctsn_ack_point = asoc->next_tsn - 1;
@@ -998,7 +1041,7 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
998 1041
999 /* Try to find an active transport. */ 1042 /* Try to find an active transport. */
1000 1043
1001 if (t->active) { 1044 if (t->state != SCTP_INACTIVE) {
1002 break; 1045 break;
1003 } else { 1046 } else {
1004 /* Keep track of the next transport in case 1047 /* Keep track of the next transport in case
@@ -1019,6 +1062,40 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
1019 } 1062 }
1020 1063
1021 asoc->peer.retran_path = t; 1064 asoc->peer.retran_path = t;
1065
1066 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
1067 " %p addr: ",
1068 " port: %d\n",
1069 asoc,
1070 (&t->ipaddr),
1071 t->ipaddr.v4.sin_port);
1072}
1073
1074/* Choose the transport for sending a INIT packet. */
1075struct sctp_transport *sctp_assoc_choose_init_transport(
1076 struct sctp_association *asoc)
1077{
1078 struct sctp_transport *t;
1079
1080 /* Use the retran path. If the last INIT was sent over the
1081 * retran path, update the retran path and use it.
1082 */
1083 if (!asoc->init_last_sent_to) {
1084 t = asoc->peer.active_path;
1085 } else {
1086 if (asoc->init_last_sent_to == asoc->peer.retran_path)
1087 sctp_assoc_update_retran_path(asoc);
1088 t = asoc->peer.retran_path;
1089 }
1090
1091 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
1092 " %p addr: ",
1093 " port: %d\n",
1094 asoc,
1095 (&t->ipaddr),
1096 t->ipaddr.v4.sin_port);
1097
1098 return t;
1022} 1099}
1023 1100
1024/* Choose the transport for sending a SHUTDOWN packet. */ 1101/* Choose the transport for sending a SHUTDOWN packet. */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 334f61773e6d..2ec0320fac3b 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -134,7 +134,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
134 ep->last_key = ep->current_key = 0; 134 ep->last_key = ep->current_key = 0;
135 ep->key_changed_at = jiffies; 135 ep->key_changed_at = jiffies;
136 136
137 ep->debug_name = "unnamedEndpoint";
138 return ep; 137 return ep;
139} 138}
140 139
diff --git a/net/sctp/input.c b/net/sctp/input.c
index fffc880a646d..339f7acfdb64 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -353,7 +353,7 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
353 353
354 sctp_do_sm(SCTP_EVENT_T_OTHER, 354 sctp_do_sm(SCTP_EVENT_T_OTHER,
355 SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), 355 SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH),
356 asoc->state, asoc->ep, asoc, NULL, 356 asoc->state, asoc->ep, asoc, t,
357 GFP_ATOMIC); 357 GFP_ATOMIC);
358 358
359} 359}
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 1b2d4adc4ddb..4eb81a1407b7 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -682,9 +682,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
682 682
683 if (!new_transport) { 683 if (!new_transport) {
684 new_transport = asoc->peer.active_path; 684 new_transport = asoc->peer.active_path;
685 } else if (!new_transport->active) { 685 } else if (new_transport->state == SCTP_INACTIVE) {
686 /* If the chunk is Heartbeat or Heartbeat Ack, 686 /* If the chunk is Heartbeat or Heartbeat Ack,
687 * send it to chunk->transport, even if it's 687 * send it to chunk->transport, even if it's
688 * inactive. 688 * inactive.
689 * 689 *
690 * 3.3.6 Heartbeat Acknowledgement: 690 * 3.3.6 Heartbeat Acknowledgement:
@@ -840,7 +840,8 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
840 * Otherwise, we want to use the active path. 840 * Otherwise, we want to use the active path.
841 */ 841 */
842 new_transport = chunk->transport; 842 new_transport = chunk->transport;
843 if (!new_transport || !new_transport->active) 843 if (!new_transport ||
844 new_transport->state == SCTP_INACTIVE)
844 new_transport = asoc->peer.active_path; 845 new_transport = asoc->peer.active_path;
845 846
846 /* Change packets if necessary. */ 847 /* Change packets if necessary. */
@@ -1454,7 +1455,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1454 /* Mark the destination transport address as 1455 /* Mark the destination transport address as
1455 * active if it is not so marked. 1456 * active if it is not so marked.
1456 */ 1457 */
1457 if (!transport->active) { 1458 if (transport->state == SCTP_INACTIVE) {
1458 sctp_assoc_control_transport( 1459 sctp_assoc_control_transport(
1459 transport->asoc, 1460 transport->asoc,
1460 transport, 1461 transport,
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 33ac8bf47b0e..5baed9bb7de5 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1830,7 +1830,7 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
1830 * be a a better choice than any of the embedded addresses. 1830 * be a a better choice than any of the embedded addresses.
1831 */ 1831 */
1832 if (peer_addr) 1832 if (peer_addr)
1833 if(!sctp_assoc_add_peer(asoc, peer_addr, gfp)) 1833 if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
1834 goto nomem; 1834 goto nomem;
1835 1835
1836 /* Process the initialization parameters. */ 1836 /* Process the initialization parameters. */
@@ -1841,6 +1841,14 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
1841 goto clean_up; 1841 goto clean_up;
1842 } 1842 }
1843 1843
1844 /* Walk list of transports, removing transports in the UNKNOWN state. */
1845 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
1846 transport = list_entry(pos, struct sctp_transport, transports);
1847 if (transport->state == SCTP_UNKNOWN) {
1848 sctp_assoc_rm_peer(asoc, transport);
1849 }
1850 }
1851
1844 /* The fixed INIT headers are always in network byte 1852 /* The fixed INIT headers are always in network byte
1845 * order. 1853 * order.
1846 */ 1854 */
@@ -1906,7 +1914,8 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
1906 * stream sequence number shall be set to 0. 1914 * stream sequence number shall be set to 0.
1907 */ 1915 */
1908 1916
1909 /* Allocate storage for the negotiated streams if it is not a temporary * association. 1917 /* Allocate storage for the negotiated streams if it is not a temporary
1918 * association.
1910 */ 1919 */
1911 if (!asoc->temp) { 1920 if (!asoc->temp) {
1912 int assoc_id; 1921 int assoc_id;
@@ -1952,6 +1961,9 @@ clean_up:
1952 list_del_init(pos); 1961 list_del_init(pos);
1953 sctp_transport_free(transport); 1962 sctp_transport_free(transport);
1954 } 1963 }
1964
1965 asoc->peer.transport_count = 0;
1966
1955nomem: 1967nomem:
1956 return 0; 1968 return 0;
1957} 1969}
@@ -1995,7 +2007,7 @@ static int sctp_process_param(struct sctp_association *asoc,
1995 af->from_addr_param(&addr, param.addr, asoc->peer.port, 0); 2007 af->from_addr_param(&addr, param.addr, asoc->peer.port, 0);
1996 scope = sctp_scope(peer_addr); 2008 scope = sctp_scope(peer_addr);
1997 if (sctp_in_scope(&addr, scope)) 2009 if (sctp_in_scope(&addr, scope))
1998 if (!sctp_assoc_add_peer(asoc, &addr, gfp)) 2010 if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_ACTIVE))
1999 return 0; 2011 return 0;
2000 break; 2012 break;
2001 2013
@@ -2396,7 +2408,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc,
2396 * Due to Resource Shortage'. 2408 * Due to Resource Shortage'.
2397 */ 2409 */
2398 2410
2399 peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC); 2411 peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_ACTIVE);
2400 if (!peer) 2412 if (!peer)
2401 return SCTP_ERROR_RSRC_LOW; 2413 return SCTP_ERROR_RSRC_LOW;
2402 2414
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index f65fa441952f..778639db125a 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -414,11 +414,13 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
414 */ 414 */
415 asoc->overall_error_count++; 415 asoc->overall_error_count++;
416 416
417 if (transport->active && 417 if (transport->state != SCTP_INACTIVE &&
418 (transport->error_count++ >= transport->max_retrans)) { 418 (transport->error_count++ >= transport->max_retrans)) {
419 SCTP_DEBUG_PRINTK("transport_strike: transport " 419 SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
420 "IP:%d.%d.%d.%d failed.\n", 420 " transport IP: port:%d failed.\n",
421 NIPQUAD(transport->ipaddr.v4.sin_addr)); 421 asoc,
422 (&transport->ipaddr),
423 transport->ipaddr.v4.sin_port);
422 sctp_assoc_control_transport(asoc, transport, 424 sctp_assoc_control_transport(asoc, transport,
423 SCTP_TRANSPORT_DOWN, 425 SCTP_TRANSPORT_DOWN,
424 SCTP_FAILED_THRESHOLD); 426 SCTP_FAILED_THRESHOLD);
@@ -593,7 +595,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
593 /* Mark the destination transport address as active if it is not so 595 /* Mark the destination transport address as active if it is not so
594 * marked. 596 * marked.
595 */ 597 */
596 if (!t->active) 598 if (t->state == SCTP_INACTIVE)
597 sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP, 599 sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP,
598 SCTP_HEARTBEAT_SUCCESS); 600 SCTP_HEARTBEAT_SUCCESS);
599 601
@@ -665,8 +667,11 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
665 667
666 asoc->state = state; 668 asoc->state = state;
667 669
670 SCTP_DEBUG_PRINTK("sctp_cmd_new_state: asoc %p[%s]\n",
671 asoc, sctp_state_tbl[state]);
672
668 if (sctp_style(sk, TCP)) { 673 if (sctp_style(sk, TCP)) {
669 /* Change the sk->sk_state of a TCP-style socket that has 674 /* Change the sk->sk_state of a TCP-style socket that has
670 * sucessfully completed a connect() call. 675 * sucessfully completed a connect() call.
671 */ 676 */
672 if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED)) 677 if (sctp_state(asoc, ESTABLISHED) && sctp_sstate(sk, CLOSED))
@@ -678,6 +683,16 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds,
678 sk->sk_shutdown |= RCV_SHUTDOWN; 683 sk->sk_shutdown |= RCV_SHUTDOWN;
679 } 684 }
680 685
686 if (sctp_state(asoc, COOKIE_WAIT)) {
687 /* Reset init timeouts since they may have been
688 * increased due to timer expirations.
689 */
690 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
691 asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT];
692 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
693 asoc->ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE];
694 }
695
681 if (sctp_state(asoc, ESTABLISHED) || 696 if (sctp_state(asoc, ESTABLISHED) ||
682 sctp_state(asoc, CLOSED) || 697 sctp_state(asoc, CLOSED) ||
683 sctp_state(asoc, SHUTDOWN_RECEIVED)) { 698 sctp_state(asoc, SHUTDOWN_RECEIVED)) {
@@ -1120,10 +1135,10 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1120 * to be executed only during failed attempts of 1135 * to be executed only during failed attempts of
1121 * association establishment. 1136 * association establishment.
1122 */ 1137 */
1123 if ((asoc->peer.retran_path != 1138 if ((asoc->peer.retran_path !=
1124 asoc->peer.primary_path) && 1139 asoc->peer.primary_path) &&
1125 (asoc->counters[SCTP_COUNTER_INIT_ERROR] > 0)) { 1140 (asoc->init_err_counter > 0)) {
1126 sctp_add_cmd_sf(commands, 1141 sctp_add_cmd_sf(commands,
1127 SCTP_CMD_FORCE_PRIM_RETRAN, 1142 SCTP_CMD_FORCE_PRIM_RETRAN,
1128 SCTP_NULL()); 1143 SCTP_NULL());
1129 } 1144 }
@@ -1237,18 +1252,67 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1237 sctp_association_put(asoc); 1252 sctp_association_put(asoc);
1238 break; 1253 break;
1239 1254
1255 case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
1256 chunk = cmd->obj.ptr;
1257 t = sctp_assoc_choose_init_transport(asoc);
1258 asoc->init_last_sent_to = t;
1259 chunk->transport = t;
1260 t->init_sent_count++;
1261 break;
1262
1240 case SCTP_CMD_INIT_RESTART: 1263 case SCTP_CMD_INIT_RESTART:
1241 /* Do the needed accounting and updates 1264 /* Do the needed accounting and updates
1242 * associated with restarting an initialization 1265 * associated with restarting an initialization
1243 * timer. 1266 * timer. Only multiply the timeout by two if
1267 * all transports have been tried at the current
1268 * timeout.
1269 */
1270 t = asoc->init_last_sent_to;
1271 asoc->init_err_counter++;
1272
1273 if (t->init_sent_count > (asoc->init_cycle + 1)) {
1274 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] *= 2;
1275 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] >
1276 asoc->max_init_timeo) {
1277 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
1278 asoc->max_init_timeo;
1279 }
1280 asoc->init_cycle++;
1281 SCTP_DEBUG_PRINTK(
1282 "T1 INIT Timeout adjustment"
1283 " init_err_counter: %d"
1284 " cycle: %d"
1285 " timeout: %d\n",
1286 asoc->init_err_counter,
1287 asoc->init_cycle,
1288 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
1289 }
1290
1291 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
1292 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
1293 break;
1294
1295 case SCTP_CMD_COOKIEECHO_RESTART:
1296 /* Do the needed accounting and updates
1297 * associated with restarting an initialization
1298 * timer. Only multiply the timeout by two if
1299 * all transports have been tried at the current
1300 * timeout.
1244 */ 1301 */
1245 asoc->counters[SCTP_COUNTER_INIT_ERROR]++; 1302 asoc->init_err_counter++;
1246 asoc->timeouts[cmd->obj.to] *= 2; 1303
1247 if (asoc->timeouts[cmd->obj.to] > 1304 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] *= 2;
1305 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] >
1248 asoc->max_init_timeo) { 1306 asoc->max_init_timeo) {
1249 asoc->timeouts[cmd->obj.to] = 1307 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
1250 asoc->max_init_timeo; 1308 asoc->max_init_timeo;
1251 } 1309 }
1310 SCTP_DEBUG_PRINTK(
1311 "T1 COOKIE Timeout adjustment"
1312 " init_err_counter: %d"
1313 " timeout: %d\n",
1314 asoc->init_err_counter,
1315 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
1252 1316
1253 /* If we've sent any data bundled with 1317 /* If we've sent any data bundled with
1254 * COOKIE-ECHO we need to resend. 1318 * COOKIE-ECHO we need to resend.
@@ -1261,7 +1325,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1261 1325
1262 sctp_add_cmd_sf(commands, 1326 sctp_add_cmd_sf(commands,
1263 SCTP_CMD_TIMER_RESTART, 1327 SCTP_CMD_TIMER_RESTART,
1264 SCTP_TO(cmd->obj.to)); 1328 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
1265 break; 1329 break;
1266 1330
1267 case SCTP_CMD_INIT_FAILED: 1331 case SCTP_CMD_INIT_FAILED:
@@ -1273,12 +1337,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1273 subtype, chunk, cmd->obj.u32); 1337 subtype, chunk, cmd->obj.u32);
1274 break; 1338 break;
1275 1339
1276 case SCTP_CMD_COUNTER_INC: 1340 case SCTP_CMD_INIT_COUNTER_INC:
1277 asoc->counters[cmd->obj.counter]++; 1341 asoc->init_err_counter++;
1278 break; 1342 break;
1279 1343
1280 case SCTP_CMD_COUNTER_RESET: 1344 case SCTP_CMD_INIT_COUNTER_RESET:
1281 asoc->counters[cmd->obj.counter] = 0; 1345 asoc->init_err_counter = 0;
1346 asoc->init_cycle = 0;
1282 break; 1347 break;
1283 1348
1284 case SCTP_CMD_REPORT_DUP: 1349 case SCTP_CMD_REPORT_DUP:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 8e01b8f09ac2..058189684c7c 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -533,6 +533,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
533 sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT, 533 sctp_add_cmd_sf(commands, SCTP_CMD_PEER_INIT,
534 SCTP_PEER_INIT(initchunk)); 534 SCTP_PEER_INIT(initchunk));
535 535
536 /* Reset init error count upon receipt of INIT-ACK. */
537 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
538
536 /* 5.1 C) "A" shall stop the T1-init timer and leave 539 /* 5.1 C) "A" shall stop the T1-init timer and leave
537 * COOKIE-WAIT state. "A" shall then ... start the T1-cookie 540 * COOKIE-WAIT state. "A" shall then ... start the T1-cookie
538 * timer, and enter the COOKIE-ECHOED state. 541 * timer, and enter the COOKIE-ECHOED state.
@@ -775,8 +778,7 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
775 * from the COOKIE-ECHOED state to the COOKIE-WAIT 778 * from the COOKIE-ECHOED state to the COOKIE-WAIT
776 * state is performed. 779 * state is performed.
777 */ 780 */
778 sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_RESET, 781 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
779 SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
780 782
781 /* RFC 2960 5.1 Normal Establishment of an Association 783 /* RFC 2960 5.1 Normal Establishment of an Association
782 * 784 *
@@ -1019,10 +1021,22 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
1019 link = sctp_assoc_lookup_paddr(asoc, &from_addr); 1021 link = sctp_assoc_lookup_paddr(asoc, &from_addr);
1020 1022
1021 /* This should never happen, but lets log it if so. */ 1023 /* This should never happen, but lets log it if so. */
1022 if (!link) { 1024 if (unlikely(!link)) {
1023 printk(KERN_WARNING 1025 if (from_addr.sa.sa_family == AF_INET6) {
1024 "%s: Could not find address %d.%d.%d.%d\n", 1026 printk(KERN_WARNING
1025 __FUNCTION__, NIPQUAD(from_addr.v4.sin_addr)); 1027 "%s association %p could not find address "
1028 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
1029 __FUNCTION__,
1030 asoc,
1031 NIP6(from_addr.v6.sin6_addr));
1032 } else {
1033 printk(KERN_WARNING
1034 "%s association %p could not find address "
1035 "%u.%u.%u.%u\n",
1036 __FUNCTION__,
1037 asoc,
1038 NIPQUAD(from_addr.v4.sin_addr.s_addr));
1039 }
1026 return SCTP_DISPOSITION_DISCARD; 1040 return SCTP_DISPOSITION_DISCARD;
1027 } 1041 }
1028 1042
@@ -2095,9 +2109,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
2095 sctp_errhdr_t *err; 2109 sctp_errhdr_t *err;
2096 struct sctp_chunk *reply; 2110 struct sctp_chunk *reply;
2097 struct sctp_bind_addr *bp; 2111 struct sctp_bind_addr *bp;
2098 int attempts; 2112 int attempts = asoc->init_err_counter + 1;
2099
2100 attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
2101 2113
2102 if (attempts >= asoc->max_init_attempts) { 2114 if (attempts >= asoc->max_init_attempts) {
2103 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 2115 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
@@ -2157,8 +2169,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
2157 /* Cast away the const modifier, as we want to just 2169 /* Cast away the const modifier, as we want to just
2158 * rerun it through as a sideffect. 2170 * rerun it through as a sideffect.
2159 */ 2171 */
2160 sctp_add_cmd_sf(commands, SCTP_CMD_COUNTER_INC, 2172 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_INC, SCTP_NULL());
2161 SCTP_COUNTER(SCTP_COUNTER_INIT_ERROR));
2162 2173
2163 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 2174 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2164 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE)); 2175 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
@@ -2281,8 +2292,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
2281 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr)) 2292 if (len >= sizeof(struct sctp_chunkhdr) + sizeof(struct sctp_errhdr))
2282 error = ((sctp_errhdr_t *)chunk->skb->data)->cause; 2293 error = ((sctp_errhdr_t *)chunk->skb->data)->cause;
2283 2294
2284 sctp_stop_t1_and_abort(commands, error); 2295 return sctp_stop_t1_and_abort(commands, error, asoc, chunk->transport);
2285 return SCTP_DISPOSITION_ABORT;
2286} 2296}
2287 2297
2288/* 2298/*
@@ -2294,8 +2304,8 @@ sctp_disposition_t sctp_sf_cookie_wait_icmp_abort(const struct sctp_endpoint *ep
2294 void *arg, 2304 void *arg,
2295 sctp_cmd_seq_t *commands) 2305 sctp_cmd_seq_t *commands)
2296{ 2306{
2297 sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR); 2307 return sctp_stop_t1_and_abort(commands, SCTP_ERROR_NO_ERROR, asoc,
2298 return SCTP_DISPOSITION_ABORT; 2308 (struct sctp_transport *)arg);
2299} 2309}
2300 2310
2301/* 2311/*
@@ -2318,8 +2328,12 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
2318 * 2328 *
2319 * This is common code called by several sctp_sf_*_abort() functions above. 2329 * This is common code called by several sctp_sf_*_abort() functions above.
2320 */ 2330 */
2321void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error) 2331sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
2332 __u16 error,
2333 const struct sctp_association *asoc,
2334 struct sctp_transport *transport)
2322{ 2335{
2336 SCTP_DEBUG_PRINTK("ABORT received (INIT).\n");
2323 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 2337 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
2324 SCTP_STATE(SCTP_STATE_CLOSED)); 2338 SCTP_STATE(SCTP_STATE_CLOSED));
2325 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 2339 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
@@ -2328,6 +2342,7 @@ void sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, __u16 error)
2328 /* CMD_INIT_FAILED will DELETE_TCB. */ 2342 /* CMD_INIT_FAILED will DELETE_TCB. */
2329 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 2343 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
2330 SCTP_U32(error)); 2344 SCTP_U32(error));
2345 return SCTP_DISPOSITION_ABORT;
2331} 2346}
2332 2347
2333/* 2348/*
@@ -3805,6 +3820,10 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
3805 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, 3820 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC,
3806 SCTP_ASOC((struct sctp_association *) asoc)); 3821 SCTP_ASOC((struct sctp_association *) asoc));
3807 3822
3823 /* Choose transport for INIT. */
3824 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
3825 SCTP_CHUNK(repl));
3826
3808 /* After sending the INIT, "A" starts the T1-init timer and 3827 /* After sending the INIT, "A" starts the T1-init timer and
3809 * enters the COOKIE-WAIT state. 3828 * enters the COOKIE-WAIT state.
3810 */ 3829 */
@@ -4589,7 +4608,7 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
4589} 4608}
4590 4609
4591/* 4610/*
4592 * sctp_sf_t1_timer_expire 4611 * sctp_sf_t1_init_timer_expire
4593 * 4612 *
4594 * Section: 4 Note: 2 4613 * Section: 4 Note: 2
4595 * Verification Tag: 4614 * Verification Tag:
@@ -4603,7 +4622,59 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
4603 * endpoint MUST abort the initialization process and report the 4622 * endpoint MUST abort the initialization process and report the
4604 * error to SCTP user. 4623 * error to SCTP user.
4605 * 4624 *
4606 * 3) If the T1-cookie timer expires, the endpoint MUST retransmit 4625 * Outputs
4626 * (timers, events)
4627 *
4628 */
4629sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
4630 const struct sctp_association *asoc,
4631 const sctp_subtype_t type,
4632 void *arg,
4633 sctp_cmd_seq_t *commands)
4634{
4635 struct sctp_chunk *repl = NULL;
4636 struct sctp_bind_addr *bp;
4637 int attempts = asoc->init_err_counter + 1;
4638
4639 SCTP_DEBUG_PRINTK("Timer T1 expired (INIT).\n");
4640
4641 if (attempts < asoc->max_init_attempts) {
4642 bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
4643 repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
4644 if (!repl)
4645 return SCTP_DISPOSITION_NOMEM;
4646
4647 /* Choose transport for INIT. */
4648 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
4649 SCTP_CHUNK(repl));
4650
4651 /* Issue a sideeffect to do the needed accounting. */
4652 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART,
4653 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
4654
4655 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
4656 } else {
4657 SCTP_DEBUG_PRINTK("Giving up on INIT, attempts: %d"
4658 " max_init_attempts: %d\n",
4659 attempts, asoc->max_init_attempts);
4660 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4661 SCTP_U32(SCTP_ERROR_NO_ERROR));
4662 return SCTP_DISPOSITION_DELETE_TCB;
4663 }
4664
4665 return SCTP_DISPOSITION_CONSUME;
4666}
4667
4668/*
4669 * sctp_sf_t1_cookie_timer_expire
4670 *
4671 * Section: 4 Note: 2
4672 * Verification Tag:
4673 * Inputs
4674 * (endpoint, asoc)
4675 *
4676 * RFC 2960 Section 4 Notes
4677 * 3) If the T1-cookie timer expires, the endpoint MUST retransmit
4607 * COOKIE ECHO and re-start the T1-cookie timer without changing 4678 * COOKIE ECHO and re-start the T1-cookie timer without changing
4608 * state. This MUST be repeated up to 'Max.Init.Retransmits' times. 4679 * state. This MUST be repeated up to 'Max.Init.Retransmits' times.
4609 * After that, the endpoint MUST abort the initialization process and 4680 * After that, the endpoint MUST abort the initialization process and
@@ -4613,46 +4684,26 @@ sctp_disposition_t sctp_sf_do_6_2_sack(const struct sctp_endpoint *ep,
4613 * (timers, events) 4684 * (timers, events)
4614 * 4685 *
4615 */ 4686 */
4616sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep, 4687sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep,
4617 const struct sctp_association *asoc, 4688 const struct sctp_association *asoc,
4618 const sctp_subtype_t type, 4689 const sctp_subtype_t type,
4619 void *arg, 4690 void *arg,
4620 sctp_cmd_seq_t *commands) 4691 sctp_cmd_seq_t *commands)
4621{ 4692{
4622 struct sctp_chunk *repl; 4693 struct sctp_chunk *repl = NULL;
4623 struct sctp_bind_addr *bp; 4694 int attempts = asoc->init_err_counter + 1;
4624 sctp_event_timeout_t timer = (sctp_event_timeout_t) arg;
4625 int timeout;
4626 int attempts;
4627
4628 timeout = asoc->timeouts[timer];
4629 attempts = asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1;
4630 repl = NULL;
4631 4695
4632 SCTP_DEBUG_PRINTK("Timer T1 expired.\n"); 4696 SCTP_DEBUG_PRINTK("Timer T1 expired (COOKIE-ECHO).\n");
4633 4697
4634 if (attempts < asoc->max_init_attempts) { 4698 if (attempts < asoc->max_init_attempts) {
4635 switch (timer) { 4699 repl = sctp_make_cookie_echo(asoc, NULL);
4636 case SCTP_EVENT_TIMEOUT_T1_INIT:
4637 bp = (struct sctp_bind_addr *) &asoc->base.bind_addr;
4638 repl = sctp_make_init(asoc, bp, GFP_ATOMIC, 0);
4639 break;
4640
4641 case SCTP_EVENT_TIMEOUT_T1_COOKIE:
4642 repl = sctp_make_cookie_echo(asoc, NULL);
4643 break;
4644
4645 default:
4646 BUG();
4647 break;
4648 };
4649
4650 if (!repl) 4700 if (!repl)
4651 goto nomem; 4701 return SCTP_DISPOSITION_NOMEM;
4652 4702
4653 /* Issue a sideeffect to do the needed accounting. */ 4703 /* Issue a sideeffect to do the needed accounting. */
4654 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_RESTART, 4704 sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
4655 SCTP_TO(timer)); 4705 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
4706
4656 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); 4707 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
4657 } else { 4708 } else {
4658 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 4709 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
@@ -4661,9 +4712,6 @@ sctp_disposition_t sctp_sf_t1_timer_expire(const struct sctp_endpoint *ep,
4661 } 4712 }
4662 4713
4663 return SCTP_DISPOSITION_CONSUME; 4714 return SCTP_DISPOSITION_CONSUME;
4664
4665nomem:
4666 return SCTP_DISPOSITION_NOMEM;
4667} 4715}
4668 4716
4669/* RFC2960 9.2 If the timer expires, the endpoint must re-send the SHUTDOWN 4717/* RFC2960 9.2 If the timer expires, the endpoint must re-send the SHUTDOWN
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 8967846f69e8..75ef10408764 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -783,7 +783,8 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
783 /* SCTP_STATE_COOKIE_WAIT */ \ 783 /* SCTP_STATE_COOKIE_WAIT */ \
784 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 784 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \
785 /* SCTP_STATE_COOKIE_ECHOED */ \ 785 /* SCTP_STATE_COOKIE_ECHOED */ \
786 {.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \ 786 {.fn = sctp_sf_t1_cookie_timer_expire, \
787 .name = "sctp_sf_t1_cookie_timer_expire"}, \
787 /* SCTP_STATE_ESTABLISHED */ \ 788 /* SCTP_STATE_ESTABLISHED */ \
788 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 789 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
789 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 790 /* SCTP_STATE_SHUTDOWN_PENDING */ \
@@ -802,7 +803,8 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
802 /* SCTP_STATE_CLOSED */ \ 803 /* SCTP_STATE_CLOSED */ \
803 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 804 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
804 /* SCTP_STATE_COOKIE_WAIT */ \ 805 /* SCTP_STATE_COOKIE_WAIT */ \
805 {.fn = sctp_sf_t1_timer_expire, .name = "sctp_sf_t1_timer_expire"}, \ 806 {.fn = sctp_sf_t1_init_timer_expire, \
807 .name = "sctp_sf_t1_init_timer_expire"}, \
806 /* SCTP_STATE_COOKIE_ECHOED */ \ 808 /* SCTP_STATE_COOKIE_ECHOED */ \
807 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 809 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \
808 /* SCTP_STATE_ESTABLISHED */ \ 810 /* SCTP_STATE_ESTABLISHED */ \
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index e6926cb19420..aad55dc3792b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -262,18 +262,18 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
262 * sockaddr_in6 [RFC 2553]), 262 * sockaddr_in6 [RFC 2553]),
263 * addr_len - the size of the address structure. 263 * addr_len - the size of the address structure.
264 */ 264 */
265SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) 265SCTP_STATIC int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len)
266{ 266{
267 int retval = 0; 267 int retval = 0;
268 268
269 sctp_lock_sock(sk); 269 sctp_lock_sock(sk);
270 270
271 SCTP_DEBUG_PRINTK("sctp_bind(sk: %p, uaddr: %p, addr_len: %d)\n", 271 SCTP_DEBUG_PRINTK("sctp_bind(sk: %p, addr: %p, addr_len: %d)\n",
272 sk, uaddr, addr_len); 272 sk, addr, addr_len);
273 273
274 /* Disallow binding twice. */ 274 /* Disallow binding twice. */
275 if (!sctp_sk(sk)->ep->base.bind_addr.port) 275 if (!sctp_sk(sk)->ep->base.bind_addr.port)
276 retval = sctp_do_bind(sk, (union sctp_addr *)uaddr, 276 retval = sctp_do_bind(sk, (union sctp_addr *)addr,
277 addr_len); 277 addr_len);
278 else 278 else
279 retval = -EINVAL; 279 retval = -EINVAL;
@@ -318,23 +318,27 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
318 unsigned short snum; 318 unsigned short snum;
319 int ret = 0; 319 int ret = 0;
320 320
321 SCTP_DEBUG_PRINTK("sctp_do_bind(sk: %p, newaddr: %p, len: %d)\n",
322 sk, addr, len);
323
324 /* Common sockaddr verification. */ 321 /* Common sockaddr verification. */
325 af = sctp_sockaddr_af(sp, addr, len); 322 af = sctp_sockaddr_af(sp, addr, len);
326 if (!af) 323 if (!af) {
324 SCTP_DEBUG_PRINTK("sctp_do_bind(sk: %p, newaddr: %p, len: %d) EINVAL\n",
325 sk, addr, len);
327 return -EINVAL; 326 return -EINVAL;
327 }
328
329 snum = ntohs(addr->v4.sin_port);
330
331 SCTP_DEBUG_PRINTK_IPADDR("sctp_do_bind(sk: %p, new addr: ",
332 ", port: %d, new port: %d, len: %d)\n",
333 sk,
334 addr,
335 bp->port, snum,
336 len);
328 337
329 /* PF specific bind() address verification. */ 338 /* PF specific bind() address verification. */
330 if (!sp->pf->bind_verify(sp, addr)) 339 if (!sp->pf->bind_verify(sp, addr))
331 return -EADDRNOTAVAIL; 340 return -EADDRNOTAVAIL;
332 341
333 snum= ntohs(addr->v4.sin_port);
334
335 SCTP_DEBUG_PRINTK("sctp_do_bind: port: %d, new port: %d\n",
336 bp->port, snum);
337
338 /* We must either be unbound, or bind to the same port. */ 342 /* We must either be unbound, or bind to the same port. */
339 if (bp->port && (snum != bp->port)) { 343 if (bp->port && (snum != bp->port)) {
340 SCTP_DEBUG_PRINTK("sctp_do_bind:" 344 SCTP_DEBUG_PRINTK("sctp_do_bind:"
@@ -816,7 +820,8 @@ out:
816 * 820 *
817 * Basically do nothing but copying the addresses from user to kernel 821 * Basically do nothing but copying the addresses from user to kernel
818 * land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk. 822 * land and invoking either sctp_bindx_add() or sctp_bindx_rem() on the sk.
819 * This is used for tunneling the sctp_bindx() request through sctp_setsockopt() * from userspace. 823 * This is used for tunneling the sctp_bindx() request through sctp_setsockopt()
824 * from userspace.
820 * 825 *
821 * We don't use copy_from_user() for optimization: we first do the 826 * We don't use copy_from_user() for optimization: we first do the
822 * sanity checks (buffer size -fast- and access check-healthy 827 * sanity checks (buffer size -fast- and access check-healthy
@@ -913,6 +918,243 @@ out:
913 return err; 918 return err;
914} 919}
915 920
921/* __sctp_connect(struct sock* sk, struct sockaddr *kaddrs, int addrs_size)
922 *
923 * Common routine for handling connect() and sctp_connectx().
924 * Connect will come in with just a single address.
925 */
926static int __sctp_connect(struct sock* sk,
927 struct sockaddr *kaddrs,
928 int addrs_size)
929{
930 struct sctp_sock *sp;
931 struct sctp_endpoint *ep;
932 struct sctp_association *asoc = NULL;
933 struct sctp_association *asoc2;
934 struct sctp_transport *transport;
935 union sctp_addr to;
936 struct sctp_af *af;
937 sctp_scope_t scope;
938 long timeo;
939 int err = 0;
940 int addrcnt = 0;
941 int walk_size = 0;
942 struct sockaddr *sa_addr;
943 void *addr_buf;
944
945 sp = sctp_sk(sk);
946 ep = sp->ep;
947
948 /* connect() cannot be done on a socket that is already in ESTABLISHED
949 * state - UDP-style peeled off socket or a TCP-style socket that
950 * is already connected.
951 * It cannot be done even on a TCP-style listening socket.
952 */
953 if (sctp_sstate(sk, ESTABLISHED) ||
954 (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))) {
955 err = -EISCONN;
956 goto out_free;
957 }
958
959 /* Walk through the addrs buffer and count the number of addresses. */
960 addr_buf = kaddrs;
961 while (walk_size < addrs_size) {
962 sa_addr = (struct sockaddr *)addr_buf;
963 af = sctp_get_af_specific(sa_addr->sa_family);
964
965 /* If the address family is not supported or if this address
966 * causes the address buffer to overflow return EINVAL.
967 */
968 if (!af || (walk_size + af->sockaddr_len) > addrs_size) {
969 err = -EINVAL;
970 goto out_free;
971 }
972
973 err = sctp_verify_addr(sk, (union sctp_addr *)sa_addr,
974 af->sockaddr_len);
975 if (err)
976 goto out_free;
977
978 memcpy(&to, sa_addr, af->sockaddr_len);
979 to.v4.sin_port = ntohs(to.v4.sin_port);
980
981 /* Check if there already is a matching association on the
982 * endpoint (other than the one created here).
983 */
984 asoc2 = sctp_endpoint_lookup_assoc(ep, &to, &transport);
985 if (asoc2 && asoc2 != asoc) {
986 if (asoc2->state >= SCTP_STATE_ESTABLISHED)
987 err = -EISCONN;
988 else
989 err = -EALREADY;
990 goto out_free;
991 }
992
993 /* If we could not find a matching association on the endpoint,
994 * make sure that there is no peeled-off association matching
995 * the peer address even on another socket.
996 */
997 if (sctp_endpoint_is_peeled_off(ep, &to)) {
998 err = -EADDRNOTAVAIL;
999 goto out_free;
1000 }
1001
1002 if (!asoc) {
1003 /* If a bind() or sctp_bindx() is not called prior to
1004 * an sctp_connectx() call, the system picks an
1005 * ephemeral port and will choose an address set
1006 * equivalent to binding with a wildcard address.
1007 */
1008 if (!ep->base.bind_addr.port) {
1009 if (sctp_autobind(sk)) {
1010 err = -EAGAIN;
1011 goto out_free;
1012 }
1013 }
1014
1015 scope = sctp_scope(&to);
1016 asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
1017 if (!asoc) {
1018 err = -ENOMEM;
1019 goto out_free;
1020 }
1021 }
1022
1023 /* Prime the peer's transport structures. */
1024 transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL,
1025 SCTP_UNKNOWN);
1026 if (!transport) {
1027 err = -ENOMEM;
1028 goto out_free;
1029 }
1030
1031 addrcnt++;
1032 addr_buf += af->sockaddr_len;
1033 walk_size += af->sockaddr_len;
1034 }
1035
1036 err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
1037 if (err < 0) {
1038 goto out_free;
1039 }
1040
1041 err = sctp_primitive_ASSOCIATE(asoc, NULL);
1042 if (err < 0) {
1043 goto out_free;
1044 }
1045
1046 /* Initialize sk's dport and daddr for getpeername() */
1047 inet_sk(sk)->dport = htons(asoc->peer.port);
1048 af = sctp_get_af_specific(to.sa.sa_family);
1049 af->to_sk_daddr(&to, sk);
1050
1051 timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
1052 err = sctp_wait_for_connect(asoc, &timeo);
1053
1054 /* Don't free association on exit. */
1055 asoc = NULL;
1056
1057out_free:
1058
1059 SCTP_DEBUG_PRINTK("About to exit __sctp_connect() free asoc: %p"
1060 " kaddrs: %p err: %d\n",
1061 asoc, kaddrs, err);
1062 if (asoc)
1063 sctp_association_free(asoc);
1064 return err;
1065}
1066
1067/* Helper for tunneling sctp_connectx() requests through sctp_setsockopt()
1068 *
1069 * API 8.9
1070 * int sctp_connectx(int sd, struct sockaddr *addrs, int addrcnt);
1071 *
1072 * If sd is an IPv4 socket, the addresses passed must be IPv4 addresses.
1073 * If the sd is an IPv6 socket, the addresses passed can either be IPv4
1074 * or IPv6 addresses.
1075 *
1076 * A single address may be specified as INADDR_ANY or IN6ADDR_ANY, see
1077 * Section 3.1.2 for this usage.
1078 *
1079 * addrs is a pointer to an array of one or more socket addresses. Each
1080 * address is contained in its appropriate structure (i.e. struct
1081 * sockaddr_in or struct sockaddr_in6) the family of the address type
1082 * must be used to distengish the address length (note that this
1083 * representation is termed a "packed array" of addresses). The caller
1084 * specifies the number of addresses in the array with addrcnt.
1085 *
1086 * On success, sctp_connectx() returns 0. On failure, sctp_connectx() returns
1087 * -1, and sets errno to the appropriate error code.
1088 *
1089 * For SCTP, the port given in each socket address must be the same, or
1090 * sctp_connectx() will fail, setting errno to EINVAL.
1091 *
1092 * An application can use sctp_connectx to initiate an association with
1093 * an endpoint that is multi-homed. Much like sctp_bindx() this call
1094 * allows a caller to specify multiple addresses at which a peer can be
1095 * reached. The way the SCTP stack uses the list of addresses to set up
1096 * the association is implementation dependant. This function only
1097 * specifies that the stack will try to make use of all the addresses in
1098 * the list when needed.
1099 *
1100 * Note that the list of addresses passed in is only used for setting up
1101 * the association. It does not necessarily equal the set of addresses
1102 * the peer uses for the resulting association. If the caller wants to
1103 * find out the set of peer addresses, it must use sctp_getpaddrs() to
1104 * retrieve them after the association has been set up.
1105 *
1106 * Basically do nothing but copying the addresses from user to kernel
1107 * land and invoking either sctp_connectx(). This is used for tunneling
1108 * the sctp_connectx() request through sctp_setsockopt() from userspace.
1109 *
1110 * We don't use copy_from_user() for optimization: we first do the
1111 * sanity checks (buffer size -fast- and access check-healthy
1112 * pointer); if all of those succeed, then we can alloc the memory
1113 * (expensive operation) needed to copy the data to kernel. Then we do
1114 * the copying without checking the user space area
1115 * (__copy_from_user()).
1116 *
1117 * On exit there is no need to do sockfd_put(), sys_setsockopt() does
1118 * it.
1119 *
1120 * sk The sk of the socket
1121 * addrs The pointer to the addresses in user land
1122 * addrssize Size of the addrs buffer
1123 *
1124 * Returns 0 if ok, <0 errno code on error.
1125 */
1126SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
1127 struct sockaddr __user *addrs,
1128 int addrs_size)
1129{
1130 int err = 0;
1131 struct sockaddr *kaddrs;
1132
1133 SCTP_DEBUG_PRINTK("%s - sk %p addrs %p addrs_size %d\n",
1134 __FUNCTION__, sk, addrs, addrs_size);
1135
1136 if (unlikely(addrs_size <= 0))
1137 return -EINVAL;
1138
1139 /* Check the user passed a healthy pointer. */
1140 if (unlikely(!access_ok(VERIFY_READ, addrs, addrs_size)))
1141 return -EFAULT;
1142
1143 /* Alloc space for the address array in kernel memory. */
1144 kaddrs = (struct sockaddr *)kmalloc(addrs_size, GFP_KERNEL);
1145 if (unlikely(!kaddrs))
1146 return -ENOMEM;
1147
1148 if (__copy_from_user(kaddrs, addrs, addrs_size)) {
1149 err = -EFAULT;
1150 } else {
1151 err = __sctp_connect(sk, kaddrs, addrs_size);
1152 }
1153
1154 kfree(kaddrs);
1155 return err;
1156}
1157
916/* API 3.1.4 close() - UDP Style Syntax 1158/* API 3.1.4 close() - UDP Style Syntax
917 * Applications use close() to perform graceful shutdown (as described in 1159 * Applications use close() to perform graceful shutdown (as described in
918 * Section 10.1 of [SCTP]) on ALL the associations currently represented 1160 * Section 10.1 of [SCTP]) on ALL the associations currently represented
@@ -1095,7 +1337,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1095 sp = sctp_sk(sk); 1337 sp = sctp_sk(sk);
1096 ep = sp->ep; 1338 ep = sp->ep;
1097 1339
1098 SCTP_DEBUG_PRINTK("Using endpoint: %s.\n", ep->debug_name); 1340 SCTP_DEBUG_PRINTK("Using endpoint: %p.\n", ep);
1099 1341
1100 /* We cannot send a message over a TCP-style listening socket. */ 1342 /* We cannot send a message over a TCP-style listening socket. */
1101 if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) { 1343 if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) {
@@ -1306,7 +1548,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1306 } 1548 }
1307 1549
1308 /* Prime the peer's transport structures. */ 1550 /* Prime the peer's transport structures. */
1309 transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL); 1551 transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL, SCTP_UNKNOWN);
1310 if (!transport) { 1552 if (!transport) {
1311 err = -ENOMEM; 1553 err = -ENOMEM;
1312 goto out_free; 1554 goto out_free;
@@ -2208,6 +2450,12 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
2208 optlen, SCTP_BINDX_REM_ADDR); 2450 optlen, SCTP_BINDX_REM_ADDR);
2209 break; 2451 break;
2210 2452
2453 case SCTP_SOCKOPT_CONNECTX:
2454 /* 'optlen' is the size of the addresses buffer. */
2455 retval = sctp_setsockopt_connectx(sk, (struct sockaddr __user *)optval,
2456 optlen);
2457 break;
2458
2211 case SCTP_DISABLE_FRAGMENTS: 2459 case SCTP_DISABLE_FRAGMENTS:
2212 retval = sctp_setsockopt_disable_fragments(sk, optval, optlen); 2460 retval = sctp_setsockopt_disable_fragments(sk, optval, optlen);
2213 break; 2461 break;
@@ -2283,112 +2531,29 @@ out_nounlock:
2283 * 2531 *
2284 * len: the size of the address. 2532 * len: the size of the address.
2285 */ 2533 */
2286SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *uaddr, 2534SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *addr,
2287 int addr_len) 2535 int addr_len)
2288{ 2536{
2289 struct sctp_sock *sp;
2290 struct sctp_endpoint *ep;
2291 struct sctp_association *asoc;
2292 struct sctp_transport *transport;
2293 union sctp_addr to;
2294 struct sctp_af *af;
2295 sctp_scope_t scope;
2296 long timeo;
2297 int err = 0; 2537 int err = 0;
2538 struct sctp_af *af;
2298 2539
2299 sctp_lock_sock(sk); 2540 sctp_lock_sock(sk);
2300 2541
2301 SCTP_DEBUG_PRINTK("%s - sk: %p, sockaddr: %p, addr_len: %d)\n", 2542 SCTP_DEBUG_PRINTK("%s - sk: %p, sockaddr: %p, addr_len: %d\n",
2302 __FUNCTION__, sk, uaddr, addr_len); 2543 __FUNCTION__, sk, addr, addr_len);
2303
2304 sp = sctp_sk(sk);
2305 ep = sp->ep;
2306
2307 /* connect() cannot be done on a socket that is already in ESTABLISHED
2308 * state - UDP-style peeled off socket or a TCP-style socket that
2309 * is already connected.
2310 * It cannot be done even on a TCP-style listening socket.
2311 */
2312 if (sctp_sstate(sk, ESTABLISHED) ||
2313 (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))) {
2314 err = -EISCONN;
2315 goto out_unlock;
2316 }
2317
2318 err = sctp_verify_addr(sk, (union sctp_addr *)uaddr, addr_len);
2319 if (err)
2320 goto out_unlock;
2321
2322 if (addr_len > sizeof(to))
2323 addr_len = sizeof(to);
2324 memcpy(&to, uaddr, addr_len);
2325 to.v4.sin_port = ntohs(to.v4.sin_port);
2326
2327 asoc = sctp_endpoint_lookup_assoc(ep, &to, &transport);
2328 if (asoc) {
2329 if (asoc->state >= SCTP_STATE_ESTABLISHED)
2330 err = -EISCONN;
2331 else
2332 err = -EALREADY;
2333 goto out_unlock;
2334 }
2335
2336 /* If we could not find a matching association on the endpoint,
2337 * make sure that there is no peeled-off association matching the
2338 * peer address even on another socket.
2339 */
2340 if (sctp_endpoint_is_peeled_off(ep, &to)) {
2341 err = -EADDRNOTAVAIL;
2342 goto out_unlock;
2343 }
2344
2345 /* If a bind() or sctp_bindx() is not called prior to a connect()
2346 * call, the system picks an ephemeral port and will choose an address
2347 * set equivalent to binding with a wildcard address.
2348 */
2349 if (!ep->base.bind_addr.port) {
2350 if (sctp_autobind(sk)) {
2351 err = -EAGAIN;
2352 goto out_unlock;
2353 }
2354 }
2355
2356 scope = sctp_scope(&to);
2357 asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
2358 if (!asoc) {
2359 err = -ENOMEM;
2360 goto out_unlock;
2361 }
2362 2544
2363 /* Prime the peer's transport structures. */ 2545 /* Validate addr_len before calling common connect/connectx routine. */
2364 transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL); 2546 af = sctp_get_af_specific(addr->sa_family);
2365 if (!transport) { 2547 if (!af || addr_len < af->sockaddr_len) {
2366 sctp_association_free(asoc); 2548 err = -EINVAL;
2367 goto out_unlock; 2549 } else {
2368 } 2550 /* Pass correct addr len to common routine (so it knows there
2369 err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL); 2551 * is only one address being passed.
2370 if (err < 0) { 2552 */
2371 sctp_association_free(asoc); 2553 err = __sctp_connect(sk, addr, af->sockaddr_len);
2372 goto out_unlock;
2373 }
2374
2375 err = sctp_primitive_ASSOCIATE(asoc, NULL);
2376 if (err < 0) {
2377 sctp_association_free(asoc);
2378 goto out_unlock;
2379 } 2554 }
2380 2555
2381 /* Initialize sk's dport and daddr for getpeername() */
2382 inet_sk(sk)->dport = htons(asoc->peer.port);
2383 af = sctp_get_af_specific(to.sa.sa_family);
2384 af->to_sk_daddr(&to, sk);
2385
2386 timeo = sock_sndtimeo(sk, sk->sk_socket->file->f_flags & O_NONBLOCK);
2387 err = sctp_wait_for_connect(asoc, &timeo);
2388
2389out_unlock:
2390 sctp_release_sock(sk); 2556 sctp_release_sock(sk);
2391
2392 return err; 2557 return err;
2393} 2558}
2394 2559
@@ -2677,12 +2842,15 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
2677 /* Map ipv4 address into v4-mapped-on-v6 address. */ 2842 /* Map ipv4 address into v4-mapped-on-v6 address. */
2678 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), 2843 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
2679 (union sctp_addr *)&status.sstat_primary.spinfo_address); 2844 (union sctp_addr *)&status.sstat_primary.spinfo_address);
2680 status.sstat_primary.spinfo_state = transport->active; 2845 status.sstat_primary.spinfo_state = transport->state;
2681 status.sstat_primary.spinfo_cwnd = transport->cwnd; 2846 status.sstat_primary.spinfo_cwnd = transport->cwnd;
2682 status.sstat_primary.spinfo_srtt = transport->srtt; 2847 status.sstat_primary.spinfo_srtt = transport->srtt;
2683 status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto); 2848 status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto);
2684 status.sstat_primary.spinfo_mtu = transport->pmtu; 2849 status.sstat_primary.spinfo_mtu = transport->pmtu;
2685 2850
2851 if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN)
2852 status.sstat_primary.spinfo_state = SCTP_ACTIVE;
2853
2686 if (put_user(len, optlen)) { 2854 if (put_user(len, optlen)) {
2687 retval = -EFAULT; 2855 retval = -EFAULT;
2688 goto out; 2856 goto out;
@@ -2733,12 +2901,15 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len,
2733 return -EINVAL; 2901 return -EINVAL;
2734 2902
2735 pinfo.spinfo_assoc_id = sctp_assoc2id(transport->asoc); 2903 pinfo.spinfo_assoc_id = sctp_assoc2id(transport->asoc);
2736 pinfo.spinfo_state = transport->active; 2904 pinfo.spinfo_state = transport->state;
2737 pinfo.spinfo_cwnd = transport->cwnd; 2905 pinfo.spinfo_cwnd = transport->cwnd;
2738 pinfo.spinfo_srtt = transport->srtt; 2906 pinfo.spinfo_srtt = transport->srtt;
2739 pinfo.spinfo_rto = jiffies_to_msecs(transport->rto); 2907 pinfo.spinfo_rto = jiffies_to_msecs(transport->rto);
2740 pinfo.spinfo_mtu = transport->pmtu; 2908 pinfo.spinfo_mtu = transport->pmtu;
2741 2909
2910 if (pinfo.spinfo_state == SCTP_UNKNOWN)
2911 pinfo.spinfo_state = SCTP_ACTIVE;
2912
2742 if (put_user(len, optlen)) { 2913 if (put_user(len, optlen)) {
2743 retval = -EFAULT; 2914 retval = -EFAULT;
2744 goto out; 2915 goto out;
@@ -3591,7 +3762,8 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
3591 int retval = 0; 3762 int retval = 0;
3592 int len; 3763 int len;
3593 3764
3594 SCTP_DEBUG_PRINTK("sctp_getsockopt(sk: %p, ...)\n", sk); 3765 SCTP_DEBUG_PRINTK("sctp_getsockopt(sk: %p... optname: %d)\n",
3766 sk, optname);
3595 3767
3596 /* I can hardly begin to describe how wrong this is. This is 3768 /* I can hardly begin to describe how wrong this is. This is
3597 * so broken as to be worse than useless. The API draft 3769 * so broken as to be worse than useless. The API draft
@@ -4596,8 +4768,7 @@ out:
4596 return err; 4768 return err;
4597 4769
4598do_error: 4770do_error:
4599 if (asoc->counters[SCTP_COUNTER_INIT_ERROR] + 1 >= 4771 if (asoc->init_err_counter + 1 >= asoc->max_init_attempts)
4600 asoc->max_init_attempts)
4601 err = -ETIMEDOUT; 4772 err = -ETIMEDOUT;
4602 else 4773 else
4603 err = -ECONNREFUSED; 4774 err = -ECONNREFUSED;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index f30882e1e96a..0ec0fde6e6c5 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -83,7 +83,9 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
83 peer->last_time_used = jiffies; 83 peer->last_time_used = jiffies;
84 peer->last_time_ecne_reduced = jiffies; 84 peer->last_time_ecne_reduced = jiffies;
85 85
86 peer->active = SCTP_ACTIVE; 86 peer->init_sent_count = 0;
87
88 peer->state = SCTP_ACTIVE;
87 peer->hb_allowed = 0; 89 peer->hb_allowed = 0;
88 90
89 /* Initialize the default path max_retrans. */ 91 /* Initialize the default path max_retrans. */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 0a4260719a12..d65ed8684fc1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -118,7 +118,6 @@ retry:
118 xfrm_policy_put_afinfo(afinfo); 118 xfrm_policy_put_afinfo(afinfo);
119 return type; 119 return type;
120} 120}
121EXPORT_SYMBOL(xfrm_get_type);
122 121
123int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, 122int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
124 unsigned short family) 123 unsigned short family)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 2537f26f097c..9d206c282cf1 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1055,6 +1055,43 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
1055} 1055}
1056 1056
1057EXPORT_SYMBOL(xfrm_state_mtu); 1057EXPORT_SYMBOL(xfrm_state_mtu);
1058
1059int xfrm_init_state(struct xfrm_state *x)
1060{
1061 struct xfrm_state_afinfo *afinfo;
1062 int family = x->props.family;
1063 int err;
1064
1065 err = -EAFNOSUPPORT;
1066 afinfo = xfrm_state_get_afinfo(family);
1067 if (!afinfo)
1068 goto error;
1069
1070 err = 0;
1071 if (afinfo->init_flags)
1072 err = afinfo->init_flags(x);
1073
1074 xfrm_state_put_afinfo(afinfo);
1075
1076 if (err)
1077 goto error;
1078
1079 err = -EPROTONOSUPPORT;
1080 x->type = xfrm_get_type(x->id.proto, family);
1081 if (x->type == NULL)
1082 goto error;
1083
1084 err = x->type->init_state(x);
1085 if (err)
1086 goto error;
1087
1088 x->km.state = XFRM_STATE_VALID;
1089
1090error:
1091 return err;
1092}
1093
1094EXPORT_SYMBOL(xfrm_init_state);
1058 1095
1059void __init xfrm_state_init(void) 1096void __init xfrm_state_init(void)
1060{ 1097{
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 5ce8558eac91..ecade4893a13 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -249,17 +249,10 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
249 if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1]))) 249 if ((err = attach_encap_tmpl(&x->encap, xfrma[XFRMA_ENCAP-1])))
250 goto error; 250 goto error;
251 251
252 err = -ENOENT; 252 err = xfrm_init_state(x);
253 x->type = xfrm_get_type(x->id.proto, x->props.family);
254 if (x->type == NULL)
255 goto error;
256
257 err = x->type->init_state(x, NULL);
258 if (err) 253 if (err)
259 goto error; 254 goto error;
260 255
261 x->curlft.add_time = (unsigned long) xtime.tv_sec;
262 x->km.state = XFRM_STATE_VALID;
263 x->km.seq = p->seq; 256 x->km.seq = p->seq;
264 257
265 return x; 258 return x;