aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-10-13 21:23:44 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-10-13 21:23:44 -0400
commitdd4efa44ebf2a8a0e5edf60a53eadec981b4b10a (patch)
treedd6e750c3e7228abb1f922de240b86d7d12d14bf
parent1a04392bd6439876b1552793389cbb5be356ea54 (diff)
parent046d20b73960b7a2474b6d5e920d54c3fd7c23fe (diff)
Merge branch 'master'
-rw-r--r--Documentation/connector/connector.txt44
-rw-r--r--Documentation/dell_rbu.txt38
-rw-r--r--Makefile2
-rw-r--r--arch/arm/Makefile2
-rw-r--r--arch/arm/kernel/armksyms.c4
-rw-r--r--arch/arm/kernel/entry-common.S7
-rw-r--r--arch/arm/mach-s3c2410/mach-anubis.c2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c2
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2440.c4
-rw-r--r--arch/arm/mach-s3c2410/time.c1
-rw-r--r--arch/arm/mm/alignment.c44
-rw-r--r--arch/arm/nwfpe/fpa11.c5
-rw-r--r--arch/arm/nwfpe/fpa11.h20
-rw-r--r--arch/arm/nwfpe/fpa11_cprt.c3
-rw-r--r--arch/arm/nwfpe/fpopcode.h6
-rw-r--r--arch/arm/nwfpe/softfloat.h3
-rw-r--r--arch/cris/arch-v32/kernel/smp.c2
-rw-r--r--arch/m32r/kernel/entry.S9
-rw-r--r--arch/m32r/kernel/traps.c33
-rw-r--r--arch/ppc/kernel/cputable.c5
-rw-r--r--arch/ppc/kernel/dma-mapping.c4
-rw-r--r--arch/ppc64/kernel/module.c13
-rw-r--r--arch/ppc64/kernel/pSeries_pci.c4
-rw-r--r--arch/sh/kernel/smp.c3
-rw-r--r--arch/sparc/Kconfig4
-rw-r--r--arch/sparc/defconfig1
-rw-r--r--arch/sparc64/kernel/dtlb_base.S14
-rw-r--r--arch/sparc64/kernel/dtlb_prot.S12
-rw-r--r--arch/sparc64/kernel/head.S69
-rw-r--r--arch/sparc64/kernel/itlb_base.S26
-rw-r--r--arch/sparc64/kernel/ktlb.S92
-rw-r--r--arch/sparc64/mm/init.c187
-rw-r--r--arch/um/drivers/Makefile2
-rw-r--r--arch/um/drivers/ubd_kern.c556
-rw-r--r--arch/um/drivers/ubd_user.c75
-rw-r--r--arch/um/include/aio.h18
-rw-r--r--arch/um/include/os.h5
-rw-r--r--arch/um/os-Linux/aio.c205
-rw-r--r--drivers/firmware/dell_rbu.c174
-rw-r--r--drivers/media/video/bttv-cards.c4
-rw-r--r--drivers/net/e100.c224
-rw-r--r--drivers/s390/cio/device.c2
-rw-r--r--drivers/serial/imx.c39
-rw-r--r--drivers/serial/pxa.c2
-rw-r--r--drivers/serial/s3c2410.c15
-rw-r--r--drivers/serial/sunsab.c1
-rw-r--r--drivers/serial/sunzilog.c5
-rw-r--r--fs/9p/vfs_file.c114
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/nfs_common/nfsacl.c70
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h7
-rw-r--r--include/asm-arm/arch-s3c2410/hardware.h7
-rw-r--r--include/asm-powerpc/timex.h2
-rw-r--r--include/asm-ppc/cputable.h1
-rw-r--r--include/linux/cpumask.h12
-rw-r--r--include/linux/netfilter/nfnetlink.h12
-rw-r--r--include/linux/netfilter/nfnetlink_conntrack.h15
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h8
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_protocol.h3
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack_tuple.h2
-rw-r--r--include/linux/netfilter_ipv4/ip_nat.h4
-rw-r--r--include/linux/netpoll.h2
-rw-r--r--include/net/inet_timewait_sock.h3
-rw-r--r--mm/fremap.c3
-rw-r--r--mm/madvise.c11
-rw-r--r--net/bridge/br_if.c2
-rw-r--r--net/bridge/netfilter/ebtables.c27
-rw-r--r--net/dccp/ccid.h4
-rw-r--r--net/dccp/input.c6
-rw-r--r--net/ipv4/esp4.c17
-rw-r--r--net/ipv4/inet_timewait_sock.c1
-rw-r--r--net/ipv4/netfilter/Kconfig8
-rw-r--r--net/ipv4/netfilter/arp_tables.c14
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c13
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c48
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c3
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c27
-rw-r--r--net/ipv4/netfilter/ip_tables.c17
-rw-r--r--net/ipv4/tcp_output.c11
-rw-r--r--net/ipv6/esp6.c18
-rw-r--r--net/ipv6/netfilter/ip6_tables.c16
-rw-r--r--net/netfilter/nfnetlink.c4
-rw-r--r--net/sched/Kconfig4
85 files changed, 1317 insertions, 1200 deletions
diff --git a/Documentation/connector/connector.txt b/Documentation/connector/connector.txt
index 54a0a14bfbe3..57a314b14cf8 100644
--- a/Documentation/connector/connector.txt
+++ b/Documentation/connector/connector.txt
@@ -131,3 +131,47 @@ Netlink itself is not reliable protocol, that means that messages can
131be lost due to memory pressure or process' receiving queue overflowed, 131be lost due to memory pressure or process' receiving queue overflowed,
132so caller is warned must be prepared. That is why struct cn_msg [main 132so caller is warned must be prepared. That is why struct cn_msg [main
133connector's message header] contains u32 seq and u32 ack fields. 133connector's message header] contains u32 seq and u32 ack fields.
134
135/*****************************************/
136Userspace usage.
137/*****************************************/
1382.6.14 has a new netlink socket implementation, which by default does not
139allow to send data to netlink groups other than 1.
140So, if to use netlink socket (for example using connector)
141with different group number userspace application must subscribe to
142that group. It can be achieved by following pseudocode:
143
144s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
145
146l_local.nl_family = AF_NETLINK;
147l_local.nl_groups = 12345;
148l_local.nl_pid = 0;
149
150if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
151 perror("bind");
152 close(s);
153 return -1;
154}
155
156{
157 int on = l_local.nl_groups;
158 setsockopt(s, 270, 1, &on, sizeof(on));
159}
160
161Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
162option. To drop multicast subscription one should call above socket option
163with NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.
164
1652.6.14 netlink code only allows to select a group which is less or equal to
166the maximum group number, which is used at netlink_kernel_create() time.
167In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
168group number 12345, you must increment CN_NETLINK_USERS to that number.
169Additional 0xf numbers are allocated to be used by non-in-kernel users.
170
171Due to this limitation, group 0xffffffff does not work now, so one can
172not use add/remove connector's group notifications, but as far as I know,
173only cn_test.c test module used it.
174
175Some work in netlink area is still being done, so things can be changed in
1762.6.15 timeframe, if it will happen, documentation will be updated for that
177kernel.
diff --git a/Documentation/dell_rbu.txt b/Documentation/dell_rbu.txt
index 95d7f62e4dbc..941343a7a265 100644
--- a/Documentation/dell_rbu.txt
+++ b/Documentation/dell_rbu.txt
@@ -35,6 +35,7 @@ The driver load creates the following directories under the /sys file system.
35/sys/class/firmware/dell_rbu/data 35/sys/class/firmware/dell_rbu/data
36/sys/devices/platform/dell_rbu/image_type 36/sys/devices/platform/dell_rbu/image_type
37/sys/devices/platform/dell_rbu/data 37/sys/devices/platform/dell_rbu/data
38/sys/devices/platform/dell_rbu/packet_size
38 39
39The driver supports two types of update mechanism; monolithic and packetized. 40The driver supports two types of update mechanism; monolithic and packetized.
40These update mechanism depends upon the BIOS currently running on the system. 41These update mechanism depends upon the BIOS currently running on the system.
@@ -47,8 +48,26 @@ By default the driver uses monolithic memory for the update type. This can be
47changed to packets during the driver load time by specifying the load 48changed to packets during the driver load time by specifying the load
48parameter image_type=packet. This can also be changed later as below 49parameter image_type=packet. This can also be changed later as below
49echo packet > /sys/devices/platform/dell_rbu/image_type 50echo packet > /sys/devices/platform/dell_rbu/image_type
50Also echoing either mono ,packet or init in to image_type will free up the 51
51memory allocated by the driver. 52In packet update mode the packet size has to be given before any packets can
53be downloaded. It is done as below
54echo XXXX > /sys/devices/platform/dell_rbu/packet_size
55In the packet update mechanism, the user neesd to create a new file having
56packets of data arranged back to back. It can be done as follows
57The user creates packets header, gets the chunk of the BIOS image and
58placs it next to the packetheader; now, the packetheader + BIOS image chunk
59added to geather should match the specified packet_size. This makes one
60packet, the user needs to create more such packets out of the entire BIOS
61image file and then arrange all these packets back to back in to one single
62file.
63This file is then copied to /sys/class/firmware/dell_rbu/data.
64Once this file gets to the driver, the driver extracts packet_size data from
65the file and spreads it accross the physical memory in contiguous packet_sized
66space.
67This method makes sure that all the packets get to the driver in a single operation.
68
69In monolithic update the user simply get the BIOS image (.hdr file) and copies
70to the data file as is without any change to the BIOS image itself.
52 71
53Do the steps below to download the BIOS image. 72Do the steps below to download the BIOS image.
541) echo 1 > /sys/class/firmware/dell_rbu/loading 731) echo 1 > /sys/class/firmware/dell_rbu/loading
@@ -58,7 +77,10 @@ Do the steps below to download the BIOS image.
58The /sys/class/firmware/dell_rbu/ entries will remain till the following is 77The /sys/class/firmware/dell_rbu/ entries will remain till the following is
59done. 78done.
60echo -1 > /sys/class/firmware/dell_rbu/loading. 79echo -1 > /sys/class/firmware/dell_rbu/loading.
61Until this step is completed the drivr cannot be unloaded. 80Until this step is completed the driver cannot be unloaded.
81Also echoing either mono ,packet or init in to image_type will free up the
82memory allocated by the driver.
83
62If an user by accident executes steps 1 and 3 above without executing step 2; 84If an user by accident executes steps 1 and 3 above without executing step 2;
63it will make the /sys/class/firmware/dell_rbu/ entries to disappear. 85it will make the /sys/class/firmware/dell_rbu/ entries to disappear.
64The entries can be recreated by doing the following 86The entries can be recreated by doing the following
@@ -66,15 +88,11 @@ echo init > /sys/devices/platform/dell_rbu/image_type
66NOTE: echoing init in image_type does not change it original value. 88NOTE: echoing init in image_type does not change it original value.
67 89
68Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to 90Also the driver provides /sys/devices/platform/dell_rbu/data readonly file to
69read back the image downloaded. This is useful in case of packet update 91read back the image downloaded.
70mechanism where the above steps 1,2,3 will repeated for every packet.
71By reading the /sys/devices/platform/dell_rbu/data file all packet data
72downloaded can be verified in a single file.
73The packets are arranged in this file one after the other in a FIFO order.
74 92
75NOTE: 93NOTE:
76This driver requires a patch for firmware_class.c which has the addition 94This driver requires a patch for firmware_class.c which has the modified
77of request_firmware_nowait_nohotplug function to wortk 95request_firmware_nowait function.
78Also after updating the BIOS image an user mdoe application neeeds to execute 96Also after updating the BIOS image an user mdoe application neeeds to execute
79code which message the BIOS update request to the BIOS. So on the next reboot 97code which message the BIOS update request to the BIOS. So on the next reboot
80the BIOS knows about the new image downloaded and it updates it self. 98the BIOS knows about the new image downloaded and it updates it self.
diff --git a/Makefile b/Makefile
index fdb96bc85080..504ba3ceb296 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
1VERSION = 2 1VERSION = 2
2PATCHLEVEL = 6 2PATCHLEVEL = 6
3SUBLEVEL = 14 3SUBLEVEL = 14
4EXTRAVERSION =-rc3 4EXTRAVERSION =-rc4
5NAME=Affluent Albatross 5NAME=Affluent Albatross
6 6
7# *DOCUMENTATION* 7# *DOCUMENTATION*
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7779f2d1acad..299bc0468702 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -53,7 +53,7 @@ tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
53tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 53tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
54tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 54tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
55tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 55tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
56tune-$(CONFIG_CPU_V6) :=-mtune=strongarm 56tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
57 57
58# Need -Uarm for gcc < 3.x 58# Need -Uarm for gcc < 3.x
59CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) 59CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 835d450797a1..7b17a87a3311 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -45,8 +45,8 @@ extern void fp_enter(void);
45 45
46#define EXPORT_SYMBOL_ALIAS(sym,orig) \ 46#define EXPORT_SYMBOL_ALIAS(sym,orig) \
47 EXPORT_CRC_ALIAS(sym) \ 47 EXPORT_CRC_ALIAS(sym) \
48 const struct kernel_symbol __ksymtab_##sym \ 48 static const struct kernel_symbol __ksymtab_##sym \
49 __attribute__((section("__ksymtab"))) = \ 49 __attribute_used__ __attribute__((section("__ksymtab"))) = \
50 { (unsigned long)&orig, #sym }; 50 { (unsigned long)&orig, #sym };
51 51
52/* 52/*
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 81d450ac3fab..066597f4345a 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -106,15 +106,10 @@ ENTRY(ret_from_fork)
106 .endm 106 .endm
107 107
108.Larm700bug: 108.Larm700bug:
109 ldr r0, [sp, #S_PSR] @ Get calling cpsr
110 sub lr, lr, #4
111 str lr, [r8]
112 msr spsr_cxsf, r0
113 ldmia sp, {r0 - lr}^ @ Get calling r0 - lr 109 ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
114 mov r0, r0 110 mov r0, r0
115 ldr lr, [sp, #S_PC] @ Get PC
116 add sp, sp, #S_FRAME_SIZE 111 add sp, sp, #S_FRAME_SIZE
117 movs pc, lr 112 subs pc, lr, #4
118#else 113#else
119 .macro arm710_bug_check, instr, temp 114 .macro arm710_bug_check, instr, temp
120 .endm 115 .endm
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c
index 7c05f27fe1d6..5ae80f4e3e67 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2410/mach-anubis.c
@@ -125,7 +125,7 @@ static int external_map[] = { 2 };
125static int chip0_map[] = { 0 }; 125static int chip0_map[] = { 0 };
126static int chip1_map[] = { 1 }; 126static int chip1_map[] = { 1 };
127 127
128struct mtd_partition anubis_default_nand_part[] = { 128static struct mtd_partition anubis_default_nand_part[] = {
129 [0] = { 129 [0] = {
130 .name = "Boot Agent", 130 .name = "Boot Agent",
131 .size = SZ_16K, 131 .size = SZ_16K,
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index ed1f07d7252f..8ca955984645 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -230,7 +230,7 @@ static int chip0_map[] = { 1 };
230static int chip1_map[] = { 2 }; 230static int chip1_map[] = { 2 };
231static int chip2_map[] = { 3 }; 231static int chip2_map[] = { 3 };
232 232
233struct mtd_partition bast_default_nand_part[] = { 233static struct mtd_partition bast_default_nand_part[] = {
234 [0] = { 234 [0] = {
235 .name = "Boot Agent", 235 .name = "Boot Agent",
236 .size = SZ_16K, 236 .size = SZ_16K,
@@ -340,7 +340,7 @@ static struct resource bast_dm9k_resource[] = {
340 * better IO routines can be written and tested 340 * better IO routines can be written and tested
341*/ 341*/
342 342
343struct dm9000_plat_data bast_dm9k_platdata = { 343static struct dm9000_plat_data bast_dm9k_platdata = {
344 .flags = DM9000_PLATF_16BITONLY 344 .flags = DM9000_PLATF_16BITONLY
345}; 345};
346 346
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index 663a7f98fc0b..46b259673c18 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -288,7 +288,7 @@ static struct resource vr1000_dm9k1_resource[] = {
288 * better IO routines can be written and tested 288 * better IO routines can be written and tested
289*/ 289*/
290 290
291struct dm9000_plat_data vr1000_dm9k_platdata = { 291static struct dm9000_plat_data vr1000_dm9k_platdata = {
292 .flags = DM9000_PLATF_16BITONLY, 292 .flags = DM9000_PLATF_16BITONLY,
293}; 293};
294 294
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 0b88993dfd27..a8bf5ec82602 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -125,9 +125,6 @@ static struct platform_device *uart_devices[] __initdata = {
125 &s3c_uart2 125 &s3c_uart2
126}; 126};
127 127
128/* store our uart devices for the serial driver console */
129struct platform_device *s3c2410_uart_devices[3];
130
131static int s3c2410_uart_count = 0; 128static int s3c2410_uart_count = 0;
132 129
133/* uart registration process */ 130/* uart registration process */
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index d4c8281b55f6..833fa36bce05 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -151,7 +151,7 @@ void __init s3c2440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
151 151
152#ifdef CONFIG_PM 152#ifdef CONFIG_PM
153 153
154struct sleep_save s3c2440_sleep[] = { 154static struct sleep_save s3c2440_sleep[] = {
155 SAVE_ITEM(S3C2440_DSC0), 155 SAVE_ITEM(S3C2440_DSC0),
156 SAVE_ITEM(S3C2440_DSC1), 156 SAVE_ITEM(S3C2440_DSC1),
157 SAVE_ITEM(S3C2440_GPJDAT), 157 SAVE_ITEM(S3C2440_GPJDAT),
@@ -260,7 +260,7 @@ void __init s3c2440_init_clocks(int xtal)
260 * as a driver which may support both 2410 and 2440 may try and use it. 260 * as a driver which may support both 2410 and 2440 may try and use it.
261*/ 261*/
262 262
263int __init s3c2440_core_init(void) 263static int __init s3c2440_core_init(void)
264{ 264{
265 return sysdev_class_register(&s3c2440_sysclass); 265 return sysdev_class_register(&s3c2440_sysclass);
266} 266}
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
index c0acfb2ad790..8a00e3c3cd08 100644
--- a/arch/arm/mach-s3c2410/time.c
+++ b/arch/arm/mach-s3c2410/time.c
@@ -38,6 +38,7 @@
38#include <asm/hardware/clock.h> 38#include <asm/hardware/clock.h>
39 39
40#include "clock.h" 40#include "clock.h"
41#include "cpu.h"
41 42
42static unsigned long timer_startval; 43static unsigned long timer_startval;
43static unsigned long timer_usec_ticks; 44static unsigned long timer_usec_ticks;
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index f35e69e9c65c..705c98921c37 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -111,7 +111,7 @@ proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
111} 111}
112 112
113static int proc_alignment_write(struct file *file, const char __user *buffer, 113static int proc_alignment_write(struct file *file, const char __user *buffer,
114 unsigned long count, void *data) 114 unsigned long count, void *data)
115{ 115{
116 char mode; 116 char mode;
117 117
@@ -119,7 +119,7 @@ static int proc_alignment_write(struct file *file, const char __user *buffer,
119 if (get_user(mode, buffer)) 119 if (get_user(mode, buffer))
120 return -EFAULT; 120 return -EFAULT;
121 if (mode >= '0' && mode <= '5') 121 if (mode >= '0' && mode <= '5')
122 ai_usermode = mode - '0'; 122 ai_usermode = mode - '0';
123 } 123 }
124 return count; 124 return count;
125} 125}
@@ -262,7 +262,7 @@ union offset_union {
262 goto fault; \ 262 goto fault; \
263 } while (0) 263 } while (0)
264 264
265#define put32_unaligned_check(val,addr) \ 265#define put32_unaligned_check(val,addr) \
266 __put32_unaligned_check("strb", val, addr) 266 __put32_unaligned_check("strb", val, addr)
267 267
268#define put32t_unaligned_check(val,addr) \ 268#define put32t_unaligned_check(val,addr) \
@@ -306,19 +306,19 @@ do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *r
306 return TYPE_LDST; 306 return TYPE_LDST;
307 307
308 user: 308 user:
309 if (LDST_L_BIT(instr)) { 309 if (LDST_L_BIT(instr)) {
310 unsigned long val; 310 unsigned long val;
311 get16t_unaligned_check(val, addr); 311 get16t_unaligned_check(val, addr);
312 312
313 /* signed half-word? */ 313 /* signed half-word? */
314 if (instr & 0x40) 314 if (instr & 0x40)
315 val = (signed long)((signed short) val); 315 val = (signed long)((signed short) val);
316 316
317 regs->uregs[rd] = val; 317 regs->uregs[rd] = val;
318 } else 318 } else
319 put16t_unaligned_check(regs->uregs[rd], addr); 319 put16t_unaligned_check(regs->uregs[rd], addr);
320 320
321 return TYPE_LDST; 321 return TYPE_LDST;
322 322
323 fault: 323 fault:
324 return TYPE_FAULT; 324 return TYPE_FAULT;
@@ -342,11 +342,11 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
342 unsigned long val; 342 unsigned long val;
343 get32_unaligned_check(val, addr); 343 get32_unaligned_check(val, addr);
344 regs->uregs[rd] = val; 344 regs->uregs[rd] = val;
345 get32_unaligned_check(val, addr+4); 345 get32_unaligned_check(val, addr + 4);
346 regs->uregs[rd+1] = val; 346 regs->uregs[rd + 1] = val;
347 } else { 347 } else {
348 put32_unaligned_check(regs->uregs[rd], addr); 348 put32_unaligned_check(regs->uregs[rd], addr);
349 put32_unaligned_check(regs->uregs[rd+1], addr+4); 349 put32_unaligned_check(regs->uregs[rd + 1], addr + 4);
350 } 350 }
351 351
352 return TYPE_LDST; 352 return TYPE_LDST;
@@ -356,11 +356,11 @@ do_alignment_ldrdstrd(unsigned long addr, unsigned long instr,
356 unsigned long val; 356 unsigned long val;
357 get32t_unaligned_check(val, addr); 357 get32t_unaligned_check(val, addr);
358 regs->uregs[rd] = val; 358 regs->uregs[rd] = val;
359 get32t_unaligned_check(val, addr+4); 359 get32t_unaligned_check(val, addr + 4);
360 regs->uregs[rd+1] = val; 360 regs->uregs[rd + 1] = val;
361 } else { 361 } else {
362 put32t_unaligned_check(regs->uregs[rd], addr); 362 put32t_unaligned_check(regs->uregs[rd], addr);
363 put32t_unaligned_check(regs->uregs[rd+1], addr+4); 363 put32t_unaligned_check(regs->uregs[rd + 1], addr + 4);
364 } 364 }
365 365
366 return TYPE_LDST; 366 return TYPE_LDST;
@@ -443,7 +443,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
443 if (LDST_P_EQ_U(instr)) /* U = P */ 443 if (LDST_P_EQ_U(instr)) /* U = P */
444 eaddr += 4; 444 eaddr += 4;
445 445
446 /* 446 /*
447 * For alignment faults on the ARM922T/ARM920T the MMU makes 447 * For alignment faults on the ARM922T/ARM920T the MMU makes
448 * the FSR (and hence addr) equal to the updated base address 448 * the FSR (and hence addr) equal to the updated base address
449 * of the multiple access rather than the restored value. 449 * of the multiple access rather than the restored value.
@@ -570,7 +570,7 @@ thumb2arm(u16 tinstr)
570 /* 6.5.1 Format 3: */ 570 /* 6.5.1 Format 3: */
571 case 0x4800 >> 11: /* 7.1.28 LDR(3) */ 571 case 0x4800 >> 11: /* 7.1.28 LDR(3) */
572 /* NOTE: This case is not technically possible. We're 572 /* NOTE: This case is not technically possible. We're
573 * loading 32-bit memory data via PC relative 573 * loading 32-bit memory data via PC relative
574 * addressing mode. So we can and should eliminate 574 * addressing mode. So we can and should eliminate
575 * this case. But I'll leave it here for now. 575 * this case. But I'll leave it here for now.
576 */ 576 */
@@ -642,7 +642,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
642 642
643 if (fault) { 643 if (fault) {
644 type = TYPE_FAULT; 644 type = TYPE_FAULT;
645 goto bad_or_fault; 645 goto bad_or_fault;
646 } 646 }
647 647
648 if (user_mode(regs)) 648 if (user_mode(regs))
diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c
index 7690f731ee87..7b3d74d73c80 100644
--- a/arch/arm/nwfpe/fpa11.c
+++ b/arch/arm/nwfpe/fpa11.c
@@ -31,11 +31,6 @@
31#include <linux/string.h> 31#include <linux/string.h>
32#include <asm/system.h> 32#include <asm/system.h>
33 33
34/* forward declarations */
35unsigned int EmulateCPDO(const unsigned int);
36unsigned int EmulateCPDT(const unsigned int);
37unsigned int EmulateCPRT(const unsigned int);
38
39/* Reset the FPA11 chip. Called to initialize and reset the emulator. */ 34/* Reset the FPA11 chip. Called to initialize and reset the emulator. */
40static void resetFPA11(void) 35static void resetFPA11(void)
41{ 36{
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h
index 93523ae4b7a1..9677ae8448e8 100644
--- a/arch/arm/nwfpe/fpa11.h
+++ b/arch/arm/nwfpe/fpa11.h
@@ -95,4 +95,24 @@ extern int8 SetRoundingMode(const unsigned int);
95extern int8 SetRoundingPrecision(const unsigned int); 95extern int8 SetRoundingPrecision(const unsigned int);
96extern void nwfpe_init_fpa(union fp_state *fp); 96extern void nwfpe_init_fpa(union fp_state *fp);
97 97
98extern unsigned int EmulateAll(unsigned int opcode);
99
100extern unsigned int EmulateCPDT(const unsigned int opcode);
101extern unsigned int EmulateCPDO(const unsigned int opcode);
102extern unsigned int EmulateCPRT(const unsigned int opcode);
103
104/* fpa11_cpdt.c */
105extern unsigned int PerformLDF(const unsigned int opcode);
106extern unsigned int PerformSTF(const unsigned int opcode);
107extern unsigned int PerformLFM(const unsigned int opcode);
108extern unsigned int PerformSFM(const unsigned int opcode);
109
110/* single_cpdo.c */
111
112extern unsigned int SingleCPDO(struct roundingData *roundData,
113 const unsigned int opcode, FPREG * rFd);
114/* double_cpdo.c */
115extern unsigned int DoubleCPDO(struct roundingData *roundData,
116 const unsigned int opcode, FPREG * rFd);
117
98#endif 118#endif
diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c
index adf8d3000540..7c67023655e4 100644
--- a/arch/arm/nwfpe/fpa11_cprt.c
+++ b/arch/arm/nwfpe/fpa11_cprt.c
@@ -26,12 +26,11 @@
26#include "fpa11.inl" 26#include "fpa11.inl"
27#include "fpmodule.h" 27#include "fpmodule.h"
28#include "fpmodule.inl" 28#include "fpmodule.inl"
29#include "softfloat.h"
29 30
30#ifdef CONFIG_FPE_NWFPE_XP 31#ifdef CONFIG_FPE_NWFPE_XP
31extern flag floatx80_is_nan(floatx80); 32extern flag floatx80_is_nan(floatx80);
32#endif 33#endif
33extern flag float64_is_nan(float64);
34extern flag float32_is_nan(float32);
35 34
36unsigned int PerformFLT(const unsigned int opcode); 35unsigned int PerformFLT(const unsigned int opcode);
37unsigned int PerformFIX(const unsigned int opcode); 36unsigned int PerformFIX(const unsigned int opcode);
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
index 1777e92a88e6..6528e081c83f 100644
--- a/arch/arm/nwfpe/fpopcode.h
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -476,4 +476,10 @@ static inline unsigned int getDestinationSize(const unsigned int opcode)
476 return (nRc); 476 return (nRc);
477} 477}
478 478
479extern unsigned int checkCondition(const unsigned int opcode,
480 const unsigned int ccodes);
481
482extern const float64 float64Constant[];
483extern const float32 float32Constant[];
484
479#endif 485#endif
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h
index 1c8799b9ee4d..14151700b6b2 100644
--- a/arch/arm/nwfpe/softfloat.h
+++ b/arch/arm/nwfpe/softfloat.h
@@ -265,4 +265,7 @@ static inline flag float64_lt_nocheck(float64 a, float64 b)
265 return (a != b) && (aSign ^ (a < b)); 265 return (a != b) && (aSign ^ (a < b));
266} 266}
267 267
268extern flag float32_is_nan( float32 a );
269extern flag float64_is_nan( float64 a );
270
268#endif 271#endif
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 2c5cae04a95c..957f551ba5ce 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/cpumask.h> 16#include <linux/cpumask.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/module.h>
18 19
19#define IPI_SCHEDULE 1 20#define IPI_SCHEDULE 1
20#define IPI_CALL 2 21#define IPI_CALL 2
@@ -28,6 +29,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
28/* CPU masks */ 29/* CPU masks */
29cpumask_t cpu_online_map = CPU_MASK_NONE; 30cpumask_t cpu_online_map = CPU_MASK_NONE;
30cpumask_t phys_cpu_present_map = CPU_MASK_NONE; 31cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
32EXPORT_SYMBOL(phys_cpu_present_map);
31 33
32/* Variables used during SMP boot */ 34/* Variables used during SMP boot */
33volatile int cpu_now_booting = 0; 35volatile int cpu_now_booting = 0;
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index dddbf6b5ed2c..85920fb8d08c 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -681,6 +681,15 @@ ENTRY(debug_trap)
681 bl do_debug_trap 681 bl do_debug_trap
682 bra error_code 682 bra error_code
683 683
684ENTRY(ill_trap)
685 /* void ill_trap(void) */
686 SWITCH_TO_KERNEL_STACK
687 SAVE_ALL
688 ldi r1, #0 ; error_code ; FIXME
689 mv r0, sp ; pt_regs
690 bl do_ill_trap
691 bra error_code
692
684 693
685/* Cache flushing handler */ 694/* Cache flushing handler */
686ENTRY(cache_flushing_handler) 695ENTRY(cache_flushing_handler)
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 01922271d17e..5fe8ed6d62dc 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -5,8 +5,6 @@
5 * Hitoshi Yamamoto 5 * Hitoshi Yamamoto
6 */ 6 */
7 7
8/* $Id$ */
9
10/* 8/*
11 * 'traps.c' handles hardware traps and faults after we have saved some 9 * 'traps.c' handles hardware traps and faults after we have saved some
12 * state in 'entry.S'. 10 * state in 'entry.S'.
@@ -35,6 +33,7 @@ asmlinkage void ei_handler(void);
35asmlinkage void rie_handler(void); 33asmlinkage void rie_handler(void);
36asmlinkage void debug_trap(void); 34asmlinkage void debug_trap(void);
37asmlinkage void cache_flushing_handler(void); 35asmlinkage void cache_flushing_handler(void);
36asmlinkage void ill_trap(void);
38 37
39#ifdef CONFIG_SMP 38#ifdef CONFIG_SMP
40extern void smp_reschedule_interrupt(void); 39extern void smp_reschedule_interrupt(void);
@@ -77,22 +76,22 @@ void set_eit_vector_entries(void)
77 eit_vector[5] = BRA_INSN(default_eit_handler, 5); 76 eit_vector[5] = BRA_INSN(default_eit_handler, 5);
78 eit_vector[8] = BRA_INSN(rie_handler, 8); 77 eit_vector[8] = BRA_INSN(rie_handler, 8);
79 eit_vector[12] = BRA_INSN(alignment_check, 12); 78 eit_vector[12] = BRA_INSN(alignment_check, 12);
80 eit_vector[16] = 0xff000000UL; 79 eit_vector[16] = BRA_INSN(ill_trap, 16);
81 eit_vector[17] = BRA_INSN(debug_trap, 17); 80 eit_vector[17] = BRA_INSN(debug_trap, 17);
82 eit_vector[18] = BRA_INSN(system_call, 18); 81 eit_vector[18] = BRA_INSN(system_call, 18);
83 eit_vector[19] = 0xff000000UL; 82 eit_vector[19] = BRA_INSN(ill_trap, 19);
84 eit_vector[20] = 0xff000000UL; 83 eit_vector[20] = BRA_INSN(ill_trap, 20);
85 eit_vector[21] = 0xff000000UL; 84 eit_vector[21] = BRA_INSN(ill_trap, 21);
86 eit_vector[22] = 0xff000000UL; 85 eit_vector[22] = BRA_INSN(ill_trap, 22);
87 eit_vector[23] = 0xff000000UL; 86 eit_vector[23] = BRA_INSN(ill_trap, 23);
88 eit_vector[24] = 0xff000000UL; 87 eit_vector[24] = BRA_INSN(ill_trap, 24);
89 eit_vector[25] = 0xff000000UL; 88 eit_vector[25] = BRA_INSN(ill_trap, 25);
90 eit_vector[26] = 0xff000000UL; 89 eit_vector[26] = BRA_INSN(ill_trap, 26);
91 eit_vector[27] = 0xff000000UL; 90 eit_vector[27] = BRA_INSN(ill_trap, 27);
92 eit_vector[28] = BRA_INSN(cache_flushing_handler, 28); 91 eit_vector[28] = BRA_INSN(cache_flushing_handler, 28);
93 eit_vector[29] = 0xff000000UL; 92 eit_vector[29] = BRA_INSN(ill_trap, 29);
94 eit_vector[30] = 0xff000000UL; 93 eit_vector[30] = BRA_INSN(ill_trap, 30);
95 eit_vector[31] = 0xff000000UL; 94 eit_vector[31] = BRA_INSN(ill_trap, 31);
96 eit_vector[32] = BRA_INSN(ei_handler, 32); 95 eit_vector[32] = BRA_INSN(ei_handler, 32);
97 eit_vector[64] = BRA_INSN(pie_handler, 64); 96 eit_vector[64] = BRA_INSN(pie_handler, 64);
98#ifdef CONFIG_MMU 97#ifdef CONFIG_MMU
@@ -286,7 +285,8 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
286 285
287DO_ERROR( 1, SIGTRAP, "debug trap", debug_trap) 286DO_ERROR( 1, SIGTRAP, "debug trap", debug_trap)
288DO_ERROR_INFO(0x20, SIGILL, "reserved instruction ", rie_handler, ILL_ILLOPC, regs->bpc) 287DO_ERROR_INFO(0x20, SIGILL, "reserved instruction ", rie_handler, ILL_ILLOPC, regs->bpc)
289DO_ERROR_INFO(0x100, SIGILL, "privilege instruction", pie_handler, ILL_PRVOPC, regs->bpc) 288DO_ERROR_INFO(0x100, SIGILL, "privileged instruction", pie_handler, ILL_PRVOPC, regs->bpc)
289DO_ERROR_INFO(-1, SIGILL, "illegal trap", ill_trap, ILL_ILLTRP, regs->bpc)
290 290
291extern int handle_unaligned_access(unsigned long, struct pt_regs *); 291extern int handle_unaligned_access(unsigned long, struct pt_regs *);
292 292
@@ -329,4 +329,3 @@ asmlinkage void do_alignment_check(struct pt_regs *regs, long error_code)
329 set_fs(oldfs); 329 set_fs(oldfs);
330 } 330 }
331} 331}
332
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c
index 546e1ea4cafa..6b76cf58d9e0 100644
--- a/arch/ppc/kernel/cputable.c
+++ b/arch/ppc/kernel/cputable.c
@@ -91,7 +91,7 @@ struct cpu_spec cpu_specs[] = {
91 .cpu_features = CPU_FTR_COMMON | CPU_FTR_601 | 91 .cpu_features = CPU_FTR_COMMON | CPU_FTR_601 |
92 CPU_FTR_HPTE_TABLE, 92 CPU_FTR_HPTE_TABLE,
93 .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR | 93 .cpu_user_features = COMMON_PPC | PPC_FEATURE_601_INSTR |
94 PPC_FEATURE_UNIFIED_CACHE, 94 PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB,
95 .icache_bsize = 32, 95 .icache_bsize = 32,
96 .dcache_bsize = 32, 96 .dcache_bsize = 32,
97 .cpu_setup = __setup_cpu_601 97 .cpu_setup = __setup_cpu_601
@@ -745,7 +745,8 @@ struct cpu_spec cpu_specs[] = {
745 .cpu_name = "403GCX", 745 .cpu_name = "403GCX",
746 .cpu_features = CPU_FTR_SPLIT_ID_CACHE | 746 .cpu_features = CPU_FTR_SPLIT_ID_CACHE |
747 CPU_FTR_USE_TB, 747 CPU_FTR_USE_TB,
748 .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, 748 .cpu_user_features = PPC_FEATURE_32 |
749 PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB,
749 .icache_bsize = 16, 750 .icache_bsize = 16,
750 .dcache_bsize = 16, 751 .dcache_bsize = 16,
751 }, 752 },
diff --git a/arch/ppc/kernel/dma-mapping.c b/arch/ppc/kernel/dma-mapping.c
index b566d982806c..8edee806dae7 100644
--- a/arch/ppc/kernel/dma-mapping.c
+++ b/arch/ppc/kernel/dma-mapping.c
@@ -401,10 +401,10 @@ EXPORT_SYMBOL(__dma_sync);
401static inline void __dma_sync_page_highmem(struct page *page, 401static inline void __dma_sync_page_highmem(struct page *page,
402 unsigned long offset, size_t size, int direction) 402 unsigned long offset, size_t size, int direction)
403{ 403{
404 size_t seg_size = min((size_t)PAGE_SIZE, size) - offset; 404 size_t seg_size = min((size_t)(PAGE_SIZE - offset), size);
405 size_t cur_size = seg_size; 405 size_t cur_size = seg_size;
406 unsigned long flags, start, seg_offset = offset; 406 unsigned long flags, start, seg_offset = offset;
407 int nr_segs = PAGE_ALIGN(size + (PAGE_SIZE - offset))/PAGE_SIZE; 407 int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE;
408 int seg_nr = 0; 408 int seg_nr = 0;
409 409
410 local_irq_save(flags); 410 local_irq_save(flags);
diff --git a/arch/ppc64/kernel/module.c b/arch/ppc64/kernel/module.c
index c683bf88e690..928b8581fcb0 100644
--- a/arch/ppc64/kernel/module.c
+++ b/arch/ppc64/kernel/module.c
@@ -341,6 +341,19 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
341 *(unsigned long *)location = my_r2(sechdrs, me); 341 *(unsigned long *)location = my_r2(sechdrs, me);
342 break; 342 break;
343 343
344 case R_PPC64_TOC16:
345 /* Subtact TOC pointer */
346 value -= my_r2(sechdrs, me);
347 if (value + 0x8000 > 0xffff) {
348 printk("%s: bad TOC16 relocation (%lu)\n",
349 me->name, value);
350 return -ENOEXEC;
351 }
352 *((uint16_t *) location)
353 = (*((uint16_t *) location) & ~0xffff)
354 | (value & 0xffff);
355 break;
356
344 case R_PPC64_TOC16_DS: 357 case R_PPC64_TOC16_DS:
345 /* Subtact TOC pointer */ 358 /* Subtact TOC pointer */
346 value -= my_r2(sechdrs, me); 359 value -= my_r2(sechdrs, me);
diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
index 1f5f141fb7a1..928f8febdb3b 100644
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/ppc64/kernel/pSeries_pci.c
@@ -32,7 +32,7 @@
32 32
33#include "pci.h" 33#include "pci.h"
34 34
35static int __initdata s7a_workaround = -1; 35static int __devinitdata s7a_workaround = -1;
36 36
37#if 0 37#if 0
38void pcibios_name_device(struct pci_dev *dev) 38void pcibios_name_device(struct pci_dev *dev)
@@ -60,7 +60,7 @@ void pcibios_name_device(struct pci_dev *dev)
60DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); 60DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
61#endif 61#endif
62 62
63static void __init check_s7a(void) 63static void __devinit check_s7a(void)
64{ 64{
65 struct device_node *root; 65 struct device_node *root;
66 char *model; 66 char *model;
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 56a39d69e080..5ecefc02896a 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -22,6 +22,7 @@
22#include <linux/time.h> 22#include <linux/time.h>
23#include <linux/timex.h> 23#include <linux/timex.h>
24#include <linux/sched.h> 24#include <linux/sched.h>
25#include <linux/module.h>
25 26
26#include <asm/atomic.h> 27#include <asm/atomic.h>
27#include <asm/processor.h> 28#include <asm/processor.h>
@@ -39,6 +40,8 @@ struct sh_cpuinfo cpu_data[NR_CPUS];
39extern void per_cpu_trap_init(void); 40extern void per_cpu_trap_init(void);
40 41
41cpumask_t cpu_possible_map; 42cpumask_t cpu_possible_map;
43EXPORT_SYMBOL(cpu_possible_map);
44
42cpumask_t cpu_online_map; 45cpumask_t cpu_online_map;
43static atomic_t cpus_booted = ATOMIC_INIT(0); 46static atomic_t cpus_booted = ATOMIC_INIT(0);
44 47
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index f7c51b869049..6537445dac0e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -21,10 +21,6 @@ config GENERIC_ISA_DMA
21 bool 21 bool
22 default y 22 default y
23 23
24config GENERIC_IOMAP
25 bool
26 default y
27
28source "init/Kconfig" 24source "init/Kconfig"
29 25
30menu "General machine setup" 26menu "General machine setup"
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index 8a3aef1e22f5..a69856263009 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -5,7 +5,6 @@ CONFIG_MMU=y
5CONFIG_UID16=y 5CONFIG_UID16=y
6CONFIG_HIGHMEM=y 6CONFIG_HIGHMEM=y
7CONFIG_GENERIC_ISA_DMA=y 7CONFIG_GENERIC_ISA_DMA=y
8CONFIG_GENERIC_IOMAP=y
9 8
10# 9#
11# Code maturity level options 10# Code maturity level options
diff --git a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
index 702d349c1e88..6528786840c0 100644
--- a/arch/sparc64/kernel/dtlb_base.S
+++ b/arch/sparc64/kernel/dtlb_base.S
@@ -53,19 +53,18 @@
53 * be guaranteed to be 0 ... mmu_context.h does guarantee this 53 * be guaranteed to be 0 ... mmu_context.h does guarantee this
54 * by only using 10 bits in the hwcontext value. 54 * by only using 10 bits in the hwcontext value.
55 */ 55 */
56#define CREATE_VPTE_OFFSET1(r1, r2) 56#define CREATE_VPTE_OFFSET1(r1, r2) nop
57#define CREATE_VPTE_OFFSET2(r1, r2) \ 57#define CREATE_VPTE_OFFSET2(r1, r2) \
58 srax r1, 10, r2 58 srax r1, 10, r2
59#define CREATE_VPTE_NOP nop
60#else 59#else
61#define CREATE_VPTE_OFFSET1(r1, r2) \ 60#define CREATE_VPTE_OFFSET1(r1, r2) \
62 srax r1, PAGE_SHIFT, r2 61 srax r1, PAGE_SHIFT, r2
63#define CREATE_VPTE_OFFSET2(r1, r2) \ 62#define CREATE_VPTE_OFFSET2(r1, r2) \
64 sllx r2, 3, r2 63 sllx r2, 3, r2
65#define CREATE_VPTE_NOP
66#endif 64#endif
67 65
68/* DTLB ** ICACHE line 1: Quick user TLB misses */ 66/* DTLB ** ICACHE line 1: Quick user TLB misses */
67 mov TLB_SFSR, %g1
69 ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS 68 ldxa [%g1 + %g1] ASI_DMMU, %g4 ! Get TAG_ACCESS
70 andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus? 69 andcc %g4, TAG_CONTEXT_BITS, %g0 ! From Nucleus?
71from_tl1_trap: 70from_tl1_trap:
@@ -74,18 +73,16 @@ from_tl1_trap:
74 be,pn %xcc, kvmap ! Yep, special processing 73 be,pn %xcc, kvmap ! Yep, special processing
75 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset 74 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
76 cmp %g5, 4 ! Last trap level? 75 cmp %g5, 4 ! Last trap level?
77 be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
78 nop ! delay slot
79 76
80/* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */ 77/* DTLB ** ICACHE line 2: User finish + quick kernel TLB misses */
78 be,pn %xcc, longpath ! Yep, cannot risk VPTE miss
79 nop ! delay slot
81 ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE 80 ldxa [%g3 + %g6] ASI_S, %g5 ! Load VPTE
821: brgez,pn %g5, longpath ! Invalid, branch out 811: brgez,pn %g5, longpath ! Invalid, branch out
83 nop ! Delay-slot 82 nop ! Delay-slot
849: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB 839: stxa %g5, [%g0] ASI_DTLB_DATA_IN ! Reload TLB
85 retry ! Trap return 84 retry ! Trap return
86 nop 85 nop
87 nop
88 nop
89 86
90/* DTLB ** ICACHE line 3: winfixups+real_faults */ 87/* DTLB ** ICACHE line 3: winfixups+real_faults */
91longpath: 88longpath:
@@ -106,8 +103,7 @@ longpath:
106 nop 103 nop
107 nop 104 nop
108 nop 105 nop
109 CREATE_VPTE_NOP 106 nop
110 107
111#undef CREATE_VPTE_OFFSET1 108#undef CREATE_VPTE_OFFSET1
112#undef CREATE_VPTE_OFFSET2 109#undef CREATE_VPTE_OFFSET2
113#undef CREATE_VPTE_NOP
diff --git a/arch/sparc64/kernel/dtlb_prot.S b/arch/sparc64/kernel/dtlb_prot.S
index d848bb7374bb..e0a920162604 100644
--- a/arch/sparc64/kernel/dtlb_prot.S
+++ b/arch/sparc64/kernel/dtlb_prot.S
@@ -14,14 +14,14 @@
14 */ 14 */
15 15
16/* PROT ** ICACHE line 1: User DTLB protection trap */ 16/* PROT ** ICACHE line 1: User DTLB protection trap */
17 stxa %g0, [%g1] ASI_DMMU ! Clear SFSR FaultValid bit 17 mov TLB_SFSR, %g1
18 membar #Sync ! Synchronize ASI stores 18 stxa %g0, [%g1] ASI_DMMU ! Clear FaultValid bit
19 rdpr %pstate, %g5 ! Move into alternate globals 19 membar #Sync ! Synchronize stores
20 rdpr %pstate, %g5 ! Move into alt-globals
20 wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate 21 wrpr %g5, PSTATE_AG|PSTATE_MG, %pstate
21 rdpr %tl, %g1 ! Need to do a winfixup? 22 rdpr %tl, %g1 ! Need a winfixup?
22 cmp %g1, 1 ! Trap level >1? 23 cmp %g1, 1 ! Trap level >1?
23 mov TLB_TAG_ACCESS, %g4 ! Prepare reload of vaddr 24 mov TLB_TAG_ACCESS, %g4 ! For reload of vaddr
24 nop
25 25
26/* PROT ** ICACHE line 2: More real fault processing */ 26/* PROT ** ICACHE line 2: More real fault processing */
27 bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup 27 bgu,pn %xcc, winfix_trampoline ! Yes, perform winfixup
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index f1dcdf8f7433..b49dcd4504b0 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -28,19 +28,14 @@
28#include <asm/mmu.h> 28#include <asm/mmu.h>
29 29
30/* This section from from _start to sparc64_boot_end should fit into 30/* This section from from _start to sparc64_boot_end should fit into
31 * 0x0000.0000.0040.4000 to 0x0000.0000.0040.8000 and will be sharing space 31 * 0x0000000000404000 to 0x0000000000408000.
32 * with bootup_user_stack, which is from 0x0000.0000.0040.4000 to
33 * 0x0000.0000.0040.6000 and empty_bad_page, which is from
34 * 0x0000.0000.0040.6000 to 0x0000.0000.0040.8000.
35 */ 32 */
36
37 .text 33 .text
38 .globl start, _start, stext, _stext 34 .globl start, _start, stext, _stext
39_start: 35_start:
40start: 36start:
41_stext: 37_stext:
42stext: 38stext:
43bootup_user_stack:
44! 0x0000000000404000 39! 0x0000000000404000
45 b sparc64_boot 40 b sparc64_boot
46 flushw /* Flush register file. */ 41 flushw /* Flush register file. */
@@ -191,8 +186,9 @@ prom_boot_mapping_phys_low:
191 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5 186 stx %l3, [%sp + 2047 + 128 + 0x10] ! num_rets, 5
192 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate" 187 stx %l2, [%sp + 2047 + 128 + 0x18] ! arg1: "translate"
193 stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache 188 stx %l5, [%sp + 2047 + 128 + 0x20] ! arg2: prom_mmu_ihandle_cache
194 srlx %l0, 22, %l3 189 /* PAGE align */
195 sllx %l3, 22, %l3 190 srlx %l0, 13, %l3
191 sllx %l3, 13, %l3
196 stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC 192 stx %l3, [%sp + 2047 + 128 + 0x28] ! arg3: vaddr, our PC
197 stx %g0, [%sp + 2047 + 128 + 0x30] ! res1 193 stx %g0, [%sp + 2047 + 128 + 0x30] ! res1
198 stx %g0, [%sp + 2047 + 128 + 0x38] ! res2 194 stx %g0, [%sp + 2047 + 128 + 0x38] ! res2
@@ -211,6 +207,9 @@ prom_boot_mapping_phys_low:
211 ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high 207 ldx [%sp + 2047 + 128 + 0x48], %l2 ! physaddr high
212 stx %l2, [%l4 + 0x0] 208 stx %l2, [%l4 + 0x0]
213 ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low 209 ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low
210 /* 4MB align */
211 srlx %l3, 22, %l3
212 sllx %l3, 22, %l3
214 stx %l3, [%l4 + 0x8] 213 stx %l3, [%l4 + 0x8]
215 214
216 /* Leave service as-is, "call-method" */ 215 /* Leave service as-is, "call-method" */
@@ -388,31 +387,30 @@ tlb_fixup_done:
388 * former does use this code, the latter does not yet due 387 * former does use this code, the latter does not yet due
389 * to some complexities. That should be fixed up at some 388 * to some complexities. That should be fixed up at some
390 * point. 389 * point.
390 *
391 * There used to be enormous complexity wrt. transferring
392 * over from the firwmare's trap table to the Linux kernel's.
393 * For example, there was a chicken & egg problem wrt. building
394 * the OBP page tables, yet needing to be on the Linux kernel
395 * trap table (to translate PAGE_OFFSET addresses) in order to
396 * do that.
397 *
398 * We now handle OBP tlb misses differently, via linear lookups
399 * into the prom_trans[] array. So that specific problem no
400 * longer exists. Yet, unfortunately there are still some issues
401 * preventing trampoline.S from using this code... ho hum.
391 */ 402 */
392 .globl setup_trap_table 403 .globl setup_trap_table
393setup_trap_table: 404setup_trap_table:
394 save %sp, -192, %sp 405 save %sp, -192, %sp
395 406
396 /* Force interrupts to be disabled. Transferring over to 407 /* Force interrupts to be disabled. */
397 * the Linux trap table is a very delicate operation.
398 * Until we are actually on the Linux trap table, we cannot
399 * get the PAGE_OFFSET linear mappings translated. We need
400 * that mapping to be setup in order to initialize the firmware
401 * page tables.
402 *
403 * So there is this window of time, from the return from
404 * prom_set_trap_table() until inherit_prom_mappings_post()
405 * (in arch/sparc64/mm/init.c) completes, during which no
406 * firmware address space accesses can be made.
407 */
408 rdpr %pstate, %o1 408 rdpr %pstate, %o1
409 andn %o1, PSTATE_IE, %o1 409 andn %o1, PSTATE_IE, %o1
410 wrpr %o1, 0x0, %pstate 410 wrpr %o1, 0x0, %pstate
411 wrpr %g0, 15, %pil 411 wrpr %g0, 15, %pil
412 412
413 /* Ok, now make the final valid firmware call to jump over 413 /* Make the firmware call to jump over to the Linux trap table. */
414 * to the Linux trap table.
415 */
416 call prom_set_trap_table 414 call prom_set_trap_table
417 sethi %hi(sparc64_ttable_tl0), %o0 415 sethi %hi(sparc64_ttable_tl0), %o0
418 416
@@ -536,15 +534,21 @@ setup_tba: /* i0 = is_starfire */
536 534
537 ret 535 ret
538 restore 536 restore
537sparc64_boot_end:
538
539#include "systbls.S"
540#include "ktlb.S"
541#include "etrap.S"
542#include "rtrap.S"
543#include "winfixup.S"
544#include "entry.S"
539 545
540/* 546/*
541 * The following skips make sure the trap table in ttable.S is aligned 547 * The following skip makes sure the trap table in ttable.S is aligned
542 * on a 32K boundary as required by the v9 specs for TBA register. 548 * on a 32K boundary as required by the v9 specs for TBA register.
543 */ 549 */
544sparc64_boot_end: 5501:
545 .skip 0x2000 + _start - sparc64_boot_end 551 .skip 0x4000 + _start - 1b
546bootup_user_stack_end:
547 .skip 0x2000
548 552
549#ifdef CONFIG_SBUS 553#ifdef CONFIG_SBUS
550/* This is just a hack to fool make depend config.h discovering 554/* This is just a hack to fool make depend config.h discovering
@@ -556,15 +560,6 @@ bootup_user_stack_end:
556! 0x0000000000408000 560! 0x0000000000408000
557 561
558#include "ttable.S" 562#include "ttable.S"
559#include "systbls.S"
560#include "ktlb.S"
561#include "etrap.S"
562#include "rtrap.S"
563#include "winfixup.S"
564#include "entry.S"
565
566 /* This is just anal retentiveness on my part... */
567 .align 16384
568 563
569 .data 564 .data
570 .align 8 565 .align 8
diff --git a/arch/sparc64/kernel/itlb_base.S b/arch/sparc64/kernel/itlb_base.S
index b5e32dfa4fbc..4951ff8f6877 100644
--- a/arch/sparc64/kernel/itlb_base.S
+++ b/arch/sparc64/kernel/itlb_base.S
@@ -15,14 +15,12 @@
15 */ 15 */
16#define CREATE_VPTE_OFFSET1(r1, r2) \ 16#define CREATE_VPTE_OFFSET1(r1, r2) \
17 srax r1, 10, r2 17 srax r1, 10, r2
18#define CREATE_VPTE_OFFSET2(r1, r2) 18#define CREATE_VPTE_OFFSET2(r1, r2) nop
19#define CREATE_VPTE_NOP nop
20#else /* PAGE_SHIFT */ 19#else /* PAGE_SHIFT */
21#define CREATE_VPTE_OFFSET1(r1, r2) \ 20#define CREATE_VPTE_OFFSET1(r1, r2) \
22 srax r1, PAGE_SHIFT, r2 21 srax r1, PAGE_SHIFT, r2
23#define CREATE_VPTE_OFFSET2(r1, r2) \ 22#define CREATE_VPTE_OFFSET2(r1, r2) \
24 sllx r2, 3, r2 23 sllx r2, 3, r2
25#define CREATE_VPTE_NOP
26#endif /* PAGE_SHIFT */ 24#endif /* PAGE_SHIFT */
27 25
28 26
@@ -36,6 +34,7 @@
36 */ 34 */
37 35
38/* ITLB ** ICACHE line 1: Quick user TLB misses */ 36/* ITLB ** ICACHE line 1: Quick user TLB misses */
37 mov TLB_SFSR, %g1
39 ldxa [%g1 + %g1] ASI_IMMU, %g4 ! Get TAG_ACCESS 38 ldxa [%g1 + %g1] ASI_IMMU, %g4 ! Get TAG_ACCESS
40 CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset 39 CREATE_VPTE_OFFSET1(%g4, %g6) ! Create VPTE offset
41 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset 40 CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset
@@ -43,41 +42,38 @@
431: brgez,pn %g5, 3f ! Not valid, branch out 421: brgez,pn %g5, 3f ! Not valid, branch out
44 sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot 43 sethi %hi(_PAGE_EXEC), %g4 ! Delay-slot
45 andcc %g5, %g4, %g0 ! Executable? 44 andcc %g5, %g4, %g0 ! Executable?
45
46/* ITLB ** ICACHE line 2: Real faults */
46 be,pn %xcc, 3f ! Nope, branch. 47 be,pn %xcc, 3f ! Nope, branch.
47 nop ! Delay-slot 48 nop ! Delay-slot
482: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB 492: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB
49 retry ! Trap return 50 retry ! Trap return
503: rdpr %pstate, %g4 ! Move into alternate globals 513: rdpr %pstate, %g4 ! Move into alt-globals
51
52/* ITLB ** ICACHE line 2: Real faults */
53 wrpr %g4, PSTATE_AG|PSTATE_MG, %pstate 52 wrpr %g4, PSTATE_AG|PSTATE_MG, %pstate
54 rdpr %tpc, %g5 ! And load faulting VA 53 rdpr %tpc, %g5 ! And load faulting VA
55 mov FAULT_CODE_ITLB, %g4 ! It was read from ITLB 54 mov FAULT_CODE_ITLB, %g4 ! It was read from ITLB
56sparc64_realfault_common: ! Called by TL0 dtlb_miss too 55
56/* ITLB ** ICACHE line 3: Finish faults */
57sparc64_realfault_common: ! Called by dtlb_miss
57 stb %g4, [%g6 + TI_FAULT_CODE] 58 stb %g4, [%g6 + TI_FAULT_CODE]
58 stx %g5, [%g6 + TI_FAULT_ADDR] 59 stx %g5, [%g6 + TI_FAULT_ADDR]
59 ba,pt %xcc, etrap ! Save state 60 ba,pt %xcc, etrap ! Save state
601: rd %pc, %g7 ! ... 611: rd %pc, %g7 ! ...
61 nop
62
63/* ITLB ** ICACHE line 3: Finish faults + window fixups */
64 call do_sparc64_fault ! Call fault handler 62 call do_sparc64_fault ! Call fault handler
65 add %sp, PTREGS_OFF, %o0! Compute pt_regs arg 63 add %sp, PTREGS_OFF, %o0! Compute pt_regs arg
66 ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state 64 ba,pt %xcc, rtrap_clr_l6 ! Restore cpu state
67 nop 65 nop
66
67/* ITLB ** ICACHE line 4: Window fixups */
68winfix_trampoline: 68winfix_trampoline:
69 rdpr %tpc, %g3 ! Prepare winfixup TNPC 69 rdpr %tpc, %g3 ! Prepare winfixup TNPC
70 or %g3, 0x7c, %g3 ! Compute offset to branch 70 or %g3, 0x7c, %g3 ! Compute branch offset
71 wrpr %g3, %tnpc ! Write it into TNPC 71 wrpr %g3, %tnpc ! Write it into TNPC
72 done ! Do it to it 72 done ! Do it to it
73
74/* ITLB ** ICACHE line 4: Unused... */
75 nop 73 nop
76 nop 74 nop
77 nop 75 nop
78 nop 76 nop
79 CREATE_VPTE_NOP
80 77
81#undef CREATE_VPTE_OFFSET1 78#undef CREATE_VPTE_OFFSET1
82#undef CREATE_VPTE_OFFSET2 79#undef CREATE_VPTE_OFFSET2
83#undef CREATE_VPTE_NOP
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index 7796b37f478c..d9244d3c9f73 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -58,9 +58,6 @@ vpte_noent:
58 done 58 done
59 59
60vpte_insn_obp: 60vpte_insn_obp:
61 sethi %hi(prom_pmd_phys), %g5
62 ldx [%g5 + %lo(prom_pmd_phys)], %g5
63
64 /* Behave as if we are at TL0. */ 61 /* Behave as if we are at TL0. */
65 wrpr %g0, 1, %tl 62 wrpr %g0, 1, %tl
66 rdpr %tpc, %g4 /* Find original faulting iaddr */ 63 rdpr %tpc, %g4 /* Find original faulting iaddr */
@@ -71,58 +68,57 @@ vpte_insn_obp:
71 mov TLB_SFSR, %g1 68 mov TLB_SFSR, %g1
72 stxa %g4, [%g1 + %g1] ASI_IMMU 69 stxa %g4, [%g1 + %g1] ASI_IMMU
73 70
74 /* Get PMD offset. */ 71 sethi %hi(prom_trans), %g5
75 srlx %g4, 23, %g6 72 or %g5, %lo(prom_trans), %g5
76 and %g6, 0x7ff, %g6 73
77 sllx %g6, 2, %g6 741: ldx [%g5 + 0x00], %g6 ! base
78 75 brz,a,pn %g6, longpath ! no more entries, fail
79 /* Load PMD, is it valid? */ 76 mov TLB_SFSR, %g1 ! and restore %g1
80 lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 77 ldx [%g5 + 0x08], %g1 ! len
81 brz,pn %g5, longpath 78 add %g6, %g1, %g1 ! end
82 sllx %g5, 11, %g5 79 cmp %g6, %g4
83 80 bgu,pt %xcc, 2f
84 /* Get PTE offset. */ 81 cmp %g4, %g1
85 srlx %g4, 13, %g6 82 bgeu,pt %xcc, 2f
86 and %g6, 0x3ff, %g6 83 ldx [%g5 + 0x10], %g1 ! PTE
87 sllx %g6, 3, %g6 84
88 85 /* TLB load, restore %g1, and return from trap. */
89 /* Load PTE. */ 86 sub %g4, %g6, %g6
90 ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5 87 add %g1, %g6, %g5
91 brgez,pn %g5, longpath 88 mov TLB_SFSR, %g1
92 nop
93
94 /* TLB load and return from trap. */
95 stxa %g5, [%g0] ASI_ITLB_DATA_IN 89 stxa %g5, [%g0] ASI_ITLB_DATA_IN
96 retry 90 retry
97 91
98kvmap_do_obp: 922: ba,pt %xcc, 1b
99 sethi %hi(prom_pmd_phys), %g5 93 add %g5, (3 * 8), %g5 ! next entry
100 ldx [%g5 + %lo(prom_pmd_phys)], %g5
101
102 /* Get PMD offset. */
103 srlx %g4, 23, %g6
104 and %g6, 0x7ff, %g6
105 sllx %g6, 2, %g6
106
107 /* Load PMD, is it valid? */
108 lduwa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
109 brz,pn %g5, longpath
110 sllx %g5, 11, %g5
111
112 /* Get PTE offset. */
113 srlx %g4, 13, %g6
114 and %g6, 0x3ff, %g6
115 sllx %g6, 3, %g6
116
117 /* Load PTE. */
118 ldxa [%g5 + %g6] ASI_PHYS_USE_EC, %g5
119 brgez,pn %g5, longpath
120 nop
121 94
122 /* TLB load and return from trap. */ 95kvmap_do_obp:
96 sethi %hi(prom_trans), %g5
97 or %g5, %lo(prom_trans), %g5
98 srlx %g4, 13, %g4
99 sllx %g4, 13, %g4
100
1011: ldx [%g5 + 0x00], %g6 ! base
102 brz,a,pn %g6, longpath ! no more entries, fail
103 mov TLB_SFSR, %g1 ! and restore %g1
104 ldx [%g5 + 0x08], %g1 ! len
105 add %g6, %g1, %g1 ! end
106 cmp %g6, %g4
107 bgu,pt %xcc, 2f
108 cmp %g4, %g1
109 bgeu,pt %xcc, 2f
110 ldx [%g5 + 0x10], %g1 ! PTE
111
112 /* TLB load, restore %g1, and return from trap. */
113 sub %g4, %g6, %g6
114 add %g1, %g6, %g5
115 mov TLB_SFSR, %g1
123 stxa %g5, [%g0] ASI_DTLB_DATA_IN 116 stxa %g5, [%g0] ASI_DTLB_DATA_IN
124 retry 117 retry
125 118
1192: ba,pt %xcc, 1b
120 add %g5, (3 * 8), %g5 ! next entry
121
126/* 122/*
127 * On a first level data miss, check whether this is to the OBP range (note 123 * On a first level data miss, check whether this is to the OBP range (note
128 * that such accesses can be made by prom, as well as by kernel using 124 * that such accesses can be made by prom, as well as by kernel using
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 0d2e967c7200..1e44ee26cee8 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -105,7 +105,7 @@ static void __init read_obp_memory(const char *property,
105 regs[i].phys_addr = base; 105 regs[i].phys_addr = base;
106 regs[i].reg_size = size; 106 regs[i].reg_size = size;
107 } 107 }
108 sort(regs, ents, sizeof(struct linux_prom64_registers), 108 sort(regs, ents, sizeof(struct linux_prom64_registers),
109 cmp_p64, NULL); 109 cmp_p64, NULL);
110} 110}
111 111
@@ -367,8 +367,11 @@ struct linux_prom_translation {
367 unsigned long size; 367 unsigned long size;
368 unsigned long data; 368 unsigned long data;
369}; 369};
370static struct linux_prom_translation prom_trans[512] __initdata; 370
371static unsigned int prom_trans_ents __initdata; 371/* Exported for kernel TLB miss handling in ktlb.S */
372struct linux_prom_translation prom_trans[512] __read_mostly;
373unsigned int prom_trans_ents __read_mostly;
374unsigned int swapper_pgd_zero __read_mostly;
372 375
373extern unsigned long prom_boot_page; 376extern unsigned long prom_boot_page;
374extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle); 377extern void prom_remap(unsigned long physpage, unsigned long virtpage, int mmu_ihandle);
@@ -378,122 +381,57 @@ extern void register_prom_callbacks(void);
378/* Exported for SMP bootup purposes. */ 381/* Exported for SMP bootup purposes. */
379unsigned long kern_locked_tte_data; 382unsigned long kern_locked_tte_data;
380 383
381/* Exported for kernel TLB miss handling in ktlb.S */
382unsigned long prom_pmd_phys __read_mostly;
383unsigned int swapper_pgd_zero __read_mostly;
384
385static pmd_t *prompmd __read_mostly;
386
387#define BASE_PAGE_SIZE 8192
388
389/* 384/*
390 * Translate PROM's mapping we capture at boot time into physical address. 385 * Translate PROM's mapping we capture at boot time into physical address.
391 * The second parameter is only set from prom_callback() invocations. 386 * The second parameter is only set from prom_callback() invocations.
392 */ 387 */
393unsigned long prom_virt_to_phys(unsigned long promva, int *error) 388unsigned long prom_virt_to_phys(unsigned long promva, int *error)
394{ 389{
395 pmd_t *pmdp = prompmd + ((promva >> 23) & 0x7ff); 390 int i;
396 pte_t *ptep;
397 unsigned long base;
398
399 if (pmd_none(*pmdp)) {
400 if (error)
401 *error = 1;
402 return 0;
403 }
404 ptep = (pte_t *)__pmd_page(*pmdp) + ((promva >> 13) & 0x3ff);
405 if (!pte_present(*ptep)) {
406 if (error)
407 *error = 1;
408 return 0;
409 }
410 if (error) {
411 *error = 0;
412 return pte_val(*ptep);
413 }
414 base = pte_val(*ptep) & _PAGE_PADDR;
415
416 return base + (promva & (BASE_PAGE_SIZE - 1));
417}
418 391
419/* The obp translations are saved based on 8k pagesize, since obp can 392 for (i = 0; i < prom_trans_ents; i++) {
420 * use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS -> 393 struct linux_prom_translation *p = &prom_trans[i];
421 * HI_OBP_ADDRESS range are handled in entry.S and do not use the vpte
422 * scheme (also, see rant in inherit_locked_prom_mappings()).
423 */
424static void __init build_obp_range(unsigned long start, unsigned long end, unsigned long data)
425{
426 unsigned long vaddr;
427 394
428 for (vaddr = start; vaddr < end; vaddr += BASE_PAGE_SIZE) { 395 if (promva >= p->virt &&
429 unsigned long val; 396 promva < (p->virt + p->size)) {
430 pmd_t *pmd; 397 unsigned long base = p->data & _PAGE_PADDR;
431 pte_t *pte;
432 398
433 pmd = prompmd + ((vaddr >> 23) & 0x7ff); 399 if (error)
434 if (pmd_none(*pmd)) { 400 *error = 0;
435 pte = __alloc_bootmem(BASE_PAGE_SIZE, BASE_PAGE_SIZE, 401 return base + (promva & (8192 - 1));
436 PAGE_SIZE);
437 if (!pte)
438 prom_halt();
439 memset(pte, 0, BASE_PAGE_SIZE);
440 pmd_set(pmd, pte);
441 } 402 }
442 pte = (pte_t *) __pmd_page(*pmd) + ((vaddr >> 13) & 0x3ff);
443
444 val = data;
445
446 /* Clear diag TTE bits. */
447 if (tlb_type == spitfire)
448 val &= ~0x0003fe0000000000UL;
449
450 set_pte_at(&init_mm, vaddr, pte,
451 __pte(val | _PAGE_MODIFIED));
452
453 data += BASE_PAGE_SIZE;
454 } 403 }
404 if (error)
405 *error = 1;
406 return 0UL;
455} 407}
456 408
409/* The obp translations are saved based on 8k pagesize, since obp can
410 * use a mixture of pagesizes. Misses to the LOW_OBP_ADDRESS ->
411 * HI_OBP_ADDRESS range are handled in ktlb.S and do not use the vpte
412 * scheme (also, see rant in inherit_locked_prom_mappings()).
413 */
457static inline int in_obp_range(unsigned long vaddr) 414static inline int in_obp_range(unsigned long vaddr)
458{ 415{
459 return (vaddr >= LOW_OBP_ADDRESS && 416 return (vaddr >= LOW_OBP_ADDRESS &&
460 vaddr < HI_OBP_ADDRESS); 417 vaddr < HI_OBP_ADDRESS);
461} 418}
462 419
463#define OBP_PMD_SIZE 2048 420static int cmp_ptrans(const void *a, const void *b)
464static void __init build_obp_pgtable(void)
465{ 421{
466 unsigned long i; 422 const struct linux_prom_translation *x = a, *y = b;
467
468 prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, PAGE_SIZE);
469 if (!prompmd)
470 prom_halt();
471
472 memset(prompmd, 0, OBP_PMD_SIZE);
473
474 prom_pmd_phys = __pa(prompmd);
475
476 for (i = 0; i < prom_trans_ents; i++) {
477 unsigned long start, end;
478
479 if (!in_obp_range(prom_trans[i].virt))
480 continue;
481 423
482 start = prom_trans[i].virt; 424 if (x->virt > y->virt)
483 end = start + prom_trans[i].size; 425 return 1;
484 if (end > HI_OBP_ADDRESS) 426 if (x->virt < y->virt)
485 end = HI_OBP_ADDRESS; 427 return -1;
486 428 return 0;
487 build_obp_range(start, end, prom_trans[i].data);
488 }
489} 429}
490 430
491/* Read OBP translations property into 'prom_trans[]'. 431/* Read OBP translations property into 'prom_trans[]'. */
492 * Return the number of entries.
493 */
494static void __init read_obp_translations(void) 432static void __init read_obp_translations(void)
495{ 433{
496 int n, node; 434 int n, node, ents, first, last, i;
497 435
498 node = prom_finddevice("/virtual-memory"); 436 node = prom_finddevice("/virtual-memory");
499 n = prom_getproplen(node, "translations"); 437 n = prom_getproplen(node, "translations");
@@ -515,7 +453,41 @@ static void __init read_obp_translations(void)
515 453
516 n = n / sizeof(struct linux_prom_translation); 454 n = n / sizeof(struct linux_prom_translation);
517 455
518 prom_trans_ents = n; 456 ents = n;
457
458 sort(prom_trans, ents, sizeof(struct linux_prom_translation),
459 cmp_ptrans, NULL);
460
461 /* Now kick out all the non-OBP entries. */
462 for (i = 0; i < ents; i++) {
463 if (in_obp_range(prom_trans[i].virt))
464 break;
465 }
466 first = i;
467 for (; i < ents; i++) {
468 if (!in_obp_range(prom_trans[i].virt))
469 break;
470 }
471 last = i;
472
473 for (i = 0; i < (last - first); i++) {
474 struct linux_prom_translation *src = &prom_trans[i + first];
475 struct linux_prom_translation *dest = &prom_trans[i];
476
477 *dest = *src;
478 }
479 for (; i < ents; i++) {
480 struct linux_prom_translation *dest = &prom_trans[i];
481 dest->virt = dest->size = dest->data = 0x0UL;
482 }
483
484 prom_trans_ents = last - first;
485
486 if (tlb_type == spitfire) {
487 /* Clear diag TTE bits. */
488 for (i = 0; i < prom_trans_ents; i++)
489 prom_trans[i].data &= ~0x0003fe0000000000UL;
490 }
519} 491}
520 492
521static void __init remap_kernel(void) 493static void __init remap_kernel(void)
@@ -553,21 +525,18 @@ static void __init remap_kernel(void)
553} 525}
554 526
555 527
556static void __init inherit_prom_mappings_pre(void) 528static void __init inherit_prom_mappings(void)
557{ 529{
558 read_obp_translations(); 530 read_obp_translations();
559 531
560 /* Now fixup OBP's idea about where we really are mapped. */ 532 /* Now fixup OBP's idea about where we really are mapped. */
561 prom_printf("Remapping the kernel... "); 533 prom_printf("Remapping the kernel... ");
562 remap_kernel(); 534 remap_kernel();
563
564 prom_printf("done.\n"); 535 prom_printf("done.\n");
565}
566 536
567static void __init inherit_prom_mappings_post(void) 537 prom_printf("Registering callbacks... ");
568{
569 build_obp_pgtable();
570 register_prom_callbacks(); 538 register_prom_callbacks();
539 prom_printf("done.\n");
571} 540}
572 541
573/* The OBP specifications for sun4u mark 0xfffffffc00000000 and 542/* The OBP specifications for sun4u mark 0xfffffffc00000000 and
@@ -1519,7 +1488,7 @@ void __init paging_init(void)
1519 1488
1520 swapper_pgd_zero = pgd_val(swapper_pg_dir[0]); 1489 swapper_pgd_zero = pgd_val(swapper_pg_dir[0]);
1521 1490
1522 inherit_prom_mappings_pre(); 1491 inherit_prom_mappings();
1523 1492
1524 /* Ok, we can use our TLB miss and window trap handlers safely. 1493 /* Ok, we can use our TLB miss and window trap handlers safely.
1525 * We need to do a quick peek here to see if we are on StarFire 1494 * We need to do a quick peek here to see if we are on StarFire
@@ -1530,23 +1499,15 @@ void __init paging_init(void)
1530 extern void setup_tba(int); 1499 extern void setup_tba(int);
1531 setup_tba(this_is_starfire); 1500 setup_tba(this_is_starfire);
1532 } 1501 }
1533 __flush_tlb_all();
1534 1502
1535 /* Everything from this point forward, until we are done with 1503 inherit_locked_prom_mappings(1);
1536 * inherit_prom_mappings_post(), must complete successfully 1504
1537 * without calling into the firmware. The firwmare page tables 1505 __flush_tlb_all();
1538 * have not been built, but we are running on the Linux kernel's
1539 * trap table.
1540 */
1541 1506
1542 /* Setup bootmem... */ 1507 /* Setup bootmem... */
1543 pages_avail = 0; 1508 pages_avail = 0;
1544 last_valid_pfn = end_pfn = bootmem_init(&pages_avail); 1509 last_valid_pfn = end_pfn = bootmem_init(&pages_avail);
1545 1510
1546 inherit_prom_mappings_post();
1547
1548 inherit_locked_prom_mappings(1);
1549
1550#ifdef CONFIG_DEBUG_PAGEALLOC 1511#ifdef CONFIG_DEBUG_PAGEALLOC
1551 kernel_physical_mapping_init(); 1512 kernel_physical_mapping_init();
1552#endif 1513#endif
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 783e18cae090..de17d4c6e02d 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -13,7 +13,7 @@ mcast-objs := mcast_kern.o mcast_user.o
13net-objs := net_kern.o net_user.o 13net-objs := net_kern.o net_user.o
14mconsole-objs := mconsole_kern.o mconsole_user.o 14mconsole-objs := mconsole_kern.o mconsole_user.o
15hostaudio-objs := hostaudio_kern.o 15hostaudio-objs := hostaudio_kern.o
16ubd-objs := ubd_kern.o 16ubd-objs := ubd_kern.o ubd_user.o
17port-objs := port_kern.o port_user.o 17port-objs := port_kern.o port_user.o
18harddog-objs := harddog_kern.o harddog_user.o 18harddog-objs := harddog_kern.o harddog_user.o
19 19
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index e77a38da4350..f73134333f64 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -35,7 +35,6 @@
35#include "linux/blkpg.h" 35#include "linux/blkpg.h"
36#include "linux/genhd.h" 36#include "linux/genhd.h"
37#include "linux/spinlock.h" 37#include "linux/spinlock.h"
38#include "asm/atomic.h"
39#include "asm/segment.h" 38#include "asm/segment.h"
40#include "asm/uaccess.h" 39#include "asm/uaccess.h"
41#include "asm/irq.h" 40#include "asm/irq.h"
@@ -54,21 +53,20 @@
54#include "mem.h" 53#include "mem.h"
55#include "mem_kern.h" 54#include "mem_kern.h"
56#include "cow.h" 55#include "cow.h"
57#include "aio.h"
58 56
59enum ubd_req { UBD_READ, UBD_WRITE }; 57enum ubd_req { UBD_READ, UBD_WRITE };
60 58
61struct io_thread_req { 59struct io_thread_req {
62 enum aio_type op; 60 enum ubd_req op;
63 int fds[2]; 61 int fds[2];
64 unsigned long offsets[2]; 62 unsigned long offsets[2];
65 unsigned long long offset; 63 unsigned long long offset;
66 unsigned long length; 64 unsigned long length;
67 char *buffer; 65 char *buffer;
68 int sectorsize; 66 int sectorsize;
69 int bitmap_offset; 67 unsigned long sector_mask;
70 long bitmap_start; 68 unsigned long long cow_offset;
71 long bitmap_end; 69 unsigned long bitmap_words[2];
72 int error; 70 int error;
73}; 71};
74 72
@@ -82,31 +80,28 @@ extern int create_cow_file(char *cow_file, char *backing_file,
82 unsigned long *bitmap_len_out, 80 unsigned long *bitmap_len_out,
83 int *data_offset_out); 81 int *data_offset_out);
84extern int read_cow_bitmap(int fd, void *buf, int offset, int len); 82extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
85extern void do_io(struct io_thread_req *req, struct request *r, 83extern void do_io(struct io_thread_req *req);
86 unsigned long *bitmap);
87 84
88static inline int ubd_test_bit(__u64 bit, void *data) 85static inline int ubd_test_bit(__u64 bit, unsigned char *data)
89{ 86{
90 unsigned char *buffer = data;
91 __u64 n; 87 __u64 n;
92 int bits, off; 88 int bits, off;
93 89
94 bits = sizeof(buffer[0]) * 8; 90 bits = sizeof(data[0]) * 8;
95 n = bit / bits; 91 n = bit / bits;
96 off = bit % bits; 92 off = bit % bits;
97 return((buffer[n] & (1 << off)) != 0); 93 return((data[n] & (1 << off)) != 0);
98} 94}
99 95
100static inline void ubd_set_bit(__u64 bit, void *data) 96static inline void ubd_set_bit(__u64 bit, unsigned char *data)
101{ 97{
102 unsigned char *buffer = data;
103 __u64 n; 98 __u64 n;
104 int bits, off; 99 int bits, off;
105 100
106 bits = sizeof(buffer[0]) * 8; 101 bits = sizeof(data[0]) * 8;
107 n = bit / bits; 102 n = bit / bits;
108 off = bit % bits; 103 off = bit % bits;
109 buffer[n] |= (1 << off); 104 data[n] |= (1 << off);
110} 105}
111/*End stuff from ubd_user.h*/ 106/*End stuff from ubd_user.h*/
112 107
@@ -115,6 +110,8 @@ static inline void ubd_set_bit(__u64 bit, void *data)
115static DEFINE_SPINLOCK(ubd_io_lock); 110static DEFINE_SPINLOCK(ubd_io_lock);
116static DEFINE_SPINLOCK(ubd_lock); 111static DEFINE_SPINLOCK(ubd_lock);
117 112
113static void (*do_ubd)(void);
114
118static int ubd_open(struct inode * inode, struct file * filp); 115static int ubd_open(struct inode * inode, struct file * filp);
119static int ubd_release(struct inode * inode, struct file * file); 116static int ubd_release(struct inode * inode, struct file * file);
120static int ubd_ioctl(struct inode * inode, struct file * file, 117static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -161,8 +158,6 @@ struct cow {
161 int data_offset; 158 int data_offset;
162}; 159};
163 160
164#define MAX_SG 64
165
166struct ubd { 161struct ubd {
167 char *file; 162 char *file;
168 int count; 163 int count;
@@ -173,7 +168,6 @@ struct ubd {
173 int no_cow; 168 int no_cow;
174 struct cow cow; 169 struct cow cow;
175 struct platform_device pdev; 170 struct platform_device pdev;
176 struct scatterlist sg[MAX_SG];
177}; 171};
178 172
179#define DEFAULT_COW { \ 173#define DEFAULT_COW { \
@@ -466,114 +460,81 @@ __uml_help(fakehd,
466); 460);
467 461
468static void do_ubd_request(request_queue_t * q); 462static void do_ubd_request(request_queue_t * q);
469static int in_ubd; 463
464/* Only changed by ubd_init, which is an initcall. */
465int thread_fd = -1;
470 466
471/* Changed by ubd_handler, which is serialized because interrupts only 467/* Changed by ubd_handler, which is serialized because interrupts only
472 * happen on CPU 0. 468 * happen on CPU 0.
473 */ 469 */
474int intr_count = 0; 470int intr_count = 0;
475 471
476static void ubd_end_request(struct request *req, int bytes, int uptodate) 472/* call ubd_finish if you need to serialize */
473static void __ubd_finish(struct request *req, int error)
477{ 474{
478 if (!end_that_request_first(req, uptodate, bytes >> 9)) { 475 int nsect;
479 add_disk_randomness(req->rq_disk); 476
480 end_that_request_last(req); 477 if(error){
478 end_request(req, 0);
479 return;
481 } 480 }
481 nsect = req->current_nr_sectors;
482 req->sector += nsect;
483 req->buffer += nsect << 9;
484 req->errors = 0;
485 req->nr_sectors -= nsect;
486 req->current_nr_sectors = 0;
487 end_request(req, 1);
482} 488}
483 489
484/* call ubd_finish if you need to serialize */ 490static inline void ubd_finish(struct request *req, int error)
485static void __ubd_finish(struct request *req, int bytes)
486{ 491{
487 if(bytes < 0){ 492 spin_lock(&ubd_io_lock);
488 ubd_end_request(req, 0, 0); 493 __ubd_finish(req, error);
489 return; 494 spin_unlock(&ubd_io_lock);
490 }
491
492 ubd_end_request(req, bytes, 1);
493} 495}
494 496
495static inline void ubd_finish(struct request *req, int bytes) 497/* Called without ubd_io_lock held */
498static void ubd_handler(void)
496{ 499{
497 spin_lock(&ubd_io_lock); 500 struct io_thread_req req;
498 __ubd_finish(req, bytes); 501 struct request *rq = elv_next_request(ubd_queue);
499 spin_unlock(&ubd_io_lock); 502 int n;
503
504 do_ubd = NULL;
505 intr_count++;
506 n = os_read_file(thread_fd, &req, sizeof(req));
507 if(n != sizeof(req)){
508 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
509 "err = %d\n", os_getpid(), -n);
510 spin_lock(&ubd_io_lock);
511 end_request(rq, 0);
512 spin_unlock(&ubd_io_lock);
513 return;
514 }
515
516 ubd_finish(rq, req.error);
517 reactivate_fd(thread_fd, UBD_IRQ);
518 do_ubd_request(ubd_queue);
500} 519}
501 520
502struct bitmap_io {
503 atomic_t count;
504 struct aio_context aio;
505};
506
507struct ubd_aio {
508 struct aio_context aio;
509 struct request *req;
510 int len;
511 struct bitmap_io *bitmap;
512 void *bitmap_buf;
513};
514
515static int ubd_reply_fd = -1;
516
517static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused) 521static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
518{ 522{
519 struct aio_thread_reply reply; 523 ubd_handler();
520 struct ubd_aio *aio; 524 return(IRQ_HANDLED);
521 struct request *req; 525}
522 int err, n, fd = (int) (long) dev;
523
524 while(1){
525 err = os_read_file(fd, &reply, sizeof(reply));
526 if(err == -EAGAIN)
527 break;
528 if(err < 0){
529 printk("ubd_aio_handler - read returned err %d\n",
530 -err);
531 break;
532 }
533
534 aio = container_of(reply.data, struct ubd_aio, aio);
535 n = reply.err;
536
537 if(n == 0){
538 req = aio->req;
539 req->nr_sectors -= aio->len >> 9;
540
541 if((aio->bitmap != NULL) &&
542 (atomic_dec_and_test(&aio->bitmap->count))){
543 aio->aio = aio->bitmap->aio;
544 aio->len = 0;
545 kfree(aio->bitmap);
546 aio->bitmap = NULL;
547 submit_aio(&aio->aio);
548 }
549 else {
550 if((req->nr_sectors == 0) &&
551 (aio->bitmap == NULL)){
552 int len = req->hard_nr_sectors << 9;
553 ubd_finish(req, len);
554 }
555
556 if(aio->bitmap_buf != NULL)
557 kfree(aio->bitmap_buf);
558 kfree(aio);
559 }
560 }
561 else if(n < 0){
562 ubd_finish(aio->req, n);
563 if(aio->bitmap != NULL)
564 kfree(aio->bitmap);
565 if(aio->bitmap_buf != NULL)
566 kfree(aio->bitmap_buf);
567 kfree(aio);
568 }
569 }
570 reactivate_fd(fd, UBD_IRQ);
571 526
572 do_ubd_request(ubd_queue); 527/* Only changed by ubd_init, which is an initcall. */
528static int io_pid = -1;
573 529
574 return(IRQ_HANDLED); 530void kill_io_thread(void)
531{
532 if(io_pid != -1)
533 os_kill_process(io_pid, 1);
575} 534}
576 535
536__uml_exitcall(kill_io_thread);
537
577static int ubd_file_size(struct ubd *dev, __u64 *size_out) 538static int ubd_file_size(struct ubd *dev, __u64 *size_out)
578{ 539{
579 char *file; 540 char *file;
@@ -608,7 +569,7 @@ static int ubd_open_dev(struct ubd *dev)
608 &dev->cow.data_offset, create_ptr); 569 &dev->cow.data_offset, create_ptr);
609 570
610 if((dev->fd == -ENOENT) && create_cow){ 571 if((dev->fd == -ENOENT) && create_cow){
611 dev->fd = create_cow_file(dev->file, dev->cow.file, 572 dev->fd = create_cow_file(dev->file, dev->cow.file,
612 dev->openflags, 1 << 9, PAGE_SIZE, 573 dev->openflags, 1 << 9, PAGE_SIZE,
613 &dev->cow.bitmap_offset, 574 &dev->cow.bitmap_offset,
614 &dev->cow.bitmap_len, 575 &dev->cow.bitmap_len,
@@ -870,10 +831,6 @@ int ubd_init(void)
870{ 831{
871 int i; 832 int i;
872 833
873 ubd_reply_fd = init_aio_irq(UBD_IRQ, "ubd", ubd_intr);
874 if(ubd_reply_fd < 0)
875 printk("Setting up ubd AIO failed, err = %d\n", ubd_reply_fd);
876
877 devfs_mk_dir("ubd"); 834 devfs_mk_dir("ubd");
878 if (register_blkdev(MAJOR_NR, "ubd")) 835 if (register_blkdev(MAJOR_NR, "ubd"))
879 return -1; 836 return -1;
@@ -884,7 +841,6 @@ int ubd_init(void)
884 return -1; 841 return -1;
885 } 842 }
886 843
887 blk_queue_max_hw_segments(ubd_queue, MAX_SG);
888 if (fake_major != MAJOR_NR) { 844 if (fake_major != MAJOR_NR) {
889 char name[sizeof("ubd_nnn\0")]; 845 char name[sizeof("ubd_nnn\0")];
890 846
@@ -896,12 +852,40 @@ int ubd_init(void)
896 driver_register(&ubd_driver); 852 driver_register(&ubd_driver);
897 for (i = 0; i < MAX_DEV; i++) 853 for (i = 0; i < MAX_DEV; i++)
898 ubd_add(i); 854 ubd_add(i);
899
900 return 0; 855 return 0;
901} 856}
902 857
903late_initcall(ubd_init); 858late_initcall(ubd_init);
904 859
860int ubd_driver_init(void){
861 unsigned long stack;
862 int err;
863
864 /* Set by CONFIG_BLK_DEV_UBD_SYNC or ubd=sync.*/
865 if(global_openflags.s){
866 printk(KERN_INFO "ubd: Synchronous mode\n");
867 /* Letting ubd=sync be like using ubd#s= instead of ubd#= is
868 * enough. So use anyway the io thread. */
869 }
870 stack = alloc_stack(0, 0);
871 io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *),
872 &thread_fd);
873 if(io_pid < 0){
874 printk(KERN_ERR
875 "ubd : Failed to start I/O thread (errno = %d) - "
876 "falling back to synchronous I/O\n", -io_pid);
877 io_pid = -1;
878 return(0);
879 }
880 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
881 SA_INTERRUPT, "ubd", ubd_dev);
882 if(err != 0)
883 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
884 return(err);
885}
886
887device_initcall(ubd_driver_init);
888
905static int ubd_open(struct inode *inode, struct file *filp) 889static int ubd_open(struct inode *inode, struct file *filp)
906{ 890{
907 struct gendisk *disk = inode->i_bdev->bd_disk; 891 struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -939,55 +923,105 @@ static int ubd_release(struct inode * inode, struct file * file)
939 return(0); 923 return(0);
940} 924}
941 925
942static void cowify_bitmap(struct io_thread_req *req, unsigned long *bitmap) 926static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
927 __u64 *cow_offset, unsigned long *bitmap,
928 __u64 bitmap_offset, unsigned long *bitmap_words,
929 __u64 bitmap_len)
943{ 930{
944 __u64 sector = req->offset / req->sectorsize; 931 __u64 sector = io_offset >> 9;
945 int i; 932 int i, update_bitmap = 0;
933
934 for(i = 0; i < length >> 9; i++){
935 if(cow_mask != NULL)
936 ubd_set_bit(i, (unsigned char *) cow_mask);
937 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
938 continue;
946 939
947 for(i = 0; i < req->length / req->sectorsize; i++){ 940 update_bitmap = 1;
948 if(ubd_test_bit(sector + i, bitmap)) 941 ubd_set_bit(sector + i, (unsigned char *) bitmap);
949 continue; 942 }
943
944 if(!update_bitmap)
945 return;
950 946
951 if(req->bitmap_start == -1) 947 *cow_offset = sector / (sizeof(unsigned long) * 8);
952 req->bitmap_start = sector + i;
953 req->bitmap_end = sector + i + 1;
954 948
955 ubd_set_bit(sector + i, bitmap); 949 /* This takes care of the case where we're exactly at the end of the
956 } 950 * device, and *cow_offset + 1 is off the end. So, just back it up
951 * by one word. Thanks to Lynn Kerby for the fix and James McMechan
952 * for the original diagnosis.
953 */
954 if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
955 sizeof(unsigned long) - 1))
956 (*cow_offset)--;
957
958 bitmap_words[0] = bitmap[*cow_offset];
959 bitmap_words[1] = bitmap[*cow_offset + 1];
960
961 *cow_offset *= sizeof(unsigned long);
962 *cow_offset += bitmap_offset;
963}
964
965static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
966 __u64 bitmap_offset, __u64 bitmap_len)
967{
968 __u64 sector = req->offset >> 9;
969 int i;
970
971 if(req->length > (sizeof(req->sector_mask) * 8) << 9)
972 panic("Operation too long");
973
974 if(req->op == UBD_READ) {
975 for(i = 0; i < req->length >> 9; i++){
976 if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
977 ubd_set_bit(i, (unsigned char *)
978 &req->sector_mask);
979 }
980 }
981 else cowify_bitmap(req->offset, req->length, &req->sector_mask,
982 &req->cow_offset, bitmap, bitmap_offset,
983 req->bitmap_words, bitmap_len);
957} 984}
958 985
959/* Called with ubd_io_lock held */ 986/* Called with ubd_io_lock held */
960static int prepare_request(struct request *req, struct io_thread_req *io_req, 987static int prepare_request(struct request *req, struct io_thread_req *io_req)
961 unsigned long long offset, int page_offset,
962 int len, struct page *page)
963{ 988{
964 struct gendisk *disk = req->rq_disk; 989 struct gendisk *disk = req->rq_disk;
965 struct ubd *dev = disk->private_data; 990 struct ubd *dev = disk->private_data;
991 __u64 offset;
992 int len;
993
994 if(req->rq_status == RQ_INACTIVE) return(1);
966 995
967 /* This should be impossible now */ 996 /* This should be impossible now */
968 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 997 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
969 printk("Write attempted on readonly ubd device %s\n", 998 printk("Write attempted on readonly ubd device %s\n",
970 disk->disk_name); 999 disk->disk_name);
971 ubd_end_request(req, 0, 0); 1000 end_request(req, 0);
972 return(1); 1001 return(1);
973 } 1002 }
974 1003
1004 offset = ((__u64) req->sector) << 9;
1005 len = req->current_nr_sectors << 9;
1006
975 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; 1007 io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
976 io_req->fds[1] = dev->fd; 1008 io_req->fds[1] = dev->fd;
1009 io_req->cow_offset = -1;
977 io_req->offset = offset; 1010 io_req->offset = offset;
978 io_req->length = len; 1011 io_req->length = len;
979 io_req->error = 0; 1012 io_req->error = 0;
980 io_req->op = (rq_data_dir(req) == READ) ? AIO_READ : AIO_WRITE; 1013 io_req->sector_mask = 0;
1014
1015 io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
981 io_req->offsets[0] = 0; 1016 io_req->offsets[0] = 0;
982 io_req->offsets[1] = dev->cow.data_offset; 1017 io_req->offsets[1] = dev->cow.data_offset;
983 io_req->buffer = page_address(page) + page_offset; 1018 io_req->buffer = req->buffer;
984 io_req->sectorsize = 1 << 9; 1019 io_req->sectorsize = 1 << 9;
985 io_req->bitmap_offset = dev->cow.bitmap_offset;
986 io_req->bitmap_start = -1;
987 io_req->bitmap_end = -1;
988 1020
989 if((dev->cow.file != NULL) && (io_req->op == UBD_WRITE)) 1021 if(dev->cow.file != NULL)
990 cowify_bitmap(io_req, dev->cow.bitmap); 1022 cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
1023 dev->cow.bitmap_len);
1024
991 return(0); 1025 return(0);
992} 1026}
993 1027
@@ -996,36 +1030,30 @@ static void do_ubd_request(request_queue_t *q)
996{ 1030{
997 struct io_thread_req io_req; 1031 struct io_thread_req io_req;
998 struct request *req; 1032 struct request *req;
999 __u64 sector; 1033 int err, n;
1000 int err; 1034
1001 1035 if(thread_fd == -1){
1002 if(in_ubd) 1036 while((req = elv_next_request(q)) != NULL){
1003 return; 1037 err = prepare_request(req, &io_req);
1004 in_ubd = 1; 1038 if(!err){
1005 while((req = elv_next_request(q)) != NULL){ 1039 do_io(&io_req);
1006 struct gendisk *disk = req->rq_disk; 1040 __ubd_finish(req, io_req.error);
1007 struct ubd *dev = disk->private_data; 1041 }
1008 int n, i; 1042 }
1009 1043 }
1010 blkdev_dequeue_request(req); 1044 else {
1011 1045 if(do_ubd || (req = elv_next_request(q)) == NULL)
1012 sector = req->sector; 1046 return;
1013 n = blk_rq_map_sg(q, req, dev->sg); 1047 err = prepare_request(req, &io_req);
1014 1048 if(!err){
1015 for(i = 0; i < n; i++){ 1049 do_ubd = ubd_handler;
1016 struct scatterlist *sg = &dev->sg[i]; 1050 n = os_write_file(thread_fd, (char *) &io_req,
1017 1051 sizeof(io_req));
1018 err = prepare_request(req, &io_req, sector << 9, 1052 if(n != sizeof(io_req))
1019 sg->offset, sg->length, 1053 printk("write to io thread failed, "
1020 sg->page); 1054 "errno = %d\n", -n);
1021 if(err)
1022 continue;
1023
1024 sector += sg->length >> 9;
1025 do_io(&io_req, req, dev->cow.bitmap);
1026 } 1055 }
1027 } 1056 }
1028 in_ubd = 0;
1029} 1057}
1030 1058
1031static int ubd_ioctl(struct inode * inode, struct file * file, 1059static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -1241,95 +1269,131 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
1241 return(err); 1269 return(err);
1242} 1270}
1243 1271
1244void do_io(struct io_thread_req *req, struct request *r, unsigned long *bitmap) 1272static int update_bitmap(struct io_thread_req *req)
1245{ 1273{
1246 struct ubd_aio *aio; 1274 int n;
1247 struct bitmap_io *bitmap_io = NULL;
1248 char *buf;
1249 void *bitmap_buf = NULL;
1250 unsigned long len, sector;
1251 int nsectors, start, end, bit, err;
1252 __u64 off;
1253
1254 if(req->bitmap_start != -1){
1255 /* Round up to the nearest word */
1256 int round = sizeof(unsigned long);
1257 len = (req->bitmap_end - req->bitmap_start +
1258 round * 8 - 1) / (round * 8);
1259 len *= round;
1260
1261 off = req->bitmap_start / (8 * round);
1262 off *= round;
1263
1264 bitmap_io = kmalloc(sizeof(*bitmap_io), GFP_KERNEL);
1265 if(bitmap_io == NULL){
1266 printk("Failed to kmalloc bitmap IO\n");
1267 req->error = 1;
1268 return;
1269 }
1270 1275
1271 bitmap_buf = kmalloc(len, GFP_KERNEL); 1276 if(req->cow_offset == -1)
1272 if(bitmap_buf == NULL){ 1277 return(0);
1273 printk("do_io : kmalloc of bitmap chunk "
1274 "failed\n");
1275 kfree(bitmap_io);
1276 req->error = 1;
1277 return;
1278 }
1279 memcpy(bitmap_buf, &bitmap[off / sizeof(bitmap[0])], len);
1280
1281 *bitmap_io = ((struct bitmap_io)
1282 { .count = ATOMIC_INIT(0),
1283 .aio = INIT_AIO(AIO_WRITE, req->fds[1],
1284 bitmap_buf, len,
1285 req->bitmap_offset + off,
1286 ubd_reply_fd) } );
1287 }
1288 1278
1289 nsectors = req->length / req->sectorsize; 1279 n = os_seek_file(req->fds[1], req->cow_offset);
1290 start = 0; 1280 if(n < 0){
1291 end = nsectors; 1281 printk("do_io - bitmap lseek failed : err = %d\n", -n);
1292 bit = 0; 1282 return(1);
1293 do { 1283 }
1294 if(bitmap != NULL){
1295 sector = req->offset / req->sectorsize;
1296 bit = ubd_test_bit(sector + start, bitmap);
1297 end = start;
1298 while((end < nsectors) &&
1299 (ubd_test_bit(sector + end, bitmap) == bit))
1300 end++;
1301 }
1302 1284
1303 off = req->offsets[bit] + req->offset + 1285 n = os_write_file(req->fds[1], &req->bitmap_words,
1304 start * req->sectorsize; 1286 sizeof(req->bitmap_words));
1305 len = (end - start) * req->sectorsize; 1287 if(n != sizeof(req->bitmap_words)){
1306 buf = &req->buffer[start * req->sectorsize]; 1288 printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
1289 req->fds[1]);
1290 return(1);
1291 }
1307 1292
1308 aio = kmalloc(sizeof(*aio), GFP_KERNEL); 1293 return(0);
1309 if(aio == NULL){ 1294}
1310 req->error = 1;
1311 return;
1312 }
1313 1295
1314 *aio = ((struct ubd_aio) 1296void do_io(struct io_thread_req *req)
1315 { .aio = INIT_AIO(req->op, req->fds[bit], buf, 1297{
1316 len, off, ubd_reply_fd), 1298 char *buf;
1317 .len = len, 1299 unsigned long len;
1318 .req = r, 1300 int n, nsectors, start, end, bit;
1319 .bitmap = bitmap_io, 1301 int err;
1320 .bitmap_buf = bitmap_buf }); 1302 __u64 off;
1321 1303
1322 if(aio->bitmap != NULL) 1304 nsectors = req->length / req->sectorsize;
1323 atomic_inc(&aio->bitmap->count); 1305 start = 0;
1324 1306 do {
1325 err = submit_aio(&aio->aio); 1307 bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask);
1326 if(err){ 1308 end = start;
1327 printk("do_io - submit_aio failed, " 1309 while((end < nsectors) &&
1328 "err = %d\n", err); 1310 (ubd_test_bit(end, (unsigned char *)
1329 req->error = 1; 1311 &req->sector_mask) == bit))
1330 return; 1312 end++;
1331 } 1313
1314 off = req->offset + req->offsets[bit] +
1315 start * req->sectorsize;
1316 len = (end - start) * req->sectorsize;
1317 buf = &req->buffer[start * req->sectorsize];
1318
1319 err = os_seek_file(req->fds[bit], off);
1320 if(err < 0){
1321 printk("do_io - lseek failed : err = %d\n", -err);
1322 req->error = 1;
1323 return;
1324 }
1325 if(req->op == UBD_READ){
1326 n = 0;
1327 do {
1328 buf = &buf[n];
1329 len -= n;
1330 n = os_read_file(req->fds[bit], buf, len);
1331 if (n < 0) {
1332 printk("do_io - read failed, err = %d "
1333 "fd = %d\n", -n, req->fds[bit]);
1334 req->error = 1;
1335 return;
1336 }
1337 } while((n < len) && (n != 0));
1338 if (n < len) memset(&buf[n], 0, len - n);
1339 } else {
1340 n = os_write_file(req->fds[bit], buf, len);
1341 if(n != len){
1342 printk("do_io - write failed err = %d "
1343 "fd = %d\n", -n, req->fds[bit]);
1344 req->error = 1;
1345 return;
1346 }
1347 }
1348
1349 start = end;
1350 } while(start < nsectors);
1332 1351
1333 start = end; 1352 req->error = update_bitmap(req);
1334 } while(start < nsectors);
1335} 1353}
1354
1355/* Changed in start_io_thread, which is serialized by being called only
1356 * from ubd_init, which is an initcall.
1357 */
1358int kernel_fd = -1;
1359
1360/* Only changed by the io thread */
1361int io_count = 0;
1362
1363int io_thread(void *arg)
1364{
1365 struct io_thread_req req;
1366 int n;
1367
1368 ignore_sigwinch_sig();
1369 while(1){
1370 n = os_read_file(kernel_fd, &req, sizeof(req));
1371 if(n != sizeof(req)){
1372 if(n < 0)
1373 printk("io_thread - read failed, fd = %d, "
1374 "err = %d\n", kernel_fd, -n);
1375 else {
1376 printk("io_thread - short read, fd = %d, "
1377 "length = %d\n", kernel_fd, n);
1378 }
1379 continue;
1380 }
1381 io_count++;
1382 do_io(&req);
1383 n = os_write_file(kernel_fd, &req, sizeof(req));
1384 if(n != sizeof(req))
1385 printk("io_thread - write failed, fd = %d, err = %d\n",
1386 kernel_fd, -n);
1387 }
1388}
1389
1390/*
1391 * Overrides for Emacs so that we follow Linus's tabbing style.
1392 * Emacs will notice this stuff at the end of the file and automatically
1393 * adjust the settings for this buffer only. This must remain at the end
1394 * of the file.
1395 * ---------------------------------------------------------------------------
1396 * Local variables:
1397 * c-file-style: "linux"
1398 * End:
1399 */
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
new file mode 100644
index 000000000000..b94d2bc4fe06
--- /dev/null
+++ b/arch/um/drivers/ubd_user.c
@@ -0,0 +1,75 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com)
4 * Licensed under the GPL
5 */
6
7#include <stddef.h>
8#include <unistd.h>
9#include <errno.h>
10#include <sched.h>
11#include <signal.h>
12#include <string.h>
13#include <netinet/in.h>
14#include <sys/time.h>
15#include <sys/socket.h>
16#include <sys/mman.h>
17#include <sys/param.h>
18#include "asm/types.h"
19#include "user_util.h"
20#include "kern_util.h"
21#include "user.h"
22#include "ubd_user.h"
23#include "os.h"
24#include "cow.h"
25
26#include <endian.h>
27#include <byteswap.h>
28
29void ignore_sigwinch_sig(void)
30{
31 signal(SIGWINCH, SIG_IGN);
32}
33
34int start_io_thread(unsigned long sp, int *fd_out)
35{
36 int pid, fds[2], err;
37
38 err = os_pipe(fds, 1, 1);
39 if(err < 0){
40 printk("start_io_thread - os_pipe failed, err = %d\n", -err);
41 goto out;
42 }
43
44 kernel_fd = fds[0];
45 *fd_out = fds[1];
46
47 pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
48 NULL);
49 if(pid < 0){
50 printk("start_io_thread - clone failed : errno = %d\n", errno);
51 err = -errno;
52 goto out_close;
53 }
54
55 return(pid);
56
57 out_close:
58 os_close_file(fds[0]);
59 os_close_file(fds[1]);
60 kernel_fd = -1;
61 *fd_out = -1;
62 out:
63 return(err);
64}
65
66/*
67 * Overrides for Emacs so that we follow Linus's tabbing style.
68 * Emacs will notice this stuff at the end of the file and automatically
69 * adjust the settings for this buffer only. This must remain at the end
70 * of the file.
71 * ---------------------------------------------------------------------------
72 * Local variables:
73 * c-file-style: "linux"
74 * End:
75 */
diff --git a/arch/um/include/aio.h b/arch/um/include/aio.h
index 83f16877ab08..423bae9153f8 100644
--- a/arch/um/include/aio.h
+++ b/arch/um/include/aio.h
@@ -14,27 +14,15 @@ struct aio_thread_reply {
14}; 14};
15 15
16struct aio_context { 16struct aio_context {
17 enum aio_type type;
18 int fd;
19 void *data;
20 int len;
21 unsigned long long offset;
22 int reply_fd; 17 int reply_fd;
23 struct aio_context *next; 18 struct aio_context *next;
24}; 19};
25 20
26#define INIT_AIO(aio_type, aio_fd, aio_data, aio_len, aio_offset, \
27 aio_reply_fd) \
28 { .type = aio_type, \
29 .fd = aio_fd, \
30 .data = aio_data, \
31 .len = aio_len, \
32 .offset = aio_offset, \
33 .reply_fd = aio_reply_fd }
34
35#define INIT_AIO_CONTEXT { .reply_fd = -1, \ 21#define INIT_AIO_CONTEXT { .reply_fd = -1, \
36 .next = NULL } 22 .next = NULL }
37 23
38extern int submit_aio(struct aio_context *aio); 24extern int submit_aio(enum aio_type type, int fd, char *buf, int len,
25 unsigned long long offset, int reply_fd,
26 struct aio_context *aio);
39 27
40#endif 28#endif
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 6f766e1faecc..2e58e304b8be 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -6,6 +6,7 @@
6#ifndef __OS_H__ 6#ifndef __OS_H__
7#define __OS_H__ 7#define __OS_H__
8 8
9#include "uml-config.h"
9#include "asm/types.h" 10#include "asm/types.h"
10#include "../os/include/file.h" 11#include "../os/include/file.h"
11 12
@@ -159,7 +160,11 @@ extern int can_do_skas(void);
159 160
160/* Make sure they are clear when running in TT mode. Required by 161/* Make sure they are clear when running in TT mode. Required by
161 * SEGV_MAYBE_FIXABLE */ 162 * SEGV_MAYBE_FIXABLE */
163#ifdef UML_CONFIG_MODE_SKAS
162#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0) 164#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
165#else
166#define clear_can_do_skas() do {} while (0)
167#endif
163 168
164/* mem.c */ 169/* mem.c */
165extern int create_mem_file(unsigned long len); 170extern int create_mem_file(unsigned long len);
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index f6e64026f995..41cfb0944201 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -6,7 +6,6 @@
6#include <stdlib.h> 6#include <stdlib.h>
7#include <unistd.h> 7#include <unistd.h>
8#include <signal.h> 8#include <signal.h>
9#include <string.h>
10#include <errno.h> 9#include <errno.h>
11#include <sched.h> 10#include <sched.h>
12#include <sys/syscall.h> 11#include <sys/syscall.h>
@@ -17,31 +16,18 @@
17#include "user.h" 16#include "user.h"
18#include "mode.h" 17#include "mode.h"
19 18
19struct aio_thread_req {
20 enum aio_type type;
21 int io_fd;
22 unsigned long long offset;
23 char *buf;
24 int len;
25 struct aio_context *aio;
26};
27
20static int aio_req_fd_r = -1; 28static int aio_req_fd_r = -1;
21static int aio_req_fd_w = -1; 29static int aio_req_fd_w = -1;
22 30
23static int update_aio(struct aio_context *aio, int res)
24{
25 if(res < 0)
26 aio->len = res;
27 else if((res == 0) && (aio->type == AIO_READ)){
28 /* This is the EOF case - we have hit the end of the file
29 * and it ends in a partial block, so we fill the end of
30 * the block with zeros and claim success.
31 */
32 memset(aio->data, 0, aio->len);
33 aio->len = 0;
34 }
35 else if(res > 0){
36 aio->len -= res;
37 aio->data += res;
38 aio->offset += res;
39 return aio->len;
40 }
41
42 return 0;
43}
44
45#if defined(HAVE_AIO_ABI) 31#if defined(HAVE_AIO_ABI)
46#include <linux/aio_abi.h> 32#include <linux/aio_abi.h>
47 33
@@ -80,7 +66,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
80 * that it now backs the mmapped area. 66 * that it now backs the mmapped area.
81 */ 67 */
82 68
83static int do_aio(aio_context_t ctx, struct aio_context *aio) 69static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
70 int len, unsigned long long offset, struct aio_context *aio)
84{ 71{
85 struct iocb iocb, *iocbp = &iocb; 72 struct iocb iocb, *iocbp = &iocb;
86 char c; 73 char c;
@@ -88,39 +75,40 @@ static int do_aio(aio_context_t ctx, struct aio_context *aio)
88 75
89 iocb = ((struct iocb) { .aio_data = (unsigned long) aio, 76 iocb = ((struct iocb) { .aio_data = (unsigned long) aio,
90 .aio_reqprio = 0, 77 .aio_reqprio = 0,
91 .aio_fildes = aio->fd, 78 .aio_fildes = fd,
92 .aio_buf = (unsigned long) aio->data, 79 .aio_buf = (unsigned long) buf,
93 .aio_nbytes = aio->len, 80 .aio_nbytes = len,
94 .aio_offset = aio->offset, 81 .aio_offset = offset,
95 .aio_reserved1 = 0, 82 .aio_reserved1 = 0,
96 .aio_reserved2 = 0, 83 .aio_reserved2 = 0,
97 .aio_reserved3 = 0 }); 84 .aio_reserved3 = 0 });
98 85
99 switch(aio->type){ 86 switch(type){
100 case AIO_READ: 87 case AIO_READ:
101 iocb.aio_lio_opcode = IOCB_CMD_PREAD; 88 iocb.aio_lio_opcode = IOCB_CMD_PREAD;
89 err = io_submit(ctx, 1, &iocbp);
102 break; 90 break;
103 case AIO_WRITE: 91 case AIO_WRITE:
104 iocb.aio_lio_opcode = IOCB_CMD_PWRITE; 92 iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
93 err = io_submit(ctx, 1, &iocbp);
105 break; 94 break;
106 case AIO_MMAP: 95 case AIO_MMAP:
107 iocb.aio_lio_opcode = IOCB_CMD_PREAD; 96 iocb.aio_lio_opcode = IOCB_CMD_PREAD;
108 iocb.aio_buf = (unsigned long) &c; 97 iocb.aio_buf = (unsigned long) &c;
109 iocb.aio_nbytes = sizeof(c); 98 iocb.aio_nbytes = sizeof(c);
99 err = io_submit(ctx, 1, &iocbp);
110 break; 100 break;
111 default: 101 default:
112 printk("Bogus op in do_aio - %d\n", aio->type); 102 printk("Bogus op in do_aio - %d\n", type);
113 err = -EINVAL; 103 err = -EINVAL;
114 goto out; 104 break;
115 } 105 }
116 106
117 err = io_submit(ctx, 1, &iocbp);
118 if(err > 0) 107 if(err > 0)
119 err = 0; 108 err = 0;
120 else 109 else
121 err = -errno; 110 err = -errno;
122 111
123 out:
124 return err; 112 return err;
125} 113}
126 114
@@ -129,9 +117,8 @@ static aio_context_t ctx = 0;
129static int aio_thread(void *arg) 117static int aio_thread(void *arg)
130{ 118{
131 struct aio_thread_reply reply; 119 struct aio_thread_reply reply;
132 struct aio_context *aio;
133 struct io_event event; 120 struct io_event event;
134 int err, n; 121 int err, n, reply_fd;
135 122
136 signal(SIGWINCH, SIG_IGN); 123 signal(SIGWINCH, SIG_IGN);
137 124
@@ -144,22 +131,14 @@ static int aio_thread(void *arg)
144 "errno = %d\n", errno); 131 "errno = %d\n", errno);
145 } 132 }
146 else { 133 else {
147 /* This is safe as we've just a pointer here. */
148 aio = (struct aio_context *) (long) event.data;
149 if(update_aio(aio, event.res)){
150 do_aio(ctx, aio);
151 continue;
152 }
153
154 reply = ((struct aio_thread_reply) 134 reply = ((struct aio_thread_reply)
155 { .data = aio, 135 { .data = (void *) (long) event.data,
156 .err = aio->len }); 136 .err = event.res });
157 err = os_write_file(aio->reply_fd, &reply, 137 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
158 sizeof(reply)); 138 err = os_write_file(reply_fd, &reply, sizeof(reply));
159 if(err != sizeof(reply)) 139 if(err != sizeof(reply))
160 printk("aio_thread - write failed, " 140 printk("aio_thread - write failed, fd = %d, "
161 "fd = %d, err = %d\n", aio->reply_fd, 141 "err = %d\n", aio_req_fd_r, -err);
162 -err);
163 } 142 }
164 } 143 }
165 return 0; 144 return 0;
@@ -167,35 +146,35 @@ static int aio_thread(void *arg)
167 146
168#endif 147#endif
169 148
170static int do_not_aio(struct aio_context *aio) 149static int do_not_aio(struct aio_thread_req *req)
171{ 150{
172 char c; 151 char c;
173 int err; 152 int err;
174 153
175 switch(aio->type){ 154 switch(req->type){
176 case AIO_READ: 155 case AIO_READ:
177 err = os_seek_file(aio->fd, aio->offset); 156 err = os_seek_file(req->io_fd, req->offset);
178 if(err) 157 if(err)
179 goto out; 158 goto out;
180 159
181 err = os_read_file(aio->fd, aio->data, aio->len); 160 err = os_read_file(req->io_fd, req->buf, req->len);
182 break; 161 break;
183 case AIO_WRITE: 162 case AIO_WRITE:
184 err = os_seek_file(aio->fd, aio->offset); 163 err = os_seek_file(req->io_fd, req->offset);
185 if(err) 164 if(err)
186 goto out; 165 goto out;
187 166
188 err = os_write_file(aio->fd, aio->data, aio->len); 167 err = os_write_file(req->io_fd, req->buf, req->len);
189 break; 168 break;
190 case AIO_MMAP: 169 case AIO_MMAP:
191 err = os_seek_file(aio->fd, aio->offset); 170 err = os_seek_file(req->io_fd, req->offset);
192 if(err) 171 if(err)
193 goto out; 172 goto out;
194 173
195 err = os_read_file(aio->fd, &c, sizeof(c)); 174 err = os_read_file(req->io_fd, &c, sizeof(c));
196 break; 175 break;
197 default: 176 default:
198 printk("do_not_aio - bad request type : %d\n", aio->type); 177 printk("do_not_aio - bad request type : %d\n", req->type);
199 err = -EINVAL; 178 err = -EINVAL;
200 break; 179 break;
201 } 180 }
@@ -206,14 +185,14 @@ static int do_not_aio(struct aio_context *aio)
206 185
207static int not_aio_thread(void *arg) 186static int not_aio_thread(void *arg)
208{ 187{
209 struct aio_context *aio; 188 struct aio_thread_req req;
210 struct aio_thread_reply reply; 189 struct aio_thread_reply reply;
211 int err; 190 int err;
212 191
213 signal(SIGWINCH, SIG_IGN); 192 signal(SIGWINCH, SIG_IGN);
214 while(1){ 193 while(1){
215 err = os_read_file(aio_req_fd_r, &aio, sizeof(aio)); 194 err = os_read_file(aio_req_fd_r, &req, sizeof(req));
216 if(err != sizeof(aio)){ 195 if(err != sizeof(req)){
217 if(err < 0) 196 if(err < 0)
218 printk("not_aio_thread - read failed, " 197 printk("not_aio_thread - read failed, "
219 "fd = %d, err = %d\n", aio_req_fd_r, 198 "fd = %d, err = %d\n", aio_req_fd_r,
@@ -224,34 +203,17 @@ static int not_aio_thread(void *arg)
224 } 203 }
225 continue; 204 continue;
226 } 205 }
227 again: 206 err = do_not_aio(&req);
228 err = do_not_aio(aio); 207 reply = ((struct aio_thread_reply) { .data = req.aio,
229 208 .err = err });
230 if(update_aio(aio, err)) 209 err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
231 goto again;
232
233 reply = ((struct aio_thread_reply) { .data = aio,
234 .err = aio->len });
235 err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
236 if(err != sizeof(reply)) 210 if(err != sizeof(reply))
237 printk("not_aio_thread - write failed, fd = %d, " 211 printk("not_aio_thread - write failed, fd = %d, "
238 "err = %d\n", aio_req_fd_r, -err); 212 "err = %d\n", aio_req_fd_r, -err);
239 } 213 }
240} 214}
241 215
242static int submit_aio_24(struct aio_context *aio)
243{
244 int err;
245
246 err = os_write_file(aio_req_fd_w, &aio, sizeof(aio));
247 if(err == sizeof(aio))
248 err = 0;
249
250 return err;
251}
252
253static int aio_pid = -1; 216static int aio_pid = -1;
254static int (*submit_proc)(struct aio_context *aio);
255 217
256static int init_aio_24(void) 218static int init_aio_24(void)
257{ 219{
@@ -283,33 +245,11 @@ static int init_aio_24(void)
283#endif 245#endif
284 printk("2.6 host AIO support not used - falling back to I/O " 246 printk("2.6 host AIO support not used - falling back to I/O "
285 "thread\n"); 247 "thread\n");
286
287 submit_proc = submit_aio_24;
288
289 return 0; 248 return 0;
290} 249}
291 250
292#ifdef HAVE_AIO_ABI 251#ifdef HAVE_AIO_ABI
293#define DEFAULT_24_AIO 0 252#define DEFAULT_24_AIO 0
294static int submit_aio_26(struct aio_context *aio)
295{
296 struct aio_thread_reply reply;
297 int err;
298
299 err = do_aio(ctx, aio);
300 if(err){
301 reply = ((struct aio_thread_reply) { .data = aio,
302 .err = err });
303 err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
304 if(err != sizeof(reply))
305 printk("submit_aio_26 - write failed, "
306 "fd = %d, err = %d\n", aio->reply_fd, -err);
307 else err = 0;
308 }
309
310 return err;
311}
312
313static int init_aio_26(void) 253static int init_aio_26(void)
314{ 254{
315 unsigned long stack; 255 unsigned long stack;
@@ -330,22 +270,39 @@ static int init_aio_26(void)
330 aio_pid = err; 270 aio_pid = err;
331 271
332 printk("Using 2.6 host AIO\n"); 272 printk("Using 2.6 host AIO\n");
273 return 0;
274}
275
276static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
277 unsigned long long offset, struct aio_context *aio)
278{
279 struct aio_thread_reply reply;
280 int err;
333 281
334 submit_proc = submit_aio_26; 282 err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
283 if(err){
284 reply = ((struct aio_thread_reply) { .data = aio,
285 .err = err });
286 err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
287 if(err != sizeof(reply))
288 printk("submit_aio_26 - write failed, "
289 "fd = %d, err = %d\n", aio->reply_fd, -err);
290 else err = 0;
291 }
335 292
336 return 0; 293 return err;
337} 294}
338 295
339#else 296#else
340#define DEFAULT_24_AIO 1 297#define DEFAULT_24_AIO 1
341static int submit_aio_26(struct aio_context *aio) 298static int init_aio_26(void)
342{ 299{
343 return -ENOSYS; 300 return -ENOSYS;
344} 301}
345 302
346static int init_aio_26(void) 303static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
304 unsigned long long offset, struct aio_context *aio)
347{ 305{
348 submit_proc = submit_aio_26;
349 return -ENOSYS; 306 return -ENOSYS;
350} 307}
351#endif 308#endif
@@ -412,7 +369,33 @@ static void exit_aio(void)
412 369
413__uml_exitcall(exit_aio); 370__uml_exitcall(exit_aio);
414 371
415int submit_aio(struct aio_context *aio) 372static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
373 unsigned long long offset, struct aio_context *aio)
416{ 374{
417 return (*submit_proc)(aio); 375 struct aio_thread_req req = { .type = type,
376 .io_fd = io_fd,
377 .offset = offset,
378 .buf = buf,
379 .len = len,
380 .aio = aio,
381 };
382 int err;
383
384 err = os_write_file(aio_req_fd_w, &req, sizeof(req));
385 if(err == sizeof(req))
386 err = 0;
387
388 return err;
389}
390
391int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
392 unsigned long long offset, int reply_fd,
393 struct aio_context *aio)
394{
395 aio->reply_fd = reply_fd;
396 if(aio_24)
397 return submit_aio_24(type, io_fd, buf, len, offset, aio);
398 else {
399 return submit_aio_26(type, io_fd, buf, len, offset, aio);
400 }
418} 401}
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index b66782398258..4f4ba9b6d182 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -50,7 +50,7 @@
50MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>"); 50MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
51MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems"); 51MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
52MODULE_LICENSE("GPL"); 52MODULE_LICENSE("GPL");
53MODULE_VERSION("2.0"); 53MODULE_VERSION("3.0");
54 54
55#define BIOS_SCAN_LIMIT 0xffffffff 55#define BIOS_SCAN_LIMIT 0xffffffff
56#define MAX_IMAGE_LENGTH 16 56#define MAX_IMAGE_LENGTH 16
@@ -62,15 +62,16 @@ static struct _rbu_data {
62 int dma_alloc; 62 int dma_alloc;
63 spinlock_t lock; 63 spinlock_t lock;
64 unsigned long packet_read_count; 64 unsigned long packet_read_count;
65 unsigned long packet_write_count;
66 unsigned long num_packets; 65 unsigned long num_packets;
67 unsigned long packetsize; 66 unsigned long packetsize;
67 unsigned long imagesize;
68 int entry_created; 68 int entry_created;
69} rbu_data; 69} rbu_data;
70 70
71static char image_type[MAX_IMAGE_LENGTH + 1] = "mono"; 71static char image_type[MAX_IMAGE_LENGTH + 1] = "mono";
72module_param_string(image_type, image_type, sizeof (image_type), 0); 72module_param_string(image_type, image_type, sizeof (image_type), 0);
73MODULE_PARM_DESC(image_type, "BIOS image type. choose- mono or packet"); 73MODULE_PARM_DESC(image_type,
74 "BIOS image type. choose- mono or packet or init");
74 75
75struct packet_data { 76struct packet_data {
76 struct list_head list; 77 struct list_head list;
@@ -88,55 +89,13 @@ static dma_addr_t dell_rbu_dmaaddr;
88static void init_packet_head(void) 89static void init_packet_head(void)
89{ 90{
90 INIT_LIST_HEAD(&packet_data_head.list); 91 INIT_LIST_HEAD(&packet_data_head.list);
91 rbu_data.packet_write_count = 0;
92 rbu_data.packet_read_count = 0; 92 rbu_data.packet_read_count = 0;
93 rbu_data.num_packets = 0; 93 rbu_data.num_packets = 0;
94 rbu_data.packetsize = 0; 94 rbu_data.packetsize = 0;
95 rbu_data.imagesize = 0;
95} 96}
96 97
97static int fill_last_packet(void *data, size_t length) 98static int create_packet(void *data, size_t length)
98{
99 struct list_head *ptemp_list;
100 struct packet_data *packet = NULL;
101 int packet_count = 0;
102
103 pr_debug("fill_last_packet: entry \n");
104
105 if (!rbu_data.num_packets) {
106 pr_debug("fill_last_packet: num_packets=0\n");
107 return -ENOMEM;
108 }
109
110 packet_count = rbu_data.num_packets;
111
112 ptemp_list = (&packet_data_head.list)->prev;
113
114 packet = list_entry(ptemp_list, struct packet_data, list);
115
116 if ((rbu_data.packet_write_count + length) > rbu_data.packetsize) {
117 pr_debug("dell_rbu:%s: packet size data "
118 "overrun\n", __FUNCTION__);
119 return -EINVAL;
120 }
121
122 pr_debug("fill_last_packet : buffer = %p\n", packet->data);
123
124 memcpy((packet->data + rbu_data.packet_write_count), data, length);
125
126 if ((rbu_data.packet_write_count + length) == rbu_data.packetsize) {
127 /*
128 * this was the last data chunk in the packet
129 * so reinitialize the packet data counter to zero
130 */
131 rbu_data.packet_write_count = 0;
132 } else
133 rbu_data.packet_write_count += length;
134
135 pr_debug("fill_last_packet: exit \n");
136 return 0;
137}
138
139static int create_packet(size_t length)
140{ 99{
141 struct packet_data *newpacket; 100 struct packet_data *newpacket;
142 int ordernum = 0; 101 int ordernum = 0;
@@ -186,9 +145,11 @@ static int create_packet(size_t length)
186 INIT_LIST_HEAD(&newpacket->list); 145 INIT_LIST_HEAD(&newpacket->list);
187 list_add_tail(&newpacket->list, &packet_data_head.list); 146 list_add_tail(&newpacket->list, &packet_data_head.list);
188 /* 147 /*
189 * packets have fixed size 148 * packets may not have fixed size
190 */ 149 */
191 newpacket->length = rbu_data.packetsize; 150 newpacket->length = length;
151
152 memcpy(newpacket->data, data, length);
192 153
193 pr_debug("create_packet: exit \n"); 154 pr_debug("create_packet: exit \n");
194 155
@@ -198,13 +159,37 @@ static int create_packet(size_t length)
198static int packetize_data(void *data, size_t length) 159static int packetize_data(void *data, size_t length)
199{ 160{
200 int rc = 0; 161 int rc = 0;
162 int done = 0;
163 int packet_length;
164 u8 *temp;
165 u8 *end = (u8 *) data + length;
166 pr_debug("packetize_data: data length %d\n", length);
167 if (!rbu_data.packetsize) {
168 printk(KERN_WARNING
169 "dell_rbu: packetsize not specified\n");
170 return -EIO;
171 }
201 172
202 if (!rbu_data.packet_write_count) { 173 temp = (u8 *) data;
203 if ((rc = create_packet(length))) 174
175 /* packetize the hunk */
176 while (!done) {
177 if ((temp + rbu_data.packetsize) < end)
178 packet_length = rbu_data.packetsize;
179 else {
180 /* this is the last packet */
181 packet_length = end - temp;
182 done = 1;
183 }
184
185 if ((rc = create_packet(temp, packet_length)))
204 return rc; 186 return rc;
187
188 pr_debug("%lu:%lu\n", temp, (end - temp));
189 temp += packet_length;
205 } 190 }
206 if ((rc = fill_last_packet(data, length))) 191
207 return rc; 192 rbu_data.imagesize = length;
208 193
209 return rc; 194 return rc;
210} 195}
@@ -243,7 +228,7 @@ static int do_packet_read(char *data, struct list_head *ptemp_list,
243 return bytes_copied; 228 return bytes_copied;
244} 229}
245 230
246static int packet_read_list(char *data, size_t *pread_length) 231static int packet_read_list(char *data, size_t * pread_length)
247{ 232{
248 struct list_head *ptemp_list; 233 struct list_head *ptemp_list;
249 int temp_count = 0; 234 int temp_count = 0;
@@ -303,10 +288,9 @@ static void packet_empty_list(void)
303 newpacket->ordernum); 288 newpacket->ordernum);
304 kfree(newpacket); 289 kfree(newpacket);
305 } 290 }
306 rbu_data.packet_write_count = 0;
307 rbu_data.packet_read_count = 0; 291 rbu_data.packet_read_count = 0;
308 rbu_data.num_packets = 0; 292 rbu_data.num_packets = 0;
309 rbu_data.packetsize = 0; 293 rbu_data.imagesize = 0;
310} 294}
311 295
312/* 296/*
@@ -425,7 +409,6 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
425 size_t bytes_left; 409 size_t bytes_left;
426 size_t data_length; 410 size_t data_length;
427 char *ptempBuf = buffer; 411 char *ptempBuf = buffer;
428 unsigned long imagesize;
429 412
430 /* check to see if we have something to return */ 413 /* check to see if we have something to return */
431 if (rbu_data.num_packets == 0) { 414 if (rbu_data.num_packets == 0) {
@@ -434,22 +417,20 @@ static ssize_t read_packet_data(char *buffer, loff_t pos, size_t count)
434 goto read_rbu_data_exit; 417 goto read_rbu_data_exit;
435 } 418 }
436 419
437 imagesize = rbu_data.num_packets * rbu_data.packetsize; 420 if (pos > rbu_data.imagesize) {
438
439 if (pos > imagesize) {
440 retval = 0; 421 retval = 0;
441 printk(KERN_WARNING "dell_rbu:read_packet_data: " 422 printk(KERN_WARNING "dell_rbu:read_packet_data: "
442 "data underrun\n"); 423 "data underrun\n");
443 goto read_rbu_data_exit; 424 goto read_rbu_data_exit;
444 } 425 }
445 426
446 bytes_left = imagesize - pos; 427 bytes_left = rbu_data.imagesize - pos;
447 data_length = min(bytes_left, count); 428 data_length = min(bytes_left, count);
448 429
449 if ((retval = packet_read_list(ptempBuf, &data_length)) < 0) 430 if ((retval = packet_read_list(ptempBuf, &data_length)) < 0)
450 goto read_rbu_data_exit; 431 goto read_rbu_data_exit;
451 432
452 if ((pos + count) > imagesize) { 433 if ((pos + count) > rbu_data.imagesize) {
453 rbu_data.packet_read_count = 0; 434 rbu_data.packet_read_count = 0;
454 /* this was the last copy */ 435 /* this was the last copy */
455 retval = bytes_left; 436 retval = bytes_left;
@@ -499,7 +480,7 @@ static ssize_t read_rbu_mono_data(char *buffer, loff_t pos, size_t count)
499} 480}
500 481
501static ssize_t read_rbu_data(struct kobject *kobj, char *buffer, 482static ssize_t read_rbu_data(struct kobject *kobj, char *buffer,
502 loff_t pos, size_t count) 483 loff_t pos, size_t count)
503{ 484{
504 ssize_t ret_count = 0; 485 ssize_t ret_count = 0;
505 486
@@ -531,13 +512,18 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
531 memcpy(rbu_data.image_update_buffer, 512 memcpy(rbu_data.image_update_buffer,
532 fw->data, fw->size); 513 fw->data, fw->size);
533 } else if (!strcmp(image_type, "packet")) { 514 } else if (!strcmp(image_type, "packet")) {
534 if (!rbu_data.packetsize) 515 /*
535 rbu_data.packetsize = fw->size; 516 * we need to free previous packets if a
536 else if (rbu_data.packetsize != fw->size) { 517 * new hunk of packets needs to be downloaded
518 */
519 packet_empty_list();
520 if (packetize_data(fw->data, fw->size))
521 /* Incase something goes wrong when we are
522 * in middle of packetizing the data, we
523 * need to free up whatever packets might
524 * have been created before we quit.
525 */
537 packet_empty_list(); 526 packet_empty_list();
538 rbu_data.packetsize = fw->size;
539 }
540 packetize_data(fw->data, fw->size);
541 } else 527 } else
542 pr_debug("invalid image type specified.\n"); 528 pr_debug("invalid image type specified.\n");
543 spin_unlock(&rbu_data.lock); 529 spin_unlock(&rbu_data.lock);
@@ -553,7 +539,7 @@ static void callbackfn_rbu(const struct firmware *fw, void *context)
553} 539}
554 540
555static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer, 541static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
556 loff_t pos, size_t count) 542 loff_t pos, size_t count)
557{ 543{
558 int size = 0; 544 int size = 0;
559 if (!pos) 545 if (!pos)
@@ -562,7 +548,7 @@ static ssize_t read_rbu_image_type(struct kobject *kobj, char *buffer,
562} 548}
563 549
564static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer, 550static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
565 loff_t pos, size_t count) 551 loff_t pos, size_t count)
566{ 552{
567 int rc = count; 553 int rc = count;
568 int req_firm_rc = 0; 554 int req_firm_rc = 0;
@@ -621,25 +607,49 @@ static ssize_t write_rbu_image_type(struct kobject *kobj, char *buffer,
621 return rc; 607 return rc;
622} 608}
623 609
610static ssize_t read_rbu_packet_size(struct kobject *kobj, char *buffer,
611 loff_t pos, size_t count)
612{
613 int size = 0;
614 if (!pos) {
615 spin_lock(&rbu_data.lock);
616 size = sprintf(buffer, "%lu\n", rbu_data.packetsize);
617 spin_unlock(&rbu_data.lock);
618 }
619 return size;
620}
621
622static ssize_t write_rbu_packet_size(struct kobject *kobj, char *buffer,
623 loff_t pos, size_t count)
624{
625 unsigned long temp;
626 spin_lock(&rbu_data.lock);
627 packet_empty_list();
628 sscanf(buffer, "%lu", &temp);
629 if (temp < 0xffffffff)
630 rbu_data.packetsize = temp;
631
632 spin_unlock(&rbu_data.lock);
633 return count;
634}
635
624static struct bin_attribute rbu_data_attr = { 636static struct bin_attribute rbu_data_attr = {
625 .attr = { 637 .attr = {.name = "data",.owner = THIS_MODULE,.mode = 0444},
626 .name = "data",
627 .owner = THIS_MODULE,
628 .mode = 0444,
629 },
630 .read = read_rbu_data, 638 .read = read_rbu_data,
631}; 639};
632 640
633static struct bin_attribute rbu_image_type_attr = { 641static struct bin_attribute rbu_image_type_attr = {
634 .attr = { 642 .attr = {.name = "image_type",.owner = THIS_MODULE,.mode = 0644},
635 .name = "image_type",
636 .owner = THIS_MODULE,
637 .mode = 0644,
638 },
639 .read = read_rbu_image_type, 643 .read = read_rbu_image_type,
640 .write = write_rbu_image_type, 644 .write = write_rbu_image_type,
641}; 645};
642 646
647static struct bin_attribute rbu_packet_size_attr = {
648 .attr = {.name = "packet_size",.owner = THIS_MODULE,.mode = 0644},
649 .read = read_rbu_packet_size,
650 .write = write_rbu_packet_size,
651};
652
643static int __init dcdrbu_init(void) 653static int __init dcdrbu_init(void)
644{ 654{
645 int rc = 0; 655 int rc = 0;
@@ -657,6 +667,8 @@ static int __init dcdrbu_init(void)
657 667
658 sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr); 668 sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_data_attr);
659 sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr); 669 sysfs_create_bin_file(&rbu_device->dev.kobj, &rbu_image_type_attr);
670 sysfs_create_bin_file(&rbu_device->dev.kobj,
671 &rbu_packet_size_attr);
660 672
661 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, 673 rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
662 "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu); 674 "dell_rbu", &rbu_device->dev, &context, callbackfn_rbu);
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 6c332800d6ab..0881a17d5226 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -2393,10 +2393,10 @@ struct tvcard bttv_tvcards[] = {
2393 .tuner = 0, 2393 .tuner = 0,
2394 .tuner_type = TUNER_LG_TDVS_H062F, 2394 .tuner_type = TUNER_LG_TDVS_H062F,
2395 .tuner_addr = ADDR_UNSET, 2395 .tuner_addr = ADDR_UNSET,
2396 .video_inputs = 2, 2396 .video_inputs = 3,
2397 .audio_inputs = 1, 2397 .audio_inputs = 1,
2398 .svhs = 2, 2398 .svhs = 2,
2399 .muxsel = { 2, 3 }, 2399 .muxsel = { 2, 3, 1 },
2400 .gpiomask = 0x00e00007, 2400 .gpiomask = 0x00e00007,
2401 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, 2401 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
2402 .no_msp34xx = 1, 2402 .no_msp34xx = 1,
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index fbf1c06ec5c1..40887f09b681 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -903,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
903 903
904static void e100_get_defaults(struct nic *nic) 904static void e100_get_defaults(struct nic *nic)
905{ 905{
906 struct param_range rfds = { .min = 16, .max = 256, .count = 256 }; 906 struct param_range rfds = { .min = 16, .max = 256, .count = 64 };
907 struct param_range cbs = { .min = 64, .max = 256, .count = 128 }; 907 struct param_range cbs = { .min = 64, .max = 256, .count = 64 };
908 908
909 pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id); 909 pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
910 /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */ 910 /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
@@ -1007,213 +1007,25 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1007 c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); 1007 c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
1008} 1008}
1009 1009
1010/********************************************************/
1011/* Micro code for 8086:1229 Rev 8 */
1012/********************************************************/
1013
1014/* Parameter values for the D101M B-step */
1015#define D101M_CPUSAVER_TIMER_DWORD 78
1016#define D101M_CPUSAVER_BUNDLE_DWORD 65
1017#define D101M_CPUSAVER_MIN_SIZE_DWORD 126
1018
1019#define D101M_B_RCVBUNDLE_UCODE \
1020{\
10210x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \
10220x000C0001, 0x00101312, 0x000C0008, 0x00380216, \
10230x0010009C, 0x00204056, 0x002380CC, 0x00380056, \
10240x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \
10250x00380438, 0x00000000, 0x00140000, 0x00380555, \
10260x00308000, 0x00100662, 0x00100561, 0x000E0408, \
10270x00134861, 0x000C0002, 0x00103093, 0x00308000, \
10280x00100624, 0x00100561, 0x000E0408, 0x00100861, \
10290x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \
10300x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \
10310x00000000, 0x00000000, 0x00000000, 0x00000000, \
10320x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \
10330x003A0437, 0x00044010, 0x0038078A, 0x00000000, \
10340x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \
10350x00130824, 0x000C0001, 0x00101213, 0x00260C75, \
10360x00041000, 0x00010004, 0x00130826, 0x000C0006, \
10370x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \
10380x00000000, 0x00000000, 0x00000000, 0x00000000, \
10390x00000000, 0x00000000, 0x00000000, 0x00000000, \
10400x00080600, 0x00101B10, 0x00050004, 0x00100826, \
10410x00101210, 0x00380C34, 0x00000000, 0x00000000, \
10420x0021155B, 0x00100099, 0x00206559, 0x0010009C, \
10430x00244559, 0x00130836, 0x000C0000, 0x00220C62, \
10440x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \
10450x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \
10460x00214C0E, 0x00380555, 0x00010004, 0x00041000, \
10470x00278C67, 0x00040800, 0x00018100, 0x003A0437, \
10480x00130826, 0x000C0001, 0x00220559, 0x00101313, \
10490x00380559, 0x00000000, 0x00000000, 0x00000000, \
10500x00000000, 0x00000000, 0x00000000, 0x00000000, \
10510x00000000, 0x00130831, 0x0010090B, 0x00124813, \
10520x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \
10530x003806A8, 0x00000000, 0x00000000, 0x00000000, \
1054}
1055
1056/********************************************************/
1057/* Micro code for 8086:1229 Rev 9 */
1058/********************************************************/
1059
1060/* Parameter values for the D101S */
1061#define D101S_CPUSAVER_TIMER_DWORD 78
1062#define D101S_CPUSAVER_BUNDLE_DWORD 67
1063#define D101S_CPUSAVER_MIN_SIZE_DWORD 128
1064
1065#define D101S_RCVBUNDLE_UCODE \
1066{\
10670x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \
10680x000C0001, 0x00101312, 0x000C0008, 0x00380243, \
10690x0010009C, 0x00204056, 0x002380D0, 0x00380056, \
10700x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \
10710x0038047F, 0x00000000, 0x00140000, 0x003805A3, \
10720x00308000, 0x00100610, 0x00100561, 0x000E0408, \
10730x00134861, 0x000C0002, 0x00103093, 0x00308000, \
10740x00100624, 0x00100561, 0x000E0408, 0x00100861, \
10750x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \
10760x00380F90, 0x00080000, 0x00103090, 0x00380F90, \
10770x00000000, 0x00000000, 0x00000000, 0x00000000, \
10780x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \
10790x003A047E, 0x00044010, 0x00380819, 0x00000000, \
10800x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \
10810x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \
10820x00101213, 0x00260FF7, 0x00041000, 0x00010004, \
10830x00130826, 0x000C0006, 0x00220700, 0x0013C926, \
10840x00101313, 0x00380700, 0x00000000, 0x00000000, \
10850x00000000, 0x00000000, 0x00000000, 0x00000000, \
10860x00080600, 0x00101B10, 0x00050004, 0x00100826, \
10870x00101210, 0x00380FB6, 0x00000000, 0x00000000, \
10880x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \
10890x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \
10900x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \
10910x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \
10920x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \
10930x00010004, 0x00041000, 0x00278FE9, 0x00040800, \
10940x00018100, 0x003A047E, 0x00130826, 0x000C0001, \
10950x002205A7, 0x00101313, 0x003805A7, 0x00000000, \
10960x00000000, 0x00000000, 0x00000000, 0x00000000, \
10970x00000000, 0x00000000, 0x00000000, 0x00130831, \
10980x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \
10990x00041000, 0x00010004, 0x00380700 \
1100}
1101
1102/********************************************************/
1103/* Micro code for the 8086:1229 Rev F/10 */
1104/********************************************************/
1105
1106/* Parameter values for the D102 E-step */
1107#define D102_E_CPUSAVER_TIMER_DWORD 42
1108#define D102_E_CPUSAVER_BUNDLE_DWORD 54
1109#define D102_E_CPUSAVER_MIN_SIZE_DWORD 46
1110
1111#define D102_E_RCVBUNDLE_UCODE \
1112{\
11130x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \
11140x00E014B9, 0x00000000, 0x00000000, 0x00000000, \
11150x00E014BD, 0x00000000, 0x00000000, 0x00000000, \
11160x00E014D5, 0x00000000, 0x00000000, 0x00000000, \
11170x00000000, 0x00000000, 0x00000000, 0x00000000, \
11180x00E014C1, 0x00000000, 0x00000000, 0x00000000, \
11190x00000000, 0x00000000, 0x00000000, 0x00000000, \
11200x00000000, 0x00000000, 0x00000000, 0x00000000, \
11210x00000000, 0x00000000, 0x00000000, 0x00000000, \
11220x00E014C8, 0x00000000, 0x00000000, 0x00000000, \
11230x00200600, 0x00E014EE, 0x00000000, 0x00000000, \
11240x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \
11250x00E00E43, 0x00000000, 0x00000000, 0x00000000, \
11260x00300006, 0x00E014FB, 0x00000000, 0x00000000, \
11270x00000000, 0x00000000, 0x00000000, 0x00000000, \
11280x00000000, 0x00000000, 0x00000000, 0x00000000, \
11290x00000000, 0x00000000, 0x00000000, 0x00000000, \
11300x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \
11310x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \
11320x00000000, 0x00000000, 0x00000000, 0x00000000, \
11330x00000000, 0x00000000, 0x00000000, 0x00000000, \
11340x00000000, 0x00000000, 0x00000000, 0x00000000, \
11350x00000000, 0x00000000, 0x00000000, 0x00000000, \
11360x00000000, 0x00000000, 0x00000000, 0x00000000, \
11370x00000000, 0x00000000, 0x00000000, 0x00000000, \
11380x00000000, 0x00000000, 0x00000000, 0x00000000, \
11390x00000000, 0x00000000, 0x00000000, 0x00000000, \
11400x00000000, 0x00000000, 0x00000000, 0x00000000, \
11410x00000000, 0x00000000, 0x00000000, 0x00000000, \
11420x00000000, 0x00000000, 0x00000000, 0x00000000, \
11430x00000000, 0x00000000, 0x00000000, 0x00000000, \
11440x00000000, 0x00000000, 0x00000000, 0x00000000, \
11450x00000000, 0x00000000, 0x00000000, 0x00000000, \
1146}
1147
1148static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) 1010static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1149{ 1011{
1150/* *INDENT-OFF* */ 1012 int i;
1151 static struct { 1013 static const u32 ucode[UCODE_SIZE] = {
1152 u32 ucode[UCODE_SIZE + 1]; 1014 /* NFS packets are misinterpreted as TCO packets and
1153 u8 mac; 1015 * incorrectly routed to the BMC over SMBus. This
1154 u8 timer_dword; 1016 * microcode patch checks the fragmented IP bit in the
1155 u8 bundle_dword; 1017 * NFS/UDP header to distinguish between NFS and TCO. */
1156 u8 min_size_dword; 1018 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
1157 } ucode_opts[] = { 1019 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
1158 { D101M_B_RCVBUNDLE_UCODE, 1020 0x00906EFD, 0x00900EFD, 0x00E00EF8,
1159 mac_82559_D101M, 1021 };
1160 D101M_CPUSAVER_TIMER_DWORD,
1161 D101M_CPUSAVER_BUNDLE_DWORD,
1162 D101M_CPUSAVER_MIN_SIZE_DWORD },
1163 { D101S_RCVBUNDLE_UCODE,
1164 mac_82559_D101S,
1165 D101S_CPUSAVER_TIMER_DWORD,
1166 D101S_CPUSAVER_BUNDLE_DWORD,
1167 D101S_CPUSAVER_MIN_SIZE_DWORD },
1168 { D102_E_RCVBUNDLE_UCODE,
1169 mac_82551_F,
1170 D102_E_CPUSAVER_TIMER_DWORD,
1171 D102_E_CPUSAVER_BUNDLE_DWORD,
1172 D102_E_CPUSAVER_MIN_SIZE_DWORD },
1173 { D102_E_RCVBUNDLE_UCODE,
1174 mac_82551_10,
1175 D102_E_CPUSAVER_TIMER_DWORD,
1176 D102_E_CPUSAVER_BUNDLE_DWORD,
1177 D102_E_CPUSAVER_MIN_SIZE_DWORD },
1178 { {0}, 0, 0, 0, 0}
1179 }, *opts;
1180/* *INDENT-ON* */
1181
1182#define BUNDLESMALL 1
1183#define BUNDLEMAX 50
1184#define INTDELAY 15000
1185
1186 opts = ucode_opts;
1187
1188 /* do not load u-code for ICH devices */
1189 if (nic->flags & ich)
1190 return;
1191
1192 /* Search for ucode match against h/w rev_id */
1193 while (opts->mac) {
1194 if (nic->mac == opts->mac) {
1195 int i;
1196 u32 *ucode = opts->ucode;
1197
1198 /* Insert user-tunable settings */
1199 ucode[opts->timer_dword] &= 0xFFFF0000;
1200 ucode[opts->timer_dword] |=
1201 (u16) INTDELAY;
1202 ucode[opts->bundle_dword] &= 0xFFFF0000;
1203 ucode[opts->bundle_dword] |= (u16) BUNDLEMAX;
1204 ucode[opts->min_size_dword] &= 0xFFFF0000;
1205 ucode[opts->min_size_dword] |=
1206 (BUNDLESMALL) ? 0xFFFF : 0xFF80;
1207
1208 for(i = 0; i < UCODE_SIZE; i++)
1209 cb->u.ucode[i] = cpu_to_le32(ucode[i]);
1210 cb->command = cpu_to_le16(cb_ucode);
1211 return;
1212 }
1213 opts++;
1214 }
1215 1022
1216 cb->command = cpu_to_le16(cb_nop); 1023 if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
1024 for(i = 0; i < UCODE_SIZE; i++)
1025 cb->u.ucode[i] = cpu_to_le32(ucode[i]);
1026 cb->command = cpu_to_le16(cb_ucode);
1027 } else
1028 cb->command = cpu_to_le16(cb_nop);
1217} 1029}
1218 1030
1219static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, 1031static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 14c76f5e4177..9adc11e8b8bc 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -544,7 +544,7 @@ get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
544 .sibling = sibling, 544 .sibling = sibling,
545 }; 545 };
546 546
547 dev = bus_find_device(&css_bus_type, NULL, &data, match_devno); 547 dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno);
548 548
549 return dev ? to_ccwdev(dev) : NULL; 549 return dev ? to_ccwdev(dev) : NULL;
550} 550}
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index 53e0323d4b83..bdb4e454b8b0 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -73,7 +73,7 @@ struct imx_port {
73 struct uart_port port; 73 struct uart_port port;
74 struct timer_list timer; 74 struct timer_list timer;
75 unsigned int old_status; 75 unsigned int old_status;
76 int txirq,rxirq; 76 int txirq,rxirq,rtsirq;
77}; 77};
78 78
79/* 79/*
@@ -181,6 +181,22 @@ static void imx_start_tx(struct uart_port *port)
181 imx_transmit_buffer(sport); 181 imx_transmit_buffer(sport);
182} 182}
183 183
184static irqreturn_t imx_rtsint(int irq, void *dev_id, struct pt_regs *regs)
185{
186 struct imx_port *sport = (struct imx_port *)dev_id;
187 unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS;
188 unsigned long flags;
189
190 spin_lock_irqsave(&sport->port.lock, flags);
191
192 USR1((u32)sport->port.membase) = USR1_RTSD;
193 uart_handle_cts_change(&sport->port, !!val);
194 wake_up_interruptible(&sport->port.info->delta_msr_wait);
195
196 spin_unlock_irqrestore(&sport->port.lock, flags);
197 return IRQ_HANDLED;
198}
199
184static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs) 200static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs)
185{ 201{
186 struct imx_port *sport = (struct imx_port *)dev_id; 202 struct imx_port *sport = (struct imx_port *)dev_id;
@@ -386,15 +402,21 @@ static int imx_startup(struct uart_port *port)
386 if (retval) goto error_out1; 402 if (retval) goto error_out1;
387 403
388 retval = request_irq(sport->txirq, imx_txint, 0, 404 retval = request_irq(sport->txirq, imx_txint, 0,
389 "imx-uart", sport); 405 DRIVER_NAME, sport);
390 if (retval) goto error_out2; 406 if (retval) goto error_out2;
391 407
408 retval = request_irq(sport->rtsirq, imx_rtsint, 0,
409 DRIVER_NAME, sport);
410 if (retval) goto error_out3;
411 set_irq_type(sport->rtsirq, IRQT_BOTHEDGE);
412
392 /* 413 /*
393 * Finally, clear and enable interrupts 414 * Finally, clear and enable interrupts
394 */ 415 */
395 416
417 USR1((u32)sport->port.membase) = USR1_RTSD;
396 UCR1((u32)sport->port.membase) |= 418 UCR1((u32)sport->port.membase) |=
397 (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); 419 (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
398 420
399 UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN); 421 UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN);
400 /* 422 /*
@@ -406,6 +428,8 @@ static int imx_startup(struct uart_port *port)
406 428
407 return 0; 429 return 0;
408 430
431error_out3:
432 free_irq(sport->txirq, sport);
409error_out2: 433error_out2:
410 free_irq(sport->rxirq, sport); 434 free_irq(sport->rxirq, sport);
411error_out1: 435error_out1:
@@ -424,6 +448,7 @@ static void imx_shutdown(struct uart_port *port)
424 /* 448 /*
425 * Free the interrupts 449 * Free the interrupts
426 */ 450 */
451 free_irq(sport->rtsirq, sport);
427 free_irq(sport->txirq, sport); 452 free_irq(sport->txirq, sport);
428 free_irq(sport->rxirq, sport); 453 free_irq(sport->rxirq, sport);
429 454
@@ -432,7 +457,7 @@ static void imx_shutdown(struct uart_port *port)
432 */ 457 */
433 458
434 UCR1((u32)sport->port.membase) &= 459 UCR1((u32)sport->port.membase) &=
435 ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); 460 ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
436} 461}
437 462
438static void 463static void
@@ -522,7 +547,7 @@ imx_set_termios(struct uart_port *port, struct termios *termios,
522 * disable interrupts and drain transmitter 547 * disable interrupts and drain transmitter
523 */ 548 */
524 old_ucr1 = UCR1((u32)sport->port.membase); 549 old_ucr1 = UCR1((u32)sport->port.membase);
525 UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN); 550 UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
526 551
527 while ( !(USR2((u32)sport->port.membase) & USR2_TXDC)) 552 while ( !(USR2((u32)sport->port.membase) & USR2_TXDC))
528 barrier(); 553 barrier();
@@ -643,6 +668,7 @@ static struct imx_port imx_ports[] = {
643 { 668 {
644 .txirq = UART1_MINT_TX, 669 .txirq = UART1_MINT_TX,
645 .rxirq = UART1_MINT_RX, 670 .rxirq = UART1_MINT_RX,
671 .rtsirq = UART1_MINT_RTS,
646 .port = { 672 .port = {
647 .type = PORT_IMX, 673 .type = PORT_IMX,
648 .iotype = SERIAL_IO_MEM, 674 .iotype = SERIAL_IO_MEM,
@@ -658,6 +684,7 @@ static struct imx_port imx_ports[] = {
658 }, { 684 }, {
659 .txirq = UART2_MINT_TX, 685 .txirq = UART2_MINT_TX,
660 .rxirq = UART2_MINT_RX, 686 .rxirq = UART2_MINT_RX,
687 .rtsirq = UART2_MINT_RTS,
661 .port = { 688 .port = {
662 .type = PORT_IMX, 689 .type = PORT_IMX,
663 .iotype = SERIAL_IO_MEM, 690 .iotype = SERIAL_IO_MEM,
@@ -737,7 +764,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
737 764
738 UCR1((u32)sport->port.membase) = 765 UCR1((u32)sport->port.membase) =
739 (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) 766 (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN)
740 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN); 767 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN);
741 UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; 768 UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN;
742 769
743 /* 770 /*
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 672b359b07ce..90c2a86c421b 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -499,7 +499,7 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
499 /* 499 /*
500 * Update the per-port timeout. 500 * Update the per-port timeout.
501 */ 501 */
502 uart_update_timeout(port, termios->c_cflag, quot); 502 uart_update_timeout(port, termios->c_cflag, baud);
503 503
504 up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; 504 up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
505 if (termios->c_iflag & INPCK) 505 if (termios->c_iflag & INPCK)
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index eff2158024c8..52692aa345ec 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1092,8 +1092,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1092 1092
1093static int probe_index = 0; 1093static int probe_index = 0;
1094 1094
1095int s3c24xx_serial_probe(struct device *_dev, 1095static int s3c24xx_serial_probe(struct device *_dev,
1096 struct s3c24xx_uart_info *info) 1096 struct s3c24xx_uart_info *info)
1097{ 1097{
1098 struct s3c24xx_uart_port *ourport; 1098 struct s3c24xx_uart_port *ourport;
1099 struct platform_device *dev = to_platform_device(_dev); 1099 struct platform_device *dev = to_platform_device(_dev);
@@ -1120,7 +1120,7 @@ int s3c24xx_serial_probe(struct device *_dev,
1120 return ret; 1120 return ret;
1121} 1121}
1122 1122
1123int s3c24xx_serial_remove(struct device *_dev) 1123static int s3c24xx_serial_remove(struct device *_dev)
1124{ 1124{
1125 struct uart_port *port = s3c24xx_dev_to_port(_dev); 1125 struct uart_port *port = s3c24xx_dev_to_port(_dev);
1126 1126
@@ -1134,7 +1134,8 @@ int s3c24xx_serial_remove(struct device *_dev)
1134 1134
1135#ifdef CONFIG_PM 1135#ifdef CONFIG_PM
1136 1136
1137int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level) 1137static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state,
1138 u32 level)
1138{ 1139{
1139 struct uart_port *port = s3c24xx_dev_to_port(dev); 1140 struct uart_port *port = s3c24xx_dev_to_port(dev);
1140 1141
@@ -1144,7 +1145,7 @@ int s3c24xx_serial_suspend(struct device *dev, pm_message_t state, u32 level)
1144 return 0; 1145 return 0;
1145} 1146}
1146 1147
1147int s3c24xx_serial_resume(struct device *dev, u32 level) 1148static int s3c24xx_serial_resume(struct device *dev, u32 level)
1148{ 1149{
1149 struct uart_port *port = s3c24xx_dev_to_port(dev); 1150 struct uart_port *port = s3c24xx_dev_to_port(dev);
1150 struct s3c24xx_uart_port *ourport = to_ourport(port); 1151 struct s3c24xx_uart_port *ourport = to_ourport(port);
@@ -1165,8 +1166,8 @@ int s3c24xx_serial_resume(struct device *dev, u32 level)
1165#define s3c24xx_serial_resume NULL 1166#define s3c24xx_serial_resume NULL
1166#endif 1167#endif
1167 1168
1168int s3c24xx_serial_init(struct device_driver *drv, 1169static int s3c24xx_serial_init(struct device_driver *drv,
1169 struct s3c24xx_uart_info *info) 1170 struct s3c24xx_uart_info *info)
1170{ 1171{
1171 dbg("s3c24xx_serial_init(%p,%p)\n", drv, info); 1172 dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
1172 return driver_register(drv); 1173 return driver_register(drv);
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index e971156daa60..ba9381fd3f2d 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -274,7 +274,6 @@ static void transmit_chars(struct uart_sunsab_port *up,
274 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { 274 if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
275 up->interrupt_mask1 |= SAB82532_IMR1_XPR; 275 up->interrupt_mask1 |= SAB82532_IMR1_XPR;
276 writeb(up->interrupt_mask1, &up->regs->w.imr1); 276 writeb(up->interrupt_mask1, &up->regs->w.imr1);
277 uart_write_wakeup(&up->port);
278 return; 277 return;
279 } 278 }
280 279
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index d75445738c88..7653d6cf05af 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -517,10 +517,9 @@ static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
517 if (up->port.info == NULL) 517 if (up->port.info == NULL)
518 goto ack_tx_int; 518 goto ack_tx_int;
519 xmit = &up->port.info->xmit; 519 xmit = &up->port.info->xmit;
520 if (uart_circ_empty(xmit)) { 520 if (uart_circ_empty(xmit))
521 uart_write_wakeup(&up->port);
522 goto ack_tx_int; 521 goto ack_tx_int;
523 } 522
524 if (uart_tx_stopped(&up->port)) 523 if (uart_tx_stopped(&up->port))
525 goto ack_tx_int; 524 goto ack_tx_int;
526 525
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index a4799e971d1c..bbc3cc63854f 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -175,16 +175,16 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
175} 175}
176 176
177/** 177/**
178 * v9fs_read - read from a file (internal) 178 * v9fs_file_read - read from a file
179 * @filep: file pointer to read 179 * @filep: file pointer to read
180 * @data: data buffer to read data into 180 * @data: data buffer to read data into
181 * @count: size of buffer 181 * @count: size of buffer
182 * @offset: offset at which to read data 182 * @offset: offset at which to read data
183 * 183 *
184 */ 184 */
185
186static ssize_t 185static ssize_t
187v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset) 186v9fs_file_read(struct file *filp, char __user * data, size_t count,
187 loff_t * offset)
188{ 188{
189 struct inode *inode = filp->f_dentry->d_inode; 189 struct inode *inode = filp->f_dentry->d_inode;
190 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 190 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
@@ -194,6 +194,7 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
194 int rsize = 0; 194 int rsize = 0;
195 int result = 0; 195 int result = 0;
196 int total = 0; 196 int total = 0;
197 int n;
197 198
198 dprintk(DEBUG_VFS, "\n"); 199 dprintk(DEBUG_VFS, "\n");
199 200
@@ -216,10 +217,15 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
216 } else 217 } else
217 *offset += result; 218 *offset += result;
218 219
219 /* XXX - extra copy */ 220 n = copy_to_user(data, fcall->params.rread.data, result);
220 memcpy(buffer, fcall->params.rread.data, result); 221 if (n) {
222 dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n);
223 kfree(fcall);
224 return -EFAULT;
225 }
226
221 count -= result; 227 count -= result;
222 buffer += result; 228 data += result;
223 total += result; 229 total += result;
224 230
225 kfree(fcall); 231 kfree(fcall);
@@ -232,42 +238,7 @@ v9fs_read(struct file *filp, char *buffer, size_t count, loff_t * offset)
232} 238}
233 239
234/** 240/**
235 * v9fs_file_read - read from a file 241 * v9fs_file_write - write to a file
236 * @filep: file pointer to read
237 * @data: data buffer to read data into
238 * @count: size of buffer
239 * @offset: offset at which to read data
240 *
241 */
242
243static ssize_t
244v9fs_file_read(struct file *filp, char __user * data, size_t count,
245 loff_t * offset)
246{
247 int retval = -1;
248 int ret = 0;
249 char *buffer;
250
251 buffer = kmalloc(count, GFP_KERNEL);
252 if (!buffer)
253 return -ENOMEM;
254
255 retval = v9fs_read(filp, buffer, count, offset);
256 if (retval > 0) {
257 if ((ret = copy_to_user(data, buffer, retval)) != 0) {
258 dprintk(DEBUG_ERROR, "Problem copying to user %d\n",
259 ret);
260 retval = ret;
261 }
262 }
263
264 kfree(buffer);
265
266 return retval;
267}
268
269/**
270 * v9fs_write - write to a file
271 * @filep: file pointer to write 242 * @filep: file pointer to write
272 * @data: data buffer to write data from 243 * @data: data buffer to write data from
273 * @count: size of buffer 244 * @count: size of buffer
@@ -276,7 +247,8 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count,
276 */ 247 */
277 248
278static ssize_t 249static ssize_t
279v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset) 250v9fs_file_write(struct file *filp, const char __user * data,
251 size_t count, loff_t * offset)
280{ 252{
281 struct inode *inode = filp->f_dentry->d_inode; 253 struct inode *inode = filp->f_dentry->d_inode;
282 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 254 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
@@ -286,30 +258,42 @@ v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset)
286 int result = -EIO; 258 int result = -EIO;
287 int rsize = 0; 259 int rsize = 0;
288 int total = 0; 260 int total = 0;
261 char *buf;
289 262
290 dprintk(DEBUG_VFS, "data %p count %d offset %x\n", buffer, (int)count, 263 dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count,
291 (int)*offset); 264 (int)*offset);
292 rsize = v9ses->maxdata - V9FS_IOHDRSZ; 265 rsize = v9ses->maxdata - V9FS_IOHDRSZ;
293 if (v9fid->iounit != 0 && rsize > v9fid->iounit) 266 if (v9fid->iounit != 0 && rsize > v9fid->iounit)
294 rsize = v9fid->iounit; 267 rsize = v9fid->iounit;
295 268
296 dump_data(buffer, count); 269 buf = kmalloc(v9ses->maxdata - V9FS_IOHDRSZ, GFP_KERNEL);
270 if (!buf)
271 return -ENOMEM;
297 272
298 do { 273 do {
299 if (count < rsize) 274 if (count < rsize)
300 rsize = count; 275 rsize = count;
301 276
302 result = 277 result = copy_from_user(buf, data, rsize);
303 v9fs_t_write(v9ses, fid, *offset, rsize, buffer, &fcall); 278 if (result) {
279 dprintk(DEBUG_ERROR, "Problem copying from user\n");
280 kfree(buf);
281 return -EFAULT;
282 }
283
284 dump_data(buf, rsize);
285 result = v9fs_t_write(v9ses, fid, *offset, rsize, buf, &fcall);
304 if (result < 0) { 286 if (result < 0) {
305 eprintk(KERN_ERR, "error while writing: %s(%d)\n", 287 eprintk(KERN_ERR, "error while writing: %s(%d)\n",
306 FCALL_ERROR(fcall), result); 288 FCALL_ERROR(fcall), result);
307 kfree(fcall); 289 kfree(fcall);
290 kfree(buf);
308 return result; 291 return result;
309 } else 292 } else
310 *offset += result; 293 *offset += result;
311 294
312 kfree(fcall); 295 kfree(fcall);
296 fcall = NULL;
313 297
314 if (result != rsize) { 298 if (result != rsize) {
315 eprintk(KERN_ERR, 299 eprintk(KERN_ERR,
@@ -319,46 +303,14 @@ v9fs_write(struct file *filp, char *buffer, size_t count, loff_t * offset)
319 } 303 }
320 304
321 count -= result; 305 count -= result;
322 buffer += result; 306 data += result;
323 total += result; 307 total += result;
324 } while (count); 308 } while (count);
325 309
310 kfree(buf);
326 return total; 311 return total;
327} 312}
328 313
329/**
330 * v9fs_file_write - write to a file
331 * @filep: file pointer to write
332 * @data: data buffer to write data from
333 * @count: size of buffer
334 * @offset: offset at which to write data
335 *
336 */
337
338static ssize_t
339v9fs_file_write(struct file *filp, const char __user * data,
340 size_t count, loff_t * offset)
341{
342 int ret = -1;
343 char *buffer;
344
345 buffer = kmalloc(count, GFP_KERNEL);
346 if (buffer == NULL)
347 return -ENOMEM;
348
349 ret = copy_from_user(buffer, data, count);
350 if (ret) {
351 dprintk(DEBUG_ERROR, "Problem copying from user\n");
352 ret = -EFAULT;
353 } else {
354 ret = v9fs_write(filp, buffer, count, offset);
355 }
356
357 kfree(buffer);
358
359 return ret;
360}
361
362struct file_operations v9fs_file_operations = { 314struct file_operations v9fs_file_operations = {
363 .llseek = generic_file_llseek, 315 .llseek = generic_file_llseek,
364 .read = v9fs_file_read, 316 .read = v9fs_file_read,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 7976a238f0a3..d4b15576e584 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -905,7 +905,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
905 send_sig(SIGKILL, current, 0); 905 send_sig(SIGKILL, current, 0);
906 goto out_free_dentry; 906 goto out_free_dentry;
907 } 907 }
908 if (padzero(elf_bss)) { 908 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
909 send_sig(SIGSEGV, current, 0); 909 send_sig(SIGSEGV, current, 0);
910 retval = -EFAULT; /* Nobody gets to see this, but.. */ 910 retval = -EFAULT; /* Nobody gets to see this, but.. */
911 goto out_free_dentry; 911 goto out_free_dentry;
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
index 251e5a1bb1c4..0c2be8c0307d 100644
--- a/fs/nfs_common/nfsacl.c
+++ b/fs/nfs_common/nfsacl.c
@@ -48,43 +48,26 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
48 (struct nfsacl_encode_desc *) desc; 48 (struct nfsacl_encode_desc *) desc;
49 u32 *p = (u32 *) elem; 49 u32 *p = (u32 *) elem;
50 50
51 if (nfsacl_desc->count < nfsacl_desc->acl->a_count) { 51 struct posix_acl_entry *entry =
52 struct posix_acl_entry *entry = 52 &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
53 &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
54 53
55 *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag); 54 *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
56 switch(entry->e_tag) { 55 switch(entry->e_tag) {
57 case ACL_USER_OBJ: 56 case ACL_USER_OBJ:
58 *p++ = htonl(nfsacl_desc->uid); 57 *p++ = htonl(nfsacl_desc->uid);
59 break; 58 break;
60 case ACL_GROUP_OBJ: 59 case ACL_GROUP_OBJ:
61 *p++ = htonl(nfsacl_desc->gid); 60 *p++ = htonl(nfsacl_desc->gid);
62 break; 61 break;
63 case ACL_USER: 62 case ACL_USER:
64 case ACL_GROUP: 63 case ACL_GROUP:
65 *p++ = htonl(entry->e_id); 64 *p++ = htonl(entry->e_id);
66 break; 65 break;
67 default: /* Solaris depends on that! */ 66 default: /* Solaris depends on that! */
68 *p++ = 0; 67 *p++ = 0;
69 break; 68 break;
70 }
71 *p++ = htonl(entry->e_perm & S_IRWXO);
72 } else {
73 const struct posix_acl_entry *pa, *pe;
74 int group_obj_perm = ACL_READ|ACL_WRITE|ACL_EXECUTE;
75
76 FOREACH_ACL_ENTRY(pa, nfsacl_desc->acl, pe) {
77 if (pa->e_tag == ACL_GROUP_OBJ) {
78 group_obj_perm = pa->e_perm & S_IRWXO;
79 break;
80 }
81 }
82 /* fake up ACL_MASK entry */
83 *p++ = htonl(ACL_MASK | nfsacl_desc->typeflag);
84 *p++ = htonl(0);
85 *p++ = htonl(group_obj_perm);
86 } 69 }
87 70 *p++ = htonl(entry->e_perm & S_IRWXO);
88 return 0; 71 return 0;
89} 72}
90 73
@@ -105,11 +88,28 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
105 .gid = inode->i_gid, 88 .gid = inode->i_gid,
106 }; 89 };
107 int err; 90 int err;
91 struct posix_acl *acl2 = NULL;
108 92
109 if (entries > NFS_ACL_MAX_ENTRIES || 93 if (entries > NFS_ACL_MAX_ENTRIES ||
110 xdr_encode_word(buf, base, entries)) 94 xdr_encode_word(buf, base, entries))
111 return -EINVAL; 95 return -EINVAL;
96 if (encode_entries && acl && acl->a_count == 3) {
97 /* Fake up an ACL_MASK entry. */
98 acl2 = posix_acl_alloc(4, GFP_KERNEL);
99 if (!acl2)
100 return -ENOMEM;
101 /* Insert entries in canonical order: other orders seem
102 to confuse Solaris VxFS. */
103 acl2->a_entries[0] = acl->a_entries[0]; /* ACL_USER_OBJ */
104 acl2->a_entries[1] = acl->a_entries[1]; /* ACL_GROUP_OBJ */
105 acl2->a_entries[2] = acl->a_entries[1]; /* ACL_MASK */
106 acl2->a_entries[2].e_tag = ACL_MASK;
107 acl2->a_entries[3] = acl->a_entries[2]; /* ACL_OTHER */
108 nfsacl_desc.acl = acl2;
109 }
112 err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc); 110 err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
111 if (acl2)
112 posix_acl_release(acl2);
113 if (!err) 113 if (!err)
114 err = 8 + nfsacl_desc.desc.elem_size * 114 err = 8 + nfsacl_desc.desc.elem_size *
115 nfsacl_desc.desc.array_len; 115 nfsacl_desc.desc.array_len;
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 939d9e5020a0..13fa2deb4ddd 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -126,8 +126,8 @@
126#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */ 126#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */
127#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */ 127#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */
128#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */ 128#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */
129#define DRCMR15 __REG(0x4000013c) /* Reserved */ 129#define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for SSP2 receive Request */
130#define DRCMR16 __REG(0x40000140) /* Reserved */ 130#define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for SSP2 transmit Request */
131#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */ 131#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */
132#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */ 132#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */
133#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */ 133#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */
@@ -151,7 +151,8 @@
151#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */ 151#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */
152#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */ 152#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */
153#define DRCMR39 __REG(0x4000019C) /* Reserved */ 153#define DRCMR39 __REG(0x4000019C) /* Reserved */
154 154#define DRCMR66 __REG(0x40001108) /* Request to Channel Map Register for SSP3 receive Request */
155#define DRCMR67 __REG(0x4000110C) /* Request to Channel Map Register for SSP3 transmit Request */
155#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */ 156#define DRCMR68 __REG(0x40001110) /* Request to Channel Map Register for Camera FIFO 0 Request */
156#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */ 157#define DRCMR69 __REG(0x40001114) /* Request to Channel Map Register for Camera FIFO 1 Request */
157#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */ 158#define DRCMR70 __REG(0x40001118) /* Request to Channel Map Register for Camera FIFO 2 Request */
diff --git a/include/asm-arm/arch-s3c2410/hardware.h b/include/asm-arm/arch-s3c2410/hardware.h
index 48a39918a760..1c9de29cafef 100644
--- a/include/asm-arm/arch-s3c2410/hardware.h
+++ b/include/asm-arm/arch-s3c2410/hardware.h
@@ -92,6 +92,13 @@ extern unsigned int s3c2410_gpio_getpin(unsigned int pin);
92 92
93extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg); 93extern unsigned int s3c2410_modify_misccr(unsigned int clr, unsigned int chg);
94 94
95#ifdef CONFIG_CPU_S3C2440
96
97extern int s3c2440_set_dsc(unsigned int pin, unsigned int value);
98
99#endif /* CONFIG_CPU_S3C2440 */
100
101
95#endif /* __ASSEMBLY__ */ 102#endif /* __ASSEMBLY__ */
96 103
97#include <asm/sizes.h> 104#include <asm/sizes.h>
diff --git a/include/asm-powerpc/timex.h b/include/asm-powerpc/timex.h
index 51c5b316be55..c02d15aced91 100644
--- a/include/asm-powerpc/timex.h
+++ b/include/asm-powerpc/timex.h
@@ -10,7 +10,7 @@
10#include <linux/config.h> 10#include <linux/config.h>
11#include <asm/cputable.h> 11#include <asm/cputable.h>
12 12
13#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ 13#define CLOCK_TICK_RATE 1024000 /* Underlying HZ */
14 14
15typedef unsigned long cycles_t; 15typedef unsigned long cycles_t;
16 16
diff --git a/include/asm-ppc/cputable.h b/include/asm-ppc/cputable.h
index 41d8f8425c04..e17c492c870b 100644
--- a/include/asm-ppc/cputable.h
+++ b/include/asm-ppc/cputable.h
@@ -24,6 +24,7 @@
24#define PPC_FEATURE_HAS_SPE 0x00800000 24#define PPC_FEATURE_HAS_SPE 0x00800000
25#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 25#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
26#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 26#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
27#define PPC_FEATURE_NO_TB 0x00100000
27 28
28#ifdef __KERNEL__ 29#ifdef __KERNEL__
29 30
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index b15826f6e3a2..fe9778301d07 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -392,4 +392,16 @@ extern cpumask_t cpu_present_map;
392#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) 392#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map)
393#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) 393#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
394 394
395/* Find the highest possible smp_processor_id() */
396static inline unsigned int highest_possible_processor_id(void)
397{
398 unsigned int cpu, highest = 0;
399
400 for_each_cpu_mask(cpu, cpu_possible_map)
401 highest = cpu;
402
403 return highest;
404}
405
406
395#endif /* __LINUX_CPUMASK_H */ 407#endif /* __LINUX_CPUMASK_H */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 1d5b10ae2399..f08e870100f4 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -41,11 +41,15 @@ enum nfnetlink_groups {
41struct nfattr 41struct nfattr
42{ 42{
43 u_int16_t nfa_len; 43 u_int16_t nfa_len;
44 u_int16_t nfa_type; 44 u_int16_t nfa_type; /* we use 15 bits for the type, and the highest
45 * bit to indicate whether the payload is nested */
45} __attribute__ ((packed)); 46} __attribute__ ((packed));
46 47
47/* FIXME: Shamelessly copy and pasted from rtnetlink.h, it's time 48/* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from
48 * to put this in a generic file */ 49 * rtnetlink.h, it's time to put this in a generic file */
50
51#define NFNL_NFA_NEST 0x8000
52#define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff)
49 53
50#define NFA_ALIGNTO 4 54#define NFA_ALIGNTO 4
51#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1)) 55#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
@@ -59,7 +63,7 @@ struct nfattr
59#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0)) 63#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
60#define NFA_NEST(skb, type) \ 64#define NFA_NEST(skb, type) \
61({ struct nfattr *__start = (struct nfattr *) (skb)->tail; \ 65({ struct nfattr *__start = (struct nfattr *) (skb)->tail; \
62 NFA_PUT(skb, type, 0, NULL); \ 66 NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \
63 __start; }) 67 __start; })
64#define NFA_NEST_END(skb, start) \ 68#define NFA_NEST_END(skb, start) \
65({ (start)->nfa_len = ((skb)->tail - (unsigned char *) (start)); \ 69({ (start)->nfa_len = ((skb)->tail - (unsigned char *) (start)); \
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 5c55751c78e4..116fcaced909 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -70,15 +70,24 @@ enum ctattr_l4proto {
70 70
71enum ctattr_protoinfo { 71enum ctattr_protoinfo {
72 CTA_PROTOINFO_UNSPEC, 72 CTA_PROTOINFO_UNSPEC,
73 CTA_PROTOINFO_TCP_STATE, 73 CTA_PROTOINFO_TCP,
74 __CTA_PROTOINFO_MAX 74 __CTA_PROTOINFO_MAX
75}; 75};
76#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1) 76#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
77 77
78enum ctattr_protoinfo_tcp {
79 CTA_PROTOINFO_TCP_UNSPEC,
80 CTA_PROTOINFO_TCP_STATE,
81 __CTA_PROTOINFO_TCP_MAX
82};
83#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
84
78enum ctattr_counters { 85enum ctattr_counters {
79 CTA_COUNTERS_UNSPEC, 86 CTA_COUNTERS_UNSPEC,
80 CTA_COUNTERS_PACKETS, 87 CTA_COUNTERS_PACKETS, /* old 64bit counters */
81 CTA_COUNTERS_BYTES, 88 CTA_COUNTERS_BYTES, /* old 64bit counters */
89 CTA_COUNTERS32_PACKETS,
90 CTA_COUNTERS32_BYTES,
82 __CTA_COUNTERS_MAX 91 __CTA_COUNTERS_MAX
83}; 92};
84#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1) 93#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index 4ced38736813..d078bb91d9e5 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -117,6 +117,10 @@ enum ip_conntrack_events
117 /* NAT info */ 117 /* NAT info */
118 IPCT_NATINFO_BIT = 10, 118 IPCT_NATINFO_BIT = 10,
119 IPCT_NATINFO = (1 << IPCT_NATINFO_BIT), 119 IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
120
121 /* Counter highest bit has been set */
122 IPCT_COUNTER_FILLING_BIT = 11,
123 IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
120}; 124};
121 125
122enum ip_conntrack_expect_events { 126enum ip_conntrack_expect_events {
@@ -192,8 +196,8 @@ do { \
192 196
193struct ip_conntrack_counter 197struct ip_conntrack_counter
194{ 198{
195 u_int64_t packets; 199 u_int32_t packets;
196 u_int64_t bytes; 200 u_int32_t bytes;
197}; 201};
198 202
199struct ip_conntrack_helper; 203struct ip_conntrack_helper;
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_protocol.h b/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
index b6b99be8632a..2c76b879e3dc 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
@@ -52,6 +52,9 @@ struct ip_conntrack_protocol
52 int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa, 52 int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa,
53 const struct ip_conntrack *ct); 53 const struct ip_conntrack *ct);
54 54
55 /* convert nfnetlink attributes to protoinfo */
56 int (*from_nfattr)(struct nfattr *tb[], struct ip_conntrack *ct);
57
55 int (*tuple_to_nfattr)(struct sk_buff *skb, 58 int (*tuple_to_nfattr)(struct sk_buff *skb,
56 const struct ip_conntrack_tuple *t); 59 const struct ip_conntrack_tuple *t);
57 int (*nfattr_to_tuple)(struct nfattr *tb[], 60 int (*nfattr_to_tuple)(struct nfattr *tb[],
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
index 20e43f018b7c..3232db11a4e5 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -1,6 +1,8 @@
1#ifndef _IP_CONNTRACK_TUPLE_H 1#ifndef _IP_CONNTRACK_TUPLE_H
2#define _IP_CONNTRACK_TUPLE_H 2#define _IP_CONNTRACK_TUPLE_H
3 3
4#include <linux/types.h>
5
4/* A `tuple' is a structure containing the information to uniquely 6/* A `tuple' is a structure containing the information to uniquely
5 identify a connection. ie. if two packets have the same tuple, they 7 identify a connection. ie. if two packets have the same tuple, they
6 are in the same connection; if not, they are not. 8 are in the same connection; if not, they are not.
diff --git a/include/linux/netfilter_ipv4/ip_nat.h b/include/linux/netfilter_ipv4/ip_nat.h
index e201ec6e9905..41a107de17cf 100644
--- a/include/linux/netfilter_ipv4/ip_nat.h
+++ b/include/linux/netfilter_ipv4/ip_nat.h
@@ -58,10 +58,6 @@ extern rwlock_t ip_nat_lock;
58struct ip_nat_info 58struct ip_nat_info
59{ 59{
60 struct list_head bysource; 60 struct list_head bysource;
61
62 /* Helper (NULL if none). */
63 struct ip_nat_helper *helper;
64
65 struct ip_nat_seq seq[IP_CT_DIR_MAX]; 61 struct ip_nat_seq seq[IP_CT_DIR_MAX];
66}; 62};
67 63
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index 5ade54a78dbb..ca5a8733000f 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -86,7 +86,7 @@ static inline void netpoll_poll_unlock(void *have)
86 86
87#else 87#else
88#define netpoll_rx(a) 0 88#define netpoll_rx(a) 0
89#define netpoll_poll_lock(a) 0 89#define netpoll_poll_lock(a) NULL
90#define netpoll_poll_unlock(a) 90#define netpoll_poll_unlock(a)
91#endif 91#endif
92 92
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 4ade56ef3a4d..28f7b2103505 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -19,6 +19,7 @@
19 19
20#include <linux/ip.h> 20#include <linux/ip.h>
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/module.h>
22#include <linux/timer.h> 23#include <linux/timer.h>
23#include <linux/types.h> 24#include <linux/types.h>
24#include <linux/workqueue.h> 25#include <linux/workqueue.h>
@@ -193,11 +194,13 @@ static inline u32 inet_rcv_saddr(const struct sock *sk)
193static inline void inet_twsk_put(struct inet_timewait_sock *tw) 194static inline void inet_twsk_put(struct inet_timewait_sock *tw)
194{ 195{
195 if (atomic_dec_and_test(&tw->tw_refcnt)) { 196 if (atomic_dec_and_test(&tw->tw_refcnt)) {
197 struct module *owner = tw->tw_prot->owner;
196#ifdef SOCK_REFCNT_DEBUG 198#ifdef SOCK_REFCNT_DEBUG
197 printk(KERN_DEBUG "%s timewait_sock %p released\n", 199 printk(KERN_DEBUG "%s timewait_sock %p released\n",
198 tw->tw_prot->name, tw); 200 tw->tw_prot->name, tw);
199#endif 201#endif
200 kmem_cache_free(tw->tw_prot->twsk_slab, tw); 202 kmem_cache_free(tw->tw_prot->twsk_slab, tw);
203 module_put(owner);
201 } 204 }
202} 205}
203 206
diff --git a/mm/fremap.c b/mm/fremap.c
index 3235fb77c133..ab23a0673c35 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -89,6 +89,9 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma,
89 size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 89 size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
90 if (!page->mapping || page->index >= size) 90 if (!page->mapping || page->index >= size)
91 goto err_unlock; 91 goto err_unlock;
92 err = -ENOMEM;
93 if (page_mapcount(page) > INT_MAX/2)
94 goto err_unlock;
92 95
93 zap_pte(mm, vma, addr, pte); 96 zap_pte(mm, vma, addr, pte);
94 97
diff --git a/mm/madvise.c b/mm/madvise.c
index 4454936f87d1..20e075d1c64c 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -83,6 +83,9 @@ static long madvise_willneed(struct vm_area_struct * vma,
83{ 83{
84 struct file *file = vma->vm_file; 84 struct file *file = vma->vm_file;
85 85
86 if (!file)
87 return -EBADF;
88
86 if (file->f_mapping->a_ops->get_xip_page) { 89 if (file->f_mapping->a_ops->get_xip_page) {
87 /* no bad return value, but ignore advice */ 90 /* no bad return value, but ignore advice */
88 return 0; 91 return 0;
@@ -141,11 +144,7 @@ static long
141madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev, 144madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
142 unsigned long start, unsigned long end, int behavior) 145 unsigned long start, unsigned long end, int behavior)
143{ 146{
144 struct file *filp = vma->vm_file; 147 long error;
145 long error = -EBADF;
146
147 if (!filp)
148 goto out;
149 148
150 switch (behavior) { 149 switch (behavior) {
151 case MADV_NORMAL: 150 case MADV_NORMAL:
@@ -166,8 +165,6 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
166 error = -EINVAL; 165 error = -EINVAL;
167 break; 166 break;
168 } 167 }
169
170out:
171 return error; 168 return error;
172} 169}
173 170
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 91bb895375f4..defcf6a8607c 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -79,7 +79,6 @@ static void destroy_nbp(struct net_bridge_port *p)
79{ 79{
80 struct net_device *dev = p->dev; 80 struct net_device *dev = p->dev;
81 81
82 dev->br_port = NULL;
83 p->br = NULL; 82 p->br = NULL;
84 p->dev = NULL; 83 p->dev = NULL;
85 dev_put(dev); 84 dev_put(dev);
@@ -100,6 +99,7 @@ static void del_nbp(struct net_bridge_port *p)
100 struct net_bridge *br = p->br; 99 struct net_bridge *br = p->br;
101 struct net_device *dev = p->dev; 100 struct net_device *dev = p->dev;
102 101
102 dev->br_port = NULL;
103 dev_set_promiscuity(dev, -1); 103 dev_set_promiscuity(dev, -1);
104 104
105 spin_lock_bh(&br->lock); 105 spin_lock_bh(&br->lock);
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index c4540144f0f4..f8ffbf6e2333 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -26,6 +26,7 @@
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28#include <linux/smp.h> 28#include <linux/smp.h>
29#include <linux/cpumask.h>
29#include <net/sock.h> 30#include <net/sock.h>
30/* needed for logical [in,out]-dev filtering */ 31/* needed for logical [in,out]-dev filtering */
31#include "../br_private.h" 32#include "../br_private.h"
@@ -823,10 +824,11 @@ static int translate_table(struct ebt_replace *repl,
823 /* this will get free'd in do_replace()/ebt_register_table() 824 /* this will get free'd in do_replace()/ebt_register_table()
824 if an error occurs */ 825 if an error occurs */
825 newinfo->chainstack = (struct ebt_chainstack **) 826 newinfo->chainstack = (struct ebt_chainstack **)
826 vmalloc(num_possible_cpus() * sizeof(struct ebt_chainstack)); 827 vmalloc((highest_possible_processor_id()+1)
828 * sizeof(struct ebt_chainstack));
827 if (!newinfo->chainstack) 829 if (!newinfo->chainstack)
828 return -ENOMEM; 830 return -ENOMEM;
829 for (i = 0; i < num_possible_cpus(); i++) { 831 for_each_cpu(i) {
830 newinfo->chainstack[i] = 832 newinfo->chainstack[i] =
831 vmalloc(udc_cnt * sizeof(struct ebt_chainstack)); 833 vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
832 if (!newinfo->chainstack[i]) { 834 if (!newinfo->chainstack[i]) {
@@ -895,9 +897,12 @@ static void get_counters(struct ebt_counter *oldcounters,
895 897
896 /* counters of cpu 0 */ 898 /* counters of cpu 0 */
897 memcpy(counters, oldcounters, 899 memcpy(counters, oldcounters,
898 sizeof(struct ebt_counter) * nentries); 900 sizeof(struct ebt_counter) * nentries);
901
899 /* add other counters to those of cpu 0 */ 902 /* add other counters to those of cpu 0 */
900 for (cpu = 1; cpu < num_possible_cpus(); cpu++) { 903 for_each_cpu(cpu) {
904 if (cpu == 0)
905 continue;
901 counter_base = COUNTER_BASE(oldcounters, nentries, cpu); 906 counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
902 for (i = 0; i < nentries; i++) { 907 for (i = 0; i < nentries; i++) {
903 counters[i].pcnt += counter_base[i].pcnt; 908 counters[i].pcnt += counter_base[i].pcnt;
@@ -929,7 +934,8 @@ static int do_replace(void __user *user, unsigned int len)
929 BUGPRINT("Entries_size never zero\n"); 934 BUGPRINT("Entries_size never zero\n");
930 return -EINVAL; 935 return -EINVAL;
931 } 936 }
932 countersize = COUNTER_OFFSET(tmp.nentries) * num_possible_cpus(); 937 countersize = COUNTER_OFFSET(tmp.nentries) *
938 (highest_possible_processor_id()+1);
933 newinfo = (struct ebt_table_info *) 939 newinfo = (struct ebt_table_info *)
934 vmalloc(sizeof(struct ebt_table_info) + countersize); 940 vmalloc(sizeof(struct ebt_table_info) + countersize);
935 if (!newinfo) 941 if (!newinfo)
@@ -1022,7 +1028,7 @@ static int do_replace(void __user *user, unsigned int len)
1022 1028
1023 vfree(table->entries); 1029 vfree(table->entries);
1024 if (table->chainstack) { 1030 if (table->chainstack) {
1025 for (i = 0; i < num_possible_cpus(); i++) 1031 for_each_cpu(i)
1026 vfree(table->chainstack[i]); 1032 vfree(table->chainstack[i]);
1027 vfree(table->chainstack); 1033 vfree(table->chainstack);
1028 } 1034 }
@@ -1040,7 +1046,7 @@ free_counterstmp:
1040 vfree(counterstmp); 1046 vfree(counterstmp);
1041 /* can be initialized in translate_table() */ 1047 /* can be initialized in translate_table() */
1042 if (newinfo->chainstack) { 1048 if (newinfo->chainstack) {
1043 for (i = 0; i < num_possible_cpus(); i++) 1049 for_each_cpu(i)
1044 vfree(newinfo->chainstack[i]); 1050 vfree(newinfo->chainstack[i]);
1045 vfree(newinfo->chainstack); 1051 vfree(newinfo->chainstack);
1046 } 1052 }
@@ -1132,7 +1138,8 @@ int ebt_register_table(struct ebt_table *table)
1132 return -EINVAL; 1138 return -EINVAL;
1133 } 1139 }
1134 1140
1135 countersize = COUNTER_OFFSET(table->table->nentries) * num_possible_cpus(); 1141 countersize = COUNTER_OFFSET(table->table->nentries) *
1142 (highest_possible_processor_id()+1);
1136 newinfo = (struct ebt_table_info *) 1143 newinfo = (struct ebt_table_info *)
1137 vmalloc(sizeof(struct ebt_table_info) + countersize); 1144 vmalloc(sizeof(struct ebt_table_info) + countersize);
1138 ret = -ENOMEM; 1145 ret = -ENOMEM;
@@ -1186,7 +1193,7 @@ free_unlock:
1186 up(&ebt_mutex); 1193 up(&ebt_mutex);
1187free_chainstack: 1194free_chainstack:
1188 if (newinfo->chainstack) { 1195 if (newinfo->chainstack) {
1189 for (i = 0; i < num_possible_cpus(); i++) 1196 for_each_cpu(i)
1190 vfree(newinfo->chainstack[i]); 1197 vfree(newinfo->chainstack[i]);
1191 vfree(newinfo->chainstack); 1198 vfree(newinfo->chainstack);
1192 } 1199 }
@@ -1209,7 +1216,7 @@ void ebt_unregister_table(struct ebt_table *table)
1209 up(&ebt_mutex); 1216 up(&ebt_mutex);
1210 vfree(table->private->entries); 1217 vfree(table->private->entries);
1211 if (table->private->chainstack) { 1218 if (table->private->chainstack) {
1212 for (i = 0; i < num_possible_cpus(); i++) 1219 for_each_cpu(i)
1213 vfree(table->private->chainstack[i]); 1220 vfree(table->private->chainstack[i]);
1214 vfree(table->private->chainstack); 1221 vfree(table->private->chainstack);
1215 } 1222 }
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 21e55142dcd3..c37eeeaf5c6e 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -110,14 +110,14 @@ static inline int ccid_hc_tx_init(struct ccid *ccid, struct sock *sk)
110 110
111static inline void ccid_hc_rx_exit(struct ccid *ccid, struct sock *sk) 111static inline void ccid_hc_rx_exit(struct ccid *ccid, struct sock *sk)
112{ 112{
113 if (ccid->ccid_hc_rx_exit != NULL && 113 if (ccid != NULL && ccid->ccid_hc_rx_exit != NULL &&
114 dccp_sk(sk)->dccps_hc_rx_ccid_private != NULL) 114 dccp_sk(sk)->dccps_hc_rx_ccid_private != NULL)
115 ccid->ccid_hc_rx_exit(sk); 115 ccid->ccid_hc_rx_exit(sk);
116} 116}
117 117
118static inline void ccid_hc_tx_exit(struct ccid *ccid, struct sock *sk) 118static inline void ccid_hc_tx_exit(struct ccid *ccid, struct sock *sk)
119{ 119{
120 if (ccid->ccid_hc_tx_exit != NULL && 120 if (ccid != NULL && ccid->ccid_hc_tx_exit != NULL &&
121 dccp_sk(sk)->dccps_hc_tx_ccid_private != NULL) 121 dccp_sk(sk)->dccps_hc_tx_ccid_private != NULL)
122 ccid->ccid_hc_tx_exit(sk); 122 ccid->ccid_hc_tx_exit(sk);
123} 123}
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 1b6b2cb12376..3454d5941900 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -375,6 +375,9 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
375 case DCCP_PKT_RESET: 375 case DCCP_PKT_RESET:
376 inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 376 inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
377 break; 377 break;
378 case DCCP_PKT_DATA:
379 if (sk->sk_state == DCCP_RESPOND)
380 break;
378 case DCCP_PKT_DATAACK: 381 case DCCP_PKT_DATAACK:
379 case DCCP_PKT_ACK: 382 case DCCP_PKT_ACK:
380 /* 383 /*
@@ -393,7 +396,8 @@ static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
393 dccp_sk(sk)->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq; 396 dccp_sk(sk)->dccps_osr = DCCP_SKB_CB(skb)->dccpd_seq;
394 dccp_set_state(sk, DCCP_OPEN); 397 dccp_set_state(sk, DCCP_OPEN);
395 398
396 if (dh->dccph_type == DCCP_PKT_DATAACK) { 399 if (dh->dccph_type == DCCP_PKT_DATAACK ||
400 dh->dccph_type == DCCP_PKT_DATA) {
397 dccp_rcv_established(sk, skb, dh, len); 401 dccp_rcv_established(sk, skb, dh, len);
398 queued = 1; /* packet was queued 402 queued = 1; /* packet was queued
399 (by dccp_rcv_established) */ 403 (by dccp_rcv_established) */
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 1b5a09d1b90b..1b18ce66e7b7 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -5,6 +5,7 @@
5#include <net/esp.h> 5#include <net/esp.h>
6#include <asm/scatterlist.h> 6#include <asm/scatterlist.h>
7#include <linux/crypto.h> 7#include <linux/crypto.h>
8#include <linux/kernel.h>
8#include <linux/pfkeyv2.h> 9#include <linux/pfkeyv2.h>
9#include <linux/random.h> 10#include <linux/random.h>
10#include <net/icmp.h> 11#include <net/icmp.h>
@@ -42,10 +43,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
42 esp = x->data; 43 esp = x->data;
43 alen = esp->auth.icv_trunc_len; 44 alen = esp->auth.icv_trunc_len;
44 tfm = esp->conf.tfm; 45 tfm = esp->conf.tfm;
45 blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3; 46 blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4);
46 clen = (clen + 2 + blksize-1)&~(blksize-1); 47 clen = ALIGN(clen + 2, blksize);
47 if (esp->conf.padlen) 48 if (esp->conf.padlen)
48 clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1); 49 clen = ALIGN(clen, esp->conf.padlen);
49 50
50 if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) 51 if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)
51 goto error; 52 goto error;
@@ -143,7 +144,7 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc
143 struct ip_esp_hdr *esph; 144 struct ip_esp_hdr *esph;
144 struct esp_data *esp = x->data; 145 struct esp_data *esp = x->data;
145 struct sk_buff *trailer; 146 struct sk_buff *trailer;
146 int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); 147 int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
147 int alen = esp->auth.icv_trunc_len; 148 int alen = esp->auth.icv_trunc_len;
148 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; 149 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
149 int nfrags; 150 int nfrags;
@@ -304,16 +305,16 @@ static int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap,
304static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) 305static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
305{ 306{
306 struct esp_data *esp = x->data; 307 struct esp_data *esp = x->data;
307 u32 blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); 308 u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
308 309
309 if (x->props.mode) { 310 if (x->props.mode) {
310 mtu = (mtu + 2 + blksize-1)&~(blksize-1); 311 mtu = ALIGN(mtu + 2, blksize);
311 } else { 312 } else {
312 /* The worst case. */ 313 /* The worst case. */
313 mtu += 2 + blksize; 314 mtu = ALIGN(mtu + 2, 4) + blksize - 4;
314 } 315 }
315 if (esp->conf.padlen) 316 if (esp->conf.padlen)
316 mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1); 317 mtu = ALIGN(mtu, esp->conf.padlen);
317 318
318 return mtu + x->props.header_len + esp->auth.icv_trunc_len; 319 return mtu + x->props.header_len + esp->auth.icv_trunc_len;
319} 320}
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index f9076ef3a1a8..a010e9a68811 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -111,6 +111,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
111 tw->tw_prot = sk->sk_prot_creator; 111 tw->tw_prot = sk->sk_prot_creator;
112 atomic_set(&tw->tw_refcnt, 1); 112 atomic_set(&tw->tw_refcnt, 1);
113 inet_twsk_dead_node_init(tw); 113 inet_twsk_dead_node_init(tw);
114 __module_get(tw->tw_prot->owner);
114 } 115 }
115 116
116 return tw; 117 return tw;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index a7659728e7a0..7d917e4ce1d9 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -139,6 +139,7 @@ config IP_NF_AMANDA
139 139
140config IP_NF_PPTP 140config IP_NF_PPTP
141 tristate 'PPTP protocol support' 141 tristate 'PPTP protocol support'
142 depends on IP_NF_CONNTRACK
142 help 143 help
143 This module adds support for PPTP (Point to Point Tunnelling 144 This module adds support for PPTP (Point to Point Tunnelling
144 Protocol, RFC2637) connection tracking and NAT. 145 Protocol, RFC2637) connection tracking and NAT.
@@ -498,9 +499,14 @@ config IP_NF_TARGET_LOG
498 To compile it as a module, choose M here. If unsure, say N. 499 To compile it as a module, choose M here. If unsure, say N.
499 500
500config IP_NF_TARGET_ULOG 501config IP_NF_TARGET_ULOG
501 tristate "ULOG target support" 502 tristate "ULOG target support (OBSOLETE)"
502 depends on IP_NF_IPTABLES 503 depends on IP_NF_IPTABLES
503 ---help--- 504 ---help---
505
506 This option enables the old IPv4-only "ipt_ULOG" implementation
507 which has been obsoleted by the new "nfnetlink_log" code (see
508 CONFIG_NETFILTER_NETLINK_LOG).
509
504 This option adds a `ULOG' target, which allows you to create rules in 510 This option adds a `ULOG' target, which allows you to create rules in
505 any iptables table. The packet is passed to a userspace logging 511 any iptables table. The packet is passed to a userspace logging
506 daemon using netlink multicast sockets; unlike the LOG target 512 daemon using netlink multicast sockets; unlike the LOG target
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index fa1634256680..a7969286e6e7 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -716,8 +716,10 @@ static int translate_table(const char *name,
716 } 716 }
717 717
718 /* And one copy for every other CPU */ 718 /* And one copy for every other CPU */
719 for (i = 1; i < num_possible_cpus(); i++) { 719 for_each_cpu(i) {
720 memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i, 720 if (i == 0)
721 continue;
722 memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
721 newinfo->entries, 723 newinfo->entries,
722 SMP_ALIGN(newinfo->size)); 724 SMP_ALIGN(newinfo->size));
723 } 725 }
@@ -767,7 +769,7 @@ static void get_counters(const struct arpt_table_info *t,
767 unsigned int cpu; 769 unsigned int cpu;
768 unsigned int i; 770 unsigned int i;
769 771
770 for (cpu = 0; cpu < num_possible_cpus(); cpu++) { 772 for_each_cpu(cpu) {
771 i = 0; 773 i = 0;
772 ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), 774 ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
773 t->size, 775 t->size,
@@ -885,7 +887,8 @@ static int do_replace(void __user *user, unsigned int len)
885 return -ENOMEM; 887 return -ENOMEM;
886 888
887 newinfo = vmalloc(sizeof(struct arpt_table_info) 889 newinfo = vmalloc(sizeof(struct arpt_table_info)
888 + SMP_ALIGN(tmp.size) * num_possible_cpus()); 890 + SMP_ALIGN(tmp.size) *
891 (highest_possible_processor_id()+1));
889 if (!newinfo) 892 if (!newinfo)
890 return -ENOMEM; 893 return -ENOMEM;
891 894
@@ -1158,7 +1161,8 @@ int arpt_register_table(struct arpt_table *table,
1158 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1161 = { 0, 0, 0, { 0 }, { 0 }, { } };
1159 1162
1160 newinfo = vmalloc(sizeof(struct arpt_table_info) 1163 newinfo = vmalloc(sizeof(struct arpt_table_info)
1161 + SMP_ALIGN(repl->size) * num_possible_cpus()); 1164 + SMP_ALIGN(repl->size) *
1165 (highest_possible_processor_id()+1));
1162 if (!newinfo) { 1166 if (!newinfo) {
1163 ret = -ENOMEM; 1167 ret = -ENOMEM;
1164 return ret; 1168 return ret;
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index ea65dd3e517a..07a80b56e8dc 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -1119,7 +1119,7 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
1119 unsigned long extra_jiffies, 1119 unsigned long extra_jiffies,
1120 int do_acct) 1120 int do_acct)
1121{ 1121{
1122 int do_event = 0; 1122 int event = 0;
1123 1123
1124 IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct); 1124 IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
1125 IP_NF_ASSERT(skb); 1125 IP_NF_ASSERT(skb);
@@ -1129,13 +1129,13 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
1129 /* If not in hash table, timer will not be active yet */ 1129 /* If not in hash table, timer will not be active yet */
1130 if (!is_confirmed(ct)) { 1130 if (!is_confirmed(ct)) {
1131 ct->timeout.expires = extra_jiffies; 1131 ct->timeout.expires = extra_jiffies;
1132 do_event = 1; 1132 event = IPCT_REFRESH;
1133 } else { 1133 } else {
1134 /* Need del_timer for race avoidance (may already be dying). */ 1134 /* Need del_timer for race avoidance (may already be dying). */
1135 if (del_timer(&ct->timeout)) { 1135 if (del_timer(&ct->timeout)) {
1136 ct->timeout.expires = jiffies + extra_jiffies; 1136 ct->timeout.expires = jiffies + extra_jiffies;
1137 add_timer(&ct->timeout); 1137 add_timer(&ct->timeout);
1138 do_event = 1; 1138 event = IPCT_REFRESH;
1139 } 1139 }
1140 } 1140 }
1141 1141
@@ -1144,14 +1144,17 @@ void __ip_ct_refresh_acct(struct ip_conntrack *ct,
1144 ct->counters[CTINFO2DIR(ctinfo)].packets++; 1144 ct->counters[CTINFO2DIR(ctinfo)].packets++;
1145 ct->counters[CTINFO2DIR(ctinfo)].bytes += 1145 ct->counters[CTINFO2DIR(ctinfo)].bytes +=
1146 ntohs(skb->nh.iph->tot_len); 1146 ntohs(skb->nh.iph->tot_len);
1147 if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
1148 || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
1149 event |= IPCT_COUNTER_FILLING;
1147 } 1150 }
1148#endif 1151#endif
1149 1152
1150 write_unlock_bh(&ip_conntrack_lock); 1153 write_unlock_bh(&ip_conntrack_lock);
1151 1154
1152 /* must be unlocked when calling event cache */ 1155 /* must be unlocked when calling event cache */
1153 if (do_event) 1156 if (event)
1154 ip_conntrack_event_cache(IPCT_REFRESH, skb); 1157 ip_conntrack_event_cache(event, skb);
1155} 1158}
1156 1159
1157#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ 1160#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index b08a432efcf8..166e6069f121 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -177,11 +177,11 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct ip_conntrack *ct,
177 struct nfattr *nest_count = NFA_NEST(skb, type); 177 struct nfattr *nest_count = NFA_NEST(skb, type);
178 u_int64_t tmp; 178 u_int64_t tmp;
179 179
180 tmp = cpu_to_be64(ct->counters[dir].packets); 180 tmp = htonl(ct->counters[dir].packets);
181 NFA_PUT(skb, CTA_COUNTERS_PACKETS, sizeof(u_int64_t), &tmp); 181 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
182 182
183 tmp = cpu_to_be64(ct->counters[dir].bytes); 183 tmp = htonl(ct->counters[dir].bytes);
184 NFA_PUT(skb, CTA_COUNTERS_BYTES, sizeof(u_int64_t), &tmp); 184 NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
185 185
186 NFA_NEST_END(skb, nest_count); 186 NFA_NEST_END(skb, nest_count);
187 187
@@ -833,7 +833,8 @@ out:
833static inline int 833static inline int
834ctnetlink_change_status(struct ip_conntrack *ct, struct nfattr *cda[]) 834ctnetlink_change_status(struct ip_conntrack *ct, struct nfattr *cda[])
835{ 835{
836 unsigned long d, status = *(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]); 836 unsigned long d;
837 unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
837 d = ct->status ^ status; 838 d = ct->status ^ status;
838 839
839 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING)) 840 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
@@ -948,6 +949,31 @@ ctnetlink_change_timeout(struct ip_conntrack *ct, struct nfattr *cda[])
948 return 0; 949 return 0;
949} 950}
950 951
952static inline int
953ctnetlink_change_protoinfo(struct ip_conntrack *ct, struct nfattr *cda[])
954{
955 struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1];
956 struct ip_conntrack_protocol *proto;
957 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
958 int err = 0;
959
960 if (nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr) < 0)
961 goto nfattr_failure;
962
963 proto = ip_conntrack_proto_find_get(npt);
964 if (!proto)
965 return -EINVAL;
966
967 if (proto->from_nfattr)
968 err = proto->from_nfattr(tb, ct);
969 ip_conntrack_proto_put(proto);
970
971 return err;
972
973nfattr_failure:
974 return -ENOMEM;
975}
976
951static int 977static int
952ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[]) 978ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
953{ 979{
@@ -973,6 +999,12 @@ ctnetlink_change_conntrack(struct ip_conntrack *ct, struct nfattr *cda[])
973 return err; 999 return err;
974 } 1000 }
975 1001
1002 if (cda[CTA_PROTOINFO-1]) {
1003 err = ctnetlink_change_protoinfo(ct, cda);
1004 if (err < 0)
1005 return err;
1006 }
1007
976 DEBUGP("all done\n"); 1008 DEBUGP("all done\n");
977 return 0; 1009 return 0;
978} 1010}
@@ -1002,6 +1034,12 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
1002 if (err < 0) 1034 if (err < 0)
1003 goto err; 1035 goto err;
1004 1036
1037 if (cda[CTA_PROTOINFO-1]) {
1038 err = ctnetlink_change_protoinfo(ct, cda);
1039 if (err < 0)
1040 return err;
1041 }
1042
1005 ct->helper = ip_conntrack_helper_find_get(rtuple); 1043 ct->helper = ip_conntrack_helper_find_get(rtuple);
1006 1044
1007 add_timer(&ct->timeout); 1045 add_timer(&ct->timeout);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 838d1d69b36e..98f0015dd255 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -296,8 +296,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
296 struct ip_conntrack_tuple *tuple) 296 struct ip_conntrack_tuple *tuple)
297{ 297{
298 if (!tb[CTA_PROTO_ICMP_TYPE-1] 298 if (!tb[CTA_PROTO_ICMP_TYPE-1]
299 || !tb[CTA_PROTO_ICMP_CODE-1] 299 || !tb[CTA_PROTO_ICMP_CODE-1])
300 || !tb[CTA_PROTO_ICMP_ID-1])
301 return -1; 300 return -1;
302 301
303 tuple->dst.u.icmp.type = 302 tuple->dst.u.icmp.type =
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 121760d6cc50..d6701cafbcc2 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -341,17 +341,43 @@ static int tcp_print_conntrack(struct seq_file *s,
341static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa, 341static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
342 const struct ip_conntrack *ct) 342 const struct ip_conntrack *ct)
343{ 343{
344 struct nfattr *nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
345
344 read_lock_bh(&tcp_lock); 346 read_lock_bh(&tcp_lock);
345 NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t), 347 NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
346 &ct->proto.tcp.state); 348 &ct->proto.tcp.state);
347 read_unlock_bh(&tcp_lock); 349 read_unlock_bh(&tcp_lock);
348 350
351 NFA_NEST_END(skb, nest_parms);
352
349 return 0; 353 return 0;
350 354
351nfattr_failure: 355nfattr_failure:
352 read_unlock_bh(&tcp_lock); 356 read_unlock_bh(&tcp_lock);
353 return -1; 357 return -1;
354} 358}
359
360static int nfattr_to_tcp(struct nfattr *cda[], struct ip_conntrack *ct)
361{
362 struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
363 struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
364
365 if (nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr) < 0)
366 goto nfattr_failure;
367
368 if (!tb[CTA_PROTOINFO_TCP_STATE-1])
369 return -EINVAL;
370
371 write_lock_bh(&tcp_lock);
372 ct->proto.tcp.state =
373 *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
374 write_unlock_bh(&tcp_lock);
375
376 return 0;
377
378nfattr_failure:
379 return -1;
380}
355#endif 381#endif
356 382
357static unsigned int get_conntrack_index(const struct tcphdr *tcph) 383static unsigned int get_conntrack_index(const struct tcphdr *tcph)
@@ -1123,6 +1149,7 @@ struct ip_conntrack_protocol ip_conntrack_protocol_tcp =
1123#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \ 1149#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
1124 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE) 1150 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
1125 .to_nfattr = tcp_to_nfattr, 1151 .to_nfattr = tcp_to_nfattr,
1152 .from_nfattr = nfattr_to_tcp,
1126 .tuple_to_nfattr = ip_ct_port_tuple_to_nfattr, 1153 .tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,
1127 .nfattr_to_tuple = ip_ct_port_nfattr_to_tuple, 1154 .nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,
1128#endif 1155#endif
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index eef99a1b5de6..75c27e92f6ab 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -27,6 +27,7 @@
27#include <asm/semaphore.h> 27#include <asm/semaphore.h>
28#include <linux/proc_fs.h> 28#include <linux/proc_fs.h>
29#include <linux/err.h> 29#include <linux/err.h>
30#include <linux/cpumask.h>
30 31
31#include <linux/netfilter_ipv4/ip_tables.h> 32#include <linux/netfilter_ipv4/ip_tables.h>
32 33
@@ -921,8 +922,10 @@ translate_table(const char *name,
921 } 922 }
922 923
923 /* And one copy for every other CPU */ 924 /* And one copy for every other CPU */
924 for (i = 1; i < num_possible_cpus(); i++) { 925 for_each_cpu(i) {
925 memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i, 926 if (i == 0)
927 continue;
928 memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
926 newinfo->entries, 929 newinfo->entries,
927 SMP_ALIGN(newinfo->size)); 930 SMP_ALIGN(newinfo->size));
928 } 931 }
@@ -943,7 +946,7 @@ replace_table(struct ipt_table *table,
943 struct ipt_entry *table_base; 946 struct ipt_entry *table_base;
944 unsigned int i; 947 unsigned int i;
945 948
946 for (i = 0; i < num_possible_cpus(); i++) { 949 for_each_cpu(i) {
947 table_base = 950 table_base =
948 (void *)newinfo->entries 951 (void *)newinfo->entries
949 + TABLE_OFFSET(newinfo, i); 952 + TABLE_OFFSET(newinfo, i);
@@ -990,7 +993,7 @@ get_counters(const struct ipt_table_info *t,
990 unsigned int cpu; 993 unsigned int cpu;
991 unsigned int i; 994 unsigned int i;
992 995
993 for (cpu = 0; cpu < num_possible_cpus(); cpu++) { 996 for_each_cpu(cpu) {
994 i = 0; 997 i = 0;
995 IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), 998 IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
996 t->size, 999 t->size,
@@ -1128,7 +1131,8 @@ do_replace(void __user *user, unsigned int len)
1128 return -ENOMEM; 1131 return -ENOMEM;
1129 1132
1130 newinfo = vmalloc(sizeof(struct ipt_table_info) 1133 newinfo = vmalloc(sizeof(struct ipt_table_info)
1131 + SMP_ALIGN(tmp.size) * num_possible_cpus()); 1134 + SMP_ALIGN(tmp.size) *
1135 (highest_possible_processor_id()+1));
1132 if (!newinfo) 1136 if (!newinfo)
1133 return -ENOMEM; 1137 return -ENOMEM;
1134 1138
@@ -1458,7 +1462,8 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl)
1458 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1462 = { 0, 0, 0, { 0 }, { 0 }, { } };
1459 1463
1460 newinfo = vmalloc(sizeof(struct ipt_table_info) 1464 newinfo = vmalloc(sizeof(struct ipt_table_info)
1461 + SMP_ALIGN(repl->size) * num_possible_cpus()); 1465 + SMP_ALIGN(repl->size) *
1466 (highest_possible_processor_id()+1));
1462 if (!newinfo) 1467 if (!newinfo)
1463 return -ENOMEM; 1468 return -ENOMEM;
1464 1469
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 8225e4257258..7114031fdc70 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -435,7 +435,16 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
435 int nsize, old_factor; 435 int nsize, old_factor;
436 u16 flags; 436 u16 flags;
437 437
438 BUG_ON(len >= skb->len); 438 if (unlikely(len >= skb->len)) {
439 if (net_ratelimit()) {
440 printk(KERN_DEBUG "TCP: seg_size=%u, mss=%u, seq=%u, "
441 "end_seq=%u, skb->len=%u.\n", len, mss_now,
442 TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
443 skb->len);
444 WARN_ON(1);
445 }
446 return 0;
447 }
439 448
440 nsize = skb_headlen(skb) - len; 449 nsize = skb_headlen(skb) - len;
441 if (nsize < 0) 450 if (nsize < 0)
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 9b27460f0cc7..40d9a1935ab5 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -31,6 +31,7 @@
31#include <net/esp.h> 31#include <net/esp.h>
32#include <asm/scatterlist.h> 32#include <asm/scatterlist.h>
33#include <linux/crypto.h> 33#include <linux/crypto.h>
34#include <linux/kernel.h>
34#include <linux/pfkeyv2.h> 35#include <linux/pfkeyv2.h>
35#include <linux/random.h> 36#include <linux/random.h>
36#include <net/icmp.h> 37#include <net/icmp.h>
@@ -66,10 +67,10 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
66 67
67 alen = esp->auth.icv_trunc_len; 68 alen = esp->auth.icv_trunc_len;
68 tfm = esp->conf.tfm; 69 tfm = esp->conf.tfm;
69 blksize = (crypto_tfm_alg_blocksize(tfm) + 3) & ~3; 70 blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4);
70 clen = (clen + 2 + blksize-1)&~(blksize-1); 71 clen = ALIGN(clen + 2, blksize);
71 if (esp->conf.padlen) 72 if (esp->conf.padlen)
72 clen = (clen + esp->conf.padlen-1)&~(esp->conf.padlen-1); 73 clen = ALIGN(clen, esp->conf.padlen);
73 74
74 if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) { 75 if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) {
75 goto error; 76 goto error;
@@ -133,7 +134,7 @@ static int esp6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, stru
133 struct ipv6_esp_hdr *esph; 134 struct ipv6_esp_hdr *esph;
134 struct esp_data *esp = x->data; 135 struct esp_data *esp = x->data;
135 struct sk_buff *trailer; 136 struct sk_buff *trailer;
136 int blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); 137 int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
137 int alen = esp->auth.icv_trunc_len; 138 int alen = esp->auth.icv_trunc_len;
138 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; 139 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen;
139 140
@@ -235,16 +236,17 @@ out_nofree:
235static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) 236static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
236{ 237{
237 struct esp_data *esp = x->data; 238 struct esp_data *esp = x->data;
238 u32 blksize = crypto_tfm_alg_blocksize(esp->conf.tfm); 239 u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);
239 240
240 if (x->props.mode) { 241 if (x->props.mode) {
241 mtu = (mtu + 2 + blksize-1)&~(blksize-1); 242 mtu = ALIGN(mtu + 2, blksize);
242 } else { 243 } else {
243 /* The worst case. */ 244 /* The worst case. */
244 mtu += 2 + blksize; 245 u32 padsize = ((blksize - 1) & 7) + 1;
246 mtu = ALIGN(mtu + 2, padsize) + blksize - padsize;
245 } 247 }
246 if (esp->conf.padlen) 248 if (esp->conf.padlen)
247 mtu = (mtu + esp->conf.padlen-1)&~(esp->conf.padlen-1); 249 mtu = ALIGN(mtu, esp->conf.padlen);
248 250
249 return mtu + x->props.header_len + esp->auth.icv_full_len; 251 return mtu + x->props.header_len + esp->auth.icv_full_len;
250} 252}
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 2da514b16d95..b03e90649eb5 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -28,6 +28,7 @@
28#include <asm/uaccess.h> 28#include <asm/uaccess.h>
29#include <asm/semaphore.h> 29#include <asm/semaphore.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/cpumask.h>
31 32
32#include <linux/netfilter_ipv6/ip6_tables.h> 33#include <linux/netfilter_ipv6/ip6_tables.h>
33 34
@@ -950,8 +951,10 @@ translate_table(const char *name,
950 } 951 }
951 952
952 /* And one copy for every other CPU */ 953 /* And one copy for every other CPU */
953 for (i = 1; i < num_possible_cpus(); i++) { 954 for_each_cpu(i) {
954 memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i, 955 if (i == 0)
956 continue;
957 memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
955 newinfo->entries, 958 newinfo->entries,
956 SMP_ALIGN(newinfo->size)); 959 SMP_ALIGN(newinfo->size));
957 } 960 }
@@ -973,6 +976,7 @@ replace_table(struct ip6t_table *table,
973 unsigned int i; 976 unsigned int i;
974 977
975 for (i = 0; i < num_possible_cpus(); i++) { 978 for (i = 0; i < num_possible_cpus(); i++) {
979 for_each_cpu(i) {
976 table_base = 980 table_base =
977 (void *)newinfo->entries 981 (void *)newinfo->entries
978 + TABLE_OFFSET(newinfo, i); 982 + TABLE_OFFSET(newinfo, i);
@@ -1019,7 +1023,7 @@ get_counters(const struct ip6t_table_info *t,
1019 unsigned int cpu; 1023 unsigned int cpu;
1020 unsigned int i; 1024 unsigned int i;
1021 1025
1022 for (cpu = 0; cpu < num_possible_cpus(); cpu++) { 1026 for_each_cpu(cpu) {
1023 i = 0; 1027 i = 0;
1024 IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu), 1028 IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
1025 t->size, 1029 t->size,
@@ -1153,7 +1157,8 @@ do_replace(void __user *user, unsigned int len)
1153 return -ENOMEM; 1157 return -ENOMEM;
1154 1158
1155 newinfo = vmalloc(sizeof(struct ip6t_table_info) 1159 newinfo = vmalloc(sizeof(struct ip6t_table_info)
1156 + SMP_ALIGN(tmp.size) * num_possible_cpus()); 1160 + SMP_ALIGN(tmp.size) *
1161 (highest_possible_processor_id()+1));
1157 if (!newinfo) 1162 if (!newinfo)
1158 return -ENOMEM; 1163 return -ENOMEM;
1159 1164
@@ -1467,7 +1472,8 @@ int ip6t_register_table(struct ip6t_table *table,
1467 = { 0, 0, 0, { 0 }, { 0 }, { } }; 1472 = { 0, 0, 0, { 0 }, { 0 }, { } };
1468 1473
1469 newinfo = vmalloc(sizeof(struct ip6t_table_info) 1474 newinfo = vmalloc(sizeof(struct ip6t_table_info)
1470 + SMP_ALIGN(repl->size) * num_possible_cpus()); 1475 + SMP_ALIGN(repl->size) *
1476 (highest_possible_processor_id()+1));
1471 if (!newinfo) 1477 if (!newinfo)
1472 return -ENOMEM; 1478 return -ENOMEM;
1473 1479
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 1caaca06f698..4bc27a6334c1 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -133,7 +133,7 @@ int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
133 memset(tb, 0, sizeof(struct nfattr *) * maxattr); 133 memset(tb, 0, sizeof(struct nfattr *) * maxattr);
134 134
135 while (NFA_OK(nfa, len)) { 135 while (NFA_OK(nfa, len)) {
136 unsigned flavor = nfa->nfa_type; 136 unsigned flavor = NFA_TYPE(nfa);
137 if (flavor && flavor <= maxattr) 137 if (flavor && flavor <= maxattr)
138 tb[flavor-1] = nfa; 138 tb[flavor-1] = nfa;
139 nfa = NFA_NEXT(nfa, len); 139 nfa = NFA_NEXT(nfa, len);
@@ -177,7 +177,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
177 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); 177 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
178 178
179 while (NFA_OK(attr, attrlen)) { 179 while (NFA_OK(attr, attrlen)) {
180 unsigned flavor = attr->nfa_type; 180 unsigned flavor = NFA_TYPE(attr);
181 if (flavor) { 181 if (flavor) {
182 if (flavor > attr_count) 182 if (flavor > attr_count)
183 return -EINVAL; 183 return -EINVAL;
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 45d3bc0812c8..81510da31792 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -72,9 +72,11 @@ config NET_SCH_CLK_GETTIMEOFDAY
72 Choose this if you need a high resolution clock source but can't use 72 Choose this if you need a high resolution clock source but can't use
73 the CPU's cycle counter. 73 the CPU's cycle counter.
74 74
75# don't allow on SMP x86 because they can have unsynchronized TSCs.
76# gettimeofday is a good alternative
75config NET_SCH_CLK_CPU 77config NET_SCH_CLK_CPU
76 bool "CPU cycle counter" 78 bool "CPU cycle counter"
77 depends on X86_TSC || X86_64 || ALPHA || SPARC64 || PPC64 || IA64 79 depends on ((X86_TSC || X86_64) && !SMP) || ALPHA || SPARC64 || PPC64 || IA64
78 help 80 help
79 Say Y here if you want to use the CPU's cycle counter as clock source. 81 Say Y here if you want to use the CPU's cycle counter as clock source.
80 This is a cheap and high resolution clock source, but on some 82 This is a cheap and high resolution clock source, but on some