aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c2
-rw-r--r--arch/i386/mach-voyager/voyager_basic.c6
-rw-r--r--arch/i386/mach-voyager/voyager_smp.c52
-rw-r--r--arch/sh/Kconfig4
-rw-r--r--arch/sh/boards/hp6xx/hp6xx_apm.c4
-rw-r--r--arch/sh/boards/landisk/landisk_pwb.c2
-rw-r--r--arch/sh/boards/mpc1211/setup.c5
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq.c105
-rw-r--r--arch/sh/boards/snapgear/setup.c2
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/setup.c2
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/gpio.c2
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/setup.c2
-rw-r--r--arch/sh/cchips/voyagergx/irq.c3
-rw-r--r--arch/sh/drivers/dma/dma-g2.c2
-rw-r--r--arch/sh/drivers/dma/dma-pvr2.c2
-rw-r--r--arch/sh/drivers/dma/dma-sh.c6
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c4
-rw-r--r--arch/sh/drivers/pci/pci-st40.c2
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c138
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c102
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S195
-rw-r--r--arch/sh/kernel/cpu/sh4/ex.S500
-rw-r--r--arch/sh/kernel/entry.S43
-rw-r--r--arch/sh/kernel/irq.c42
-rw-r--r--arch/sh/kernel/process.c30
-rw-r--r--arch/sh/kernel/time.c9
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c63
-rw-r--r--arch/sh/mm/consistent.c1
-rw-r--r--arch/sparc/kernel/pcic.c1
-rw-r--r--arch/sparc/kernel/setup.c10
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S4
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc64/kernel/setup.c10
-rw-r--r--arch/x86_64/kernel/io_apic.c2
-rw-r--r--arch/x86_64/kernel/vsmp.c1
-rw-r--r--block/elevator.c17
-rw-r--r--drivers/ide/ide-cd.c7
-rw-r--r--drivers/rtc/rtc-sh.c6
-rw-r--r--drivers/sbus/char/bbc_envctrl.c4
-rw-r--r--drivers/sbus/char/envctrl.c8
-rw-r--r--drivers/serial/sh-sci.c4
-rw-r--r--drivers/serial/sunzilog.c6
-rw-r--r--fs/Kconfig2
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/cifs/cifsacl.h4
-rw-r--r--fs/cifs/cifsencrypt.h2
-rw-r--r--fs/cifs/cifsfs.c27
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h15
-rw-r--r--fs/cifs/cifspdu.h12
-rw-r--r--fs/cifs/cifsproto.h12
-rw-r--r--fs/cifs/cifssmb.c96
-rw-r--r--fs/cifs/connect.c35
-rw-r--r--fs/cifs/inode.c12
-rw-r--r--fs/cifs/link.c6
-rw-r--r--fs/cifs/md5.c8
-rw-r--r--fs/cifs/md5.h8
-rw-r--r--fs/cifs/misc.c44
-rw-r--r--fs/cifs/netmisc.c58
-rw-r--r--fs/cifs/readdir.c27
-rw-r--r--fs/cifs/sess.c23
-rw-r--r--fs/cifs/smbdes.c6
-rw-r--r--fs/cifs/smbencrypt.c11
-rw-r--r--fs/ioprio.c5
-rw-r--r--fs/splice.c6
-rw-r--r--include/asm-i386/vic.h2
-rw-r--r--include/asm-i386/voyager.h160
-rw-r--r--include/asm-sh/cpu-sh4/ubc.h37
-rw-r--r--include/asm-sh/hw_irq.h4
-rw-r--r--include/asm-sh/irq.h14
-rw-r--r--include/asm-sh/irq_regs.h1
-rw-r--r--include/asm-sh/timer.h13
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/elevator.h1
-rw-r--r--include/linux/security.h24
-rw-r--r--include/net/flow.h2
-rw-r--r--include/net/inet_timewait_sock.h1
-rw-r--r--include/net/netlabel.h62
-rw-r--r--include/net/sctp/sctp.h14
-rw-r--r--include/net/sctp/ulpevent.h1
-rw-r--r--include/net/timewait_sock.h7
-rw-r--r--include/net/xfrm.h3
-rw-r--r--net/compat.c3
-rw-r--r--net/core/flow.c42
-rw-r--r--net/core/rtnetlink.c2
-rw-r--r--net/core/scm.c3
-rw-r--r--net/dccp/ipv4.c6
-rw-r--r--net/dccp/ipv6.c6
-rw-r--r--net/decnet/af_decnet.c4
-rw-r--r--net/decnet/dn_route.c11
-rw-r--r--net/ipv4/cipso_ipv4.c18
-rw-r--r--net/ipv4/ip_gre.c4
-rw-r--r--net/ipv4/route.c12
-rw-r--r--net/ipv4/tcp_ipv4.c18
-rw-r--r--net/ipv4/tcp_output.c31
-rw-r--r--net/ipv4/xfrm4_policy.c2
-rw-r--r--net/ipv6/Kconfig13
-rw-r--r--net/ipv6/Makefile3
-rw-r--r--net/ipv6/addrconf.c18
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/sit.c3
-rw-r--r--net/ipv6/tcp_ipv6.c13
-rw-r--r--net/ipv6/xfrm6_policy.c2
-rw-r--r--net/key/af_key.c5
-rw-r--r--net/netlabel/netlabel_kapi.c2
-rw-r--r--net/sched/sch_htb.c5
-rw-r--r--net/sctp/proc.c2
-rw-r--r--net/sctp/socket.c22
-rw-r--r--net/sctp/ulpevent.c25
-rw-r--r--net/sctp/ulpqueue.c2
-rw-r--r--net/xfrm/xfrm_policy.c101
-rw-r--r--net/xfrm/xfrm_user.c9
-rw-r--r--security/dummy.c3
-rw-r--r--security/selinux/include/xfrm.h3
-rw-r--r--security/selinux/ss/policydb.c2
-rw-r--r--security/selinux/ss/services.c66
-rw-r--r--security/selinux/xfrm.c53
117 files changed, 1114 insertions, 1584 deletions
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 692809e4aece..e9762a33b043 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -12,7 +12,7 @@
12#include <asm/fpu.h> 12#include <asm/fpu.h>
13#include <asm/machvec.h> 13#include <asm/machvec.h>
14 14
15#include <asm/unistd.h> 15#include <linux/syscalls.h>
16 16
17/* these are C runtime functions with special calling conventions: */ 17/* these are C runtime functions with special calling conventions: */
18extern void __divl (void); 18extern void __divl (void);
diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c
index c639d30d8bdc..8fe7e4593d5f 100644
--- a/arch/i386/mach-voyager/voyager_basic.c
+++ b/arch/i386/mach-voyager/voyager_basic.c
@@ -44,7 +44,7 @@ struct voyager_SUS *voyager_SUS = NULL;
44 44
45#ifdef CONFIG_SMP 45#ifdef CONFIG_SMP
46static void 46static void
47voyager_dump(int dummy1, struct pt_regs *dummy2, struct tty_struct *dummy3) 47voyager_dump(int dummy1, struct tty_struct *dummy3)
48{ 48{
49 /* get here via a sysrq */ 49 /* get here via a sysrq */
50 voyager_smp_dump(); 50 voyager_smp_dump();
@@ -166,7 +166,7 @@ voyager_memory_detect(int region, __u32 *start, __u32 *length)
166 * off the timer tick to the SMP code, since the VIC doesn't have an 166 * off the timer tick to the SMP code, since the VIC doesn't have an
167 * internal timer (The QIC does, but that's another story). */ 167 * internal timer (The QIC does, but that's another story). */
168void 168void
169voyager_timer_interrupt(struct pt_regs *regs) 169voyager_timer_interrupt(void)
170{ 170{
171 if((jiffies & 0x3ff) == 0) { 171 if((jiffies & 0x3ff) == 0) {
172 172
@@ -202,7 +202,7 @@ voyager_timer_interrupt(struct pt_regs *regs)
202 } 202 }
203 } 203 }
204#ifdef CONFIG_SMP 204#ifdef CONFIG_SMP
205 smp_vic_timer_interrupt(regs); 205 smp_vic_timer_interrupt();
206#endif 206#endif
207} 207}
208 208
diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
index d42422fc4af3..f3fea2ad50fe 100644
--- a/arch/i386/mach-voyager/voyager_smp.c
+++ b/arch/i386/mach-voyager/voyager_smp.c
@@ -85,8 +85,8 @@ static int ack_QIC_CPI(__u8 cpi);
85static void ack_special_QIC_CPI(__u8 cpi); 85static void ack_special_QIC_CPI(__u8 cpi);
86static void ack_VIC_CPI(__u8 cpi); 86static void ack_VIC_CPI(__u8 cpi);
87static void send_CPI_allbutself(__u8 cpi); 87static void send_CPI_allbutself(__u8 cpi);
88static void enable_vic_irq(unsigned int irq); 88static void mask_vic_irq(unsigned int irq);
89static void disable_vic_irq(unsigned int irq); 89static void unmask_vic_irq(unsigned int irq);
90static unsigned int startup_vic_irq(unsigned int irq); 90static unsigned int startup_vic_irq(unsigned int irq);
91static void enable_local_vic_irq(unsigned int irq); 91static void enable_local_vic_irq(unsigned int irq);
92static void disable_local_vic_irq(unsigned int irq); 92static void disable_local_vic_irq(unsigned int irq);
@@ -205,15 +205,12 @@ ack_CPI(__u8 cpi)
205/* The VIC IRQ descriptors -- these look almost identical to the 205/* The VIC IRQ descriptors -- these look almost identical to the
206 * 8259 IRQs except that masks and things must be kept per processor 206 * 8259 IRQs except that masks and things must be kept per processor
207 */ 207 */
208static struct hw_interrupt_type vic_irq_type = { 208static struct irq_chip vic_chip = {
209 .typename = "VIC-level", 209 .name = "VIC",
210 .startup = startup_vic_irq, 210 .startup = startup_vic_irq,
211 .shutdown = disable_vic_irq, 211 .mask = mask_vic_irq,
212 .enable = enable_vic_irq, 212 .unmask = unmask_vic_irq,
213 .disable = disable_vic_irq, 213 .set_affinity = set_vic_irq_affinity,
214 .ack = before_handle_vic_irq,
215 .end = after_handle_vic_irq,
216 .set_affinity = set_vic_irq_affinity,
217}; 214};
218 215
219/* used to count up as CPUs are brought on line (starts at 0) */ 216/* used to count up as CPUs are brought on line (starts at 0) */
@@ -1144,9 +1141,9 @@ smp_apic_timer_interrupt(struct pt_regs *regs)
1144fastcall void 1141fastcall void
1145smp_qic_timer_interrupt(struct pt_regs *regs) 1142smp_qic_timer_interrupt(struct pt_regs *regs)
1146{ 1143{
1147 ack_QIC_CPI(QIC_TIMER_CPI);
1148 struct pt_regs *old_regs = set_irq_regs(regs); 1144 struct pt_regs *old_regs = set_irq_regs(regs);
1149 wrapper_smp_local_timer_interrupt(void); 1145 ack_QIC_CPI(QIC_TIMER_CPI);
1146 wrapper_smp_local_timer_interrupt();
1150 set_irq_regs(old_regs); 1147 set_irq_regs(old_regs);
1151} 1148}
1152 1149
@@ -1270,12 +1267,10 @@ smp_send_stop(void)
1270/* this function is triggered in time.c when a clock tick fires 1267/* this function is triggered in time.c when a clock tick fires
1271 * we need to re-broadcast the tick to all CPUs */ 1268 * we need to re-broadcast the tick to all CPUs */
1272void 1269void
1273smp_vic_timer_interrupt(struct pt_regs *regs) 1270smp_vic_timer_interrupt(void)
1274{ 1271{
1275 struct pt_regs *old_regs = set_irq_regs(regs);
1276 send_CPI_allbutself(VIC_TIMER_CPI); 1272 send_CPI_allbutself(VIC_TIMER_CPI);
1277 smp_local_timer_interrupt(); 1273 smp_local_timer_interrupt();
1278 set_irq_regs(old_regs);
1279} 1274}
1280 1275
1281/* local (per CPU) timer interrupt. It does both profiling and 1276/* local (per CPU) timer interrupt. It does both profiling and
@@ -1310,7 +1305,7 @@ smp_local_timer_interrupt(void)
1310 per_cpu(prof_counter, cpu); 1305 per_cpu(prof_counter, cpu);
1311 } 1306 }
1312 1307
1313 update_process_times(user_mode_vm(irq_regs)); 1308 update_process_times(user_mode_vm(get_irq_regs()));
1314 } 1309 }
1315 1310
1316 if( ((1<<cpu) & voyager_extended_vic_processors) == 0) 1311 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
@@ -1397,6 +1392,17 @@ setup_profiling_timer(unsigned int multiplier)
1397 return 0; 1392 return 0;
1398} 1393}
1399 1394
1395/* This is a bit of a mess, but forced on us by the genirq changes
1396 * there's no genirq handler that really does what voyager wants
1397 * so hack it up with the simple IRQ handler */
1398static void fastcall
1399handle_vic_irq(unsigned int irq, struct irq_desc *desc)
1400{
1401 before_handle_vic_irq(irq);
1402 handle_simple_irq(irq, desc);
1403 after_handle_vic_irq(irq);
1404}
1405
1400 1406
1401/* The CPIs are handled in the per cpu 8259s, so they must be 1407/* The CPIs are handled in the per cpu 8259s, so they must be
1402 * enabled to be received: FIX: enabling the CPIs in the early 1408 * enabled to be received: FIX: enabling the CPIs in the early
@@ -1433,7 +1439,7 @@ smp_intr_init(void)
1433 * This is for later: first 16 correspond to PC IRQs; next 16 1439 * This is for later: first 16 correspond to PC IRQs; next 16
1434 * are Primary MC IRQs and final 16 are Secondary MC IRQs */ 1440 * are Primary MC IRQs and final 16 are Secondary MC IRQs */
1435 for(i = 0; i < 48; i++) 1441 for(i = 0; i < 48; i++)
1436 irq_desc[i].chip = &vic_irq_type; 1442 set_irq_chip_and_handler(i, &vic_chip, handle_vic_irq);
1437} 1443}
1438 1444
1439/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per 1445/* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
@@ -1531,7 +1537,7 @@ ack_VIC_CPI(__u8 cpi)
1531static unsigned int 1537static unsigned int
1532startup_vic_irq(unsigned int irq) 1538startup_vic_irq(unsigned int irq)
1533{ 1539{
1534 enable_vic_irq(irq); 1540 unmask_vic_irq(irq);
1535 1541
1536 return 0; 1542 return 0;
1537} 1543}
@@ -1558,7 +1564,7 @@ startup_vic_irq(unsigned int irq)
1558 * adjust their masks accordingly. */ 1564 * adjust their masks accordingly. */
1559 1565
1560static void 1566static void
1561enable_vic_irq(unsigned int irq) 1567unmask_vic_irq(unsigned int irq)
1562{ 1568{
1563 /* linux doesn't to processor-irq affinity, so enable on 1569 /* linux doesn't to processor-irq affinity, so enable on
1564 * all CPUs we know about */ 1570 * all CPUs we know about */
@@ -1567,7 +1573,7 @@ enable_vic_irq(unsigned int irq)
1567 __u32 processorList = 0; 1573 __u32 processorList = 0;
1568 unsigned long flags; 1574 unsigned long flags;
1569 1575
1570 VDEBUG(("VOYAGER: enable_vic_irq(%d) CPU%d affinity 0x%lx\n", 1576 VDEBUG(("VOYAGER: unmask_vic_irq(%d) CPU%d affinity 0x%lx\n",
1571 irq, cpu, cpu_irq_affinity[cpu])); 1577 irq, cpu, cpu_irq_affinity[cpu]));
1572 spin_lock_irqsave(&vic_irq_lock, flags); 1578 spin_lock_irqsave(&vic_irq_lock, flags);
1573 for_each_online_cpu(real_cpu) { 1579 for_each_online_cpu(real_cpu) {
@@ -1591,7 +1597,7 @@ enable_vic_irq(unsigned int irq)
1591} 1597}
1592 1598
1593static void 1599static void
1594disable_vic_irq(unsigned int irq) 1600mask_vic_irq(unsigned int irq)
1595{ 1601{
1596 /* lazy disable, do nothing */ 1602 /* lazy disable, do nothing */
1597} 1603}
@@ -1819,7 +1825,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1819 * disabled again as it comes in (voyager lazy disable). If 1825 * disabled again as it comes in (voyager lazy disable). If
1820 * the affinity map is tightened to disable the interrupt on a 1826 * the affinity map is tightened to disable the interrupt on a
1821 * cpu, it will be pushed off when it comes in */ 1827 * cpu, it will be pushed off when it comes in */
1822 enable_vic_irq(irq); 1828 unmask_vic_irq(irq);
1823} 1829}
1824 1830
1825static void 1831static void
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index f6a0c4436168..6a461d4caeff 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -45,6 +45,9 @@ config GENERIC_CALIBRATE_DELAY
45config GENERIC_IOMAP 45config GENERIC_IOMAP
46 bool 46 bool
47 47
48config GENERIC_TIME
49 def_bool n
50
48config ARCH_MAY_HAVE_PC_FDC 51config ARCH_MAY_HAVE_PC_FDC
49 bool 52 bool
50 53
@@ -357,6 +360,7 @@ config CPU_HAS_SR_RB
357endmenu 360endmenu
358 361
359menu "Timer support" 362menu "Timer support"
363depends on !GENERIC_TIME
360 364
361config SH_TMU 365config SH_TMU
362 bool "TMU timer support" 366 bool "TMU timer support"
diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c
index 75f91aaae077..219179114f0f 100644
--- a/arch/sh/boards/hp6xx/hp6xx_apm.c
+++ b/arch/sh/boards/hp6xx/hp6xx_apm.c
@@ -83,7 +83,7 @@ static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length)
83 return p - buf; 83 return p - buf;
84} 84}
85 85
86static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs) 86static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev)
87{ 87{
88 if (!apm_suspended) 88 if (!apm_suspended)
89 apm_queue_event(APM_USER_SUSPEND); 89 apm_queue_event(APM_USER_SUSPEND);
@@ -96,7 +96,7 @@ static int __init hp6x0_apm_init(void)
96 int ret; 96 int ret;
97 97
98 ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt, 98 ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt,
99 SA_INTERRUPT, MODNAME, 0); 99 IRQF_DISABLED, MODNAME, 0);
100 if (unlikely(ret < 0)) { 100 if (unlikely(ret < 0)) {
101 printk(KERN_ERR MODNAME ": IRQ %d request failed\n", 101 printk(KERN_ERR MODNAME ": IRQ %d request failed\n",
102 HP680_BTN_IRQ); 102 HP680_BTN_IRQ);
diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c
index 0b7bee1a9ca5..e62524978160 100644
--- a/arch/sh/boards/landisk/landisk_pwb.c
+++ b/arch/sh/boards/landisk/landisk_pwb.c
@@ -135,7 +135,7 @@ static int swdrv_write(struct file *filp, const char *buff, size_t count,
135 return count; 135 return count;
136} 136}
137 137
138static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs) 138static irqreturn_t sw_interrupt(int irq, void *dev_id)
139{ 139{
140 landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); 140 landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
141 disable_irq(IRQ_BUTTON); 141 disable_irq(IRQ_BUTTON);
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c
index 01c10fa5c058..7c3d1d304157 100644
--- a/arch/sh/boards/mpc1211/setup.c
+++ b/arch/sh/boards/mpc1211/setup.c
@@ -69,7 +69,6 @@ static void __init pci_write_config(unsigned long busNo,
69 69
70static unsigned char m_irq_mask = 0xfb; 70static unsigned char m_irq_mask = 0xfb;
71static unsigned char s_irq_mask = 0xff; 71static unsigned char s_irq_mask = 0xff;
72volatile unsigned long irq_err_count;
73 72
74static void disable_mpc1211_irq(unsigned int irq) 73static void disable_mpc1211_irq(unsigned int irq)
75{ 74{
@@ -118,7 +117,7 @@ static void mask_and_ack_mpc1211(unsigned int irq)
118 if(irq < 8) { 117 if(irq < 8) {
119 if(m_irq_mask & (1<<irq)){ 118 if(m_irq_mask & (1<<irq)){
120 if(!mpc1211_irq_real(irq)){ 119 if(!mpc1211_irq_real(irq)){
121 irq_err_count++; 120 atomic_inc(&irq_err_count)
122 printk("spurious 8259A interrupt: IRQ %x\n",irq); 121 printk("spurious 8259A interrupt: IRQ %x\n",irq);
123 } 122 }
124 } else { 123 } else {
@@ -131,7 +130,7 @@ static void mask_and_ack_mpc1211(unsigned int irq)
131 } else { 130 } else {
132 if(s_irq_mask & (1<<(irq - 8))){ 131 if(s_irq_mask & (1<<(irq - 8))){
133 if(!mpc1211_irq_real(irq)){ 132 if(!mpc1211_irq_real(irq)){
134 irq_err_count++; 133 atomic_inc(&irq_err_count);
135 printk("spurious 8259A interrupt: IRQ %x\n",irq); 134 printk("spurious 8259A interrupt: IRQ %x\n",irq);
136 } 135 }
137 } else { 136 } else {
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
index 2d960e9a3143..b544772cbc72 100644
--- a/arch/sh/boards/renesas/r7780rp/irq.c
+++ b/arch/sh/boards/renesas/r7780rp/irq.c
@@ -1,18 +1,16 @@
1/* 1/*
2 * linux/arch/sh/boards/renesas/r7780rp/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Solutions Highlander R7780RP-1 Support. 2 * Renesas Solutions Highlander R7780RP-1 Support.
7 * 3 *
8 * Modified for R7780RP-1 by 4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
9 * Atom Create Engineering Co., Ltd. 2002. 5 * Copyright (C) 2006 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */ 10 */
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/irq.h> 12#include <linux/irq.h>
13#include <asm/io.h> 13#include <asm/io.h>
14#include <asm/irq.h>
15#include <asm/r7780rp/r7780rp.h>
16 14
17#ifdef CONFIG_SH_R7780MP 15#ifdef CONFIG_SH_R7780MP
18static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; 16static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
@@ -20,71 +18,26 @@ static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
20static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; 18static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
21#endif 19#endif
22 20
23static void enable_r7780rp_irq(unsigned int irq);
24static void disable_r7780rp_irq(unsigned int irq);
25
26/* shutdown is same as "disable" */
27#define shutdown_r7780rp_irq disable_r7780rp_irq
28
29static void ack_r7780rp_irq(unsigned int irq);
30static void end_r7780rp_irq(unsigned int irq);
31
32static unsigned int startup_r7780rp_irq(unsigned int irq)
33{
34 enable_r7780rp_irq(irq);
35 return 0; /* never anything pending */
36}
37
38static void disable_r7780rp_irq(unsigned int irq)
39{
40 unsigned short val;
41 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
42
43 /* Set the priority in IPR to 0 */
44 val = ctrl_inw(IRLCNTR1);
45 val &= mask;
46 ctrl_outw(val, IRLCNTR1);
47}
48
49static void enable_r7780rp_irq(unsigned int irq) 21static void enable_r7780rp_irq(unsigned int irq)
50{ 22{
51 unsigned short val;
52 unsigned short value = (0x0001 << mask_pos[irq]);
53
54 /* Set priority in IPR back to original value */ 23 /* Set priority in IPR back to original value */
55 val = ctrl_inw(IRLCNTR1); 24 ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1);
56 val |= value;
57 ctrl_outw(val, IRLCNTR1);
58}
59
60static void ack_r7780rp_irq(unsigned int irq)
61{
62 disable_r7780rp_irq(irq);
63} 25}
64 26
65static void end_r7780rp_irq(unsigned int irq) 27static void disable_r7780rp_irq(unsigned int irq)
66{ 28{
67 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 29 /* Set the priority in IPR to 0 */
68 enable_r7780rp_irq(irq); 30 ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])),
31 IRLCNTR1);
69} 32}
70 33
71static struct hw_interrupt_type r7780rp_irq_type = { 34static struct irq_chip r7780rp_irq_chip __read_mostly = {
72 .typename = "R7780RP-IRQ", 35 .name = "r7780rp",
73 .startup = startup_r7780rp_irq, 36 .mask = disable_r7780rp_irq,
74 .shutdown = shutdown_r7780rp_irq, 37 .unmask = enable_r7780rp_irq,
75 .enable = enable_r7780rp_irq, 38 .mask_ack = disable_r7780rp_irq,
76 .disable = disable_r7780rp_irq,
77 .ack = ack_r7780rp_irq,
78 .end = end_r7780rp_irq,
79}; 39};
80 40
81static void make_r7780rp_irq(unsigned int irq)
82{
83 disable_irq_nosync(irq);
84 irq_desc[irq].chip = &r7780rp_irq_type;
85 disable_r7780rp_irq(irq);
86}
87
88/* 41/*
89 * Initialize IRQ setting 42 * Initialize IRQ setting
90 */ 43 */
@@ -92,24 +45,10 @@ void __init init_r7780rp_IRQ(void)
92{ 45{
93 int i; 46 int i;
94 47
95 /* IRL0=PCI Slot #A 48 for (i = 0; i < 15; i++) {
96 * IRL1=PCI Slot #B 49 disable_irq_nosync(i);
97 * IRL2=PCI Slot #C 50 set_irq_chip_and_handler(i, &r7780rp_irq_chip,
98 * IRL3=PCI Slot #D 51 handle_level_irq);
99 * IRL4=CF Card 52 enable_r7780rp_irq(i);
100 * IRL5=CF Card Insert 53 }
101 * IRL6=M66596
102 * IRL7=SD Card
103 * IRL8=Touch Panel
104 * IRL9=SCI
105 * IRL10=Serial
106 * IRL11=Extention #A
107 * IRL11=Extention #B
108 * IRL12=Debug LAN
109 * IRL13=Push Switch
110 * IRL14=ZiggBee IO
111 */
112
113 for (i=0; i<15; i++)
114 make_r7780rp_irq(i);
115} 54}
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c
index f5e98c56b530..540d0bf16446 100644
--- a/arch/sh/boards/snapgear/setup.c
+++ b/arch/sh/boards/snapgear/setup.c
@@ -33,7 +33,7 @@ extern void pcibios_init(void);
33 * EraseConfig handling functions 33 * EraseConfig handling functions
34 */ 34 */
35 35
36static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs) 36static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id)
37{ 37{
38 volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000; 38 volatile char dummy __attribute__((unused)) = * (volatile char *) 0xb8000000;
39 39
diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c
index 38f1e8171a3a..4d49b5cbcc13 100644
--- a/arch/sh/cchips/hd6446x/hd64461/setup.c
+++ b/arch/sh/cchips/hd6446x/hd64461/setup.c
@@ -71,7 +71,7 @@ static struct hw_interrupt_type hd64461_irq_type = {
71 .end = end_hd64461_irq, 71 .end = end_hd64461_irq,
72}; 72};
73 73
74static irqreturn_t hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs) 74static irqreturn_t hd64461_interrupt(int irq, void *dev_id)
75{ 75{
76 printk(KERN_INFO 76 printk(KERN_INFO
77 "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n", 77 "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
diff --git a/arch/sh/cchips/hd6446x/hd64465/gpio.c b/arch/sh/cchips/hd6446x/hd64465/gpio.c
index 72320d02d69a..43431855ec86 100644
--- a/arch/sh/cchips/hd6446x/hd64465/gpio.c
+++ b/arch/sh/cchips/hd6446x/hd64465/gpio.c
@@ -85,7 +85,7 @@ static struct {
85 void *dev; 85 void *dev;
86} handlers[GPIO_NPORTS * 8]; 86} handlers[GPIO_NPORTS * 8];
87 87
88static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev, struct pt_regs *regs) 88static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev)
89{ 89{
90 unsigned short port, pin, isr, mask, portpin; 90 unsigned short port, pin, isr, mask, portpin;
91 91
diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c
index 30573d3e1966..d126e1f30dee 100644
--- a/arch/sh/cchips/hd6446x/hd64465/setup.c
+++ b/arch/sh/cchips/hd6446x/hd64465/setup.c
@@ -84,7 +84,7 @@ static struct hw_interrupt_type hd64465_irq_type = {
84}; 84};
85 85
86 86
87static irqreturn_t hd64465_interrupt(int irq, void *dev_id, struct pt_regs *regs) 87static irqreturn_t hd64465_interrupt(int irq, void *dev_id)
88{ 88{
89 printk(KERN_INFO 89 printk(KERN_INFO
90 "HD64465: spurious interrupt, nirr: 0x%x nimr: 0x%x\n", 90 "HD64465: spurious interrupt, nirr: 0x%x nimr: 0x%x\n",
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index 392c8b12ce36..bf1b28feca06 100644
--- a/arch/sh/cchips/voyagergx/irq.c
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -88,8 +88,7 @@ static struct hw_interrupt_type voyagergx_irq_type = {
88 .end = end_voyagergx_irq, 88 .end = end_voyagergx_irq,
89}; 89};
90 90
91static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, 91static irqreturn_t voyagergx_interrupt(int irq, void *dev_id)
92 struct pt_regs *regs)
93{ 92{
94 printk(KERN_INFO 93 printk(KERN_INFO
95 "VoyagerGX: spurious interrupt, status: 0x%x\n", 94 "VoyagerGX: spurious interrupt, status: 0x%x\n",
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c
index 9cb070924180..0caf11bb7e27 100644
--- a/arch/sh/drivers/dma/dma-g2.c
+++ b/arch/sh/drivers/dma/dma-g2.c
@@ -51,7 +51,7 @@ static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa0
51 ((g2_dma->channel[i].size - \ 51 ((g2_dma->channel[i].size - \
52 g2_dma->status[i].size) & 0x0fffffff) 52 g2_dma->status[i].size) & 0x0fffffff)
53 53
54static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) 54static irqreturn_t g2_dma_interrupt(int irq, void *dev_id)
55{ 55{
56 int i; 56 int i;
57 57
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c
index c1b6bc23c107..838fad566eaf 100644
--- a/arch/sh/drivers/dma/dma-pvr2.c
+++ b/arch/sh/drivers/dma/dma-pvr2.c
@@ -21,7 +21,7 @@
21static unsigned int xfer_complete; 21static unsigned int xfer_complete;
22static int count; 22static int count;
23 23
24static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) 24static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id)
25{ 25{
26 if (get_dma_residue(PVR2_CASCADE_CHAN)) { 26 if (get_dma_residue(PVR2_CASCADE_CHAN)) {
27 printk(KERN_WARNING "DMA: SH DMAC did not complete transfer " 27 printk(KERN_WARNING "DMA: SH DMAC did not complete transfer "
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index cbbe8bce3d67..d8ece20bb2cf 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -60,9 +60,9 @@ static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
60 * Besides that it needs to waken any waiting process, which should handle 60 * Besides that it needs to waken any waiting process, which should handle
61 * setting up the next transfer. 61 * setting up the next transfer.
62 */ 62 */
63static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) 63static irqreturn_t dma_tei(int irq, void *dev_id)
64{ 64{
65 struct dma_channel *chan = (struct dma_channel *)dev_id; 65 struct dma_channel *chan = dev_id;
66 u32 chcr; 66 u32 chcr;
67 67
68 chcr = ctrl_inl(CHCR[chan->chan]); 68 chcr = ctrl_inl(CHCR[chan->chan]);
@@ -228,7 +228,7 @@ static inline int dmaor_reset(void)
228} 228}
229 229
230#if defined(CONFIG_CPU_SH4) 230#if defined(CONFIG_CPU_SH4)
231static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) 231static irqreturn_t dma_err(int irq, void *dummy)
232{ 232{
233 dmaor_reset(); 233 dmaor_reset();
234 disable_irq(irq); 234 disable_irq(irq);
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index dbe837884983..85e1ee2e2e7b 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -155,7 +155,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
155 */ 155 */
156 pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", 156 pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n",
157 PCIBIOS_MIN_IO, (64 << 10), 157 PCIBIOS_MIN_IO, (64 << 10),
158 SH4_PCI_IO_BASE + PCIBIOS_MIN_IO); 158 SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO);
159 159
160 /* 160 /*
161 * XXX: For now, leave this board-specific. In the event we have other 161 * XXX: For now, leave this board-specific. In the event we have other
@@ -163,7 +163,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
163 */ 163 */
164#ifdef CONFIG_SH_BIGSUR 164#ifdef CONFIG_SH_BIGSUR
165 bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10), 165 bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10),
166 SH4_PCI_IO_BASE + PCIBIOS_MIN_IO, 0); 166 SH7751_PCI_IO_BASE + PCIBIOS_MIN_IO, 0);
167#endif 167#endif
168 168
169 /* Make sure the MSB's of IO window are set to access PCI space 169 /* Make sure the MSB's of IO window are set to access PCI space
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
index 4ab5ea6b35fb..efecb3d5995c 100644
--- a/arch/sh/drivers/pci/pci-st40.c
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -161,7 +161,7 @@ static char * pci_commands[16]={
161 "Memory Write-and-Invalidate" 161 "Memory Write-and-Invalidate"
162}; 162};
163 163
164static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs) 164static irqreturn_t st40_pci_irq(int irq, void *dev_instance)
165{ 165{
166 unsigned pci_int, pci_air, pci_cir, pci_aint; 166 unsigned pci_int, pci_air, pci_cir, pci_aint;
167 static int count=0; 167 static int count=0;
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
index e30e4b7aa70e..d4b2bb7e08c7 100644
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ b/arch/sh/kernel/cpu/irq/intc2.c
@@ -10,93 +10,32 @@
10 * These are the "new Hitachi style" interrupts, as present on the 10 * These are the "new Hitachi style" interrupts, as present on the
11 * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. 11 * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780.
12 */ 12 */
13
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/init.h> 14#include <linux/init.h>
16#include <linux/irq.h> 15#include <linux/irq.h>
17#include <asm/system.h> 16#include <asm/system.h>
18#include <asm/io.h> 17#include <asm/io.h>
19#include <asm/machvec.h>
20
21struct intc2_data {
22 unsigned char msk_offset;
23 unsigned char msk_shift;
24
25 int (*clear_irq) (int);
26};
27
28static struct intc2_data intc2_data[NR_INTC2_IRQS];
29
30static void enable_intc2_irq(unsigned int irq);
31static void disable_intc2_irq(unsigned int irq);
32
33/* shutdown is same as "disable" */
34#define shutdown_intc2_irq disable_intc2_irq
35
36static void mask_and_ack_intc2(unsigned int);
37static void end_intc2_irq(unsigned int irq);
38
39static unsigned int startup_intc2_irq(unsigned int irq)
40{
41 enable_intc2_irq(irq);
42 return 0; /* never anything pending */
43}
44
45static struct hw_interrupt_type intc2_irq_type = {
46 .typename = "INTC2-IRQ",
47 .startup = startup_intc2_irq,
48 .shutdown = shutdown_intc2_irq,
49 .enable = enable_intc2_irq,
50 .disable = disable_intc2_irq,
51 .ack = mask_and_ack_intc2,
52 .end = end_intc2_irq
53};
54 18
55static void disable_intc2_irq(unsigned int irq) 19static void disable_intc2_irq(unsigned int irq)
56{ 20{
57 int irq_offset = irq - INTC2_FIRST_IRQ; 21 struct intc2_data *p = get_irq_chip_data(irq);
58 int msk_shift, msk_offset; 22 ctrl_outl(1 << p->msk_shift,
59 23 INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset);
60 /* Sanity check */
61 if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
62 return;
63
64 msk_shift = intc2_data[irq_offset].msk_shift;
65 msk_offset = intc2_data[irq_offset].msk_offset;
66
67 ctrl_outl(1 << msk_shift,
68 INTC2_BASE + INTC2_INTMSK_OFFSET + msk_offset);
69} 24}
70 25
71static void enable_intc2_irq(unsigned int irq) 26static void enable_intc2_irq(unsigned int irq)
72{ 27{
73 int irq_offset = irq - INTC2_FIRST_IRQ; 28 struct intc2_data *p = get_irq_chip_data(irq);
74 int msk_shift, msk_offset; 29 ctrl_outl(1 << p->msk_shift,
75 30 INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset);
76 /* Sanity check */
77 if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS))
78 return;
79
80 msk_shift = intc2_data[irq_offset].msk_shift;
81 msk_offset = intc2_data[irq_offset].msk_offset;
82
83 ctrl_outl(1 << msk_shift,
84 INTC2_BASE + INTC2_INTMSKCLR_OFFSET + msk_offset);
85}
86
87static void mask_and_ack_intc2(unsigned int irq)
88{
89 disable_intc2_irq(irq);
90} 31}
91 32
92static void end_intc2_irq(unsigned int irq) 33static struct irq_chip intc2_irq_chip = {
93{ 34 .typename = "intc2",
94 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 35 .mask = disable_intc2_irq,
95 enable_intc2_irq(irq); 36 .unmask = enable_intc2_irq,
96 37 .mask_ack = disable_intc2_irq,
97 if (unlikely(intc2_data[irq - INTC2_FIRST_IRQ].clear_irq)) 38};
98 intc2_data[irq - INTC2_FIRST_IRQ].clear_irq(irq);
99}
100 39
101/* 40/*
102 * Setup an INTC2 style interrupt. 41 * Setup an INTC2 style interrupt.
@@ -108,46 +47,30 @@ static void end_intc2_irq(unsigned int irq)
108 * | | | | 47 * | | | |
109 * make_intc2_irq(84, 0, 16, 0, 13); 48 * make_intc2_irq(84, 0, 16, 0, 13);
110 */ 49 */
111void make_intc2_irq(unsigned int irq, 50void make_intc2_irq(struct intc2_data *p)
112 unsigned int ipr_offset, unsigned int ipr_shift,
113 unsigned int msk_offset, unsigned int msk_shift,
114 unsigned int priority)
115{ 51{
116 int irq_offset = irq - INTC2_FIRST_IRQ;
117 unsigned int flags; 52 unsigned int flags;
118 unsigned long ipr; 53 unsigned long ipr;
119 54
120 if (unlikely(irq_offset < 0 || irq_offset >= NR_INTC2_IRQS)) 55 disable_irq_nosync(p->irq);
121 return;
122
123 disable_irq_nosync(irq);
124
125 /* Fill the data we need */
126 intc2_data[irq_offset].msk_offset = msk_offset;
127 intc2_data[irq_offset].msk_shift = msk_shift;
128 intc2_data[irq_offset].clear_irq = NULL;
129 56
130 /* Set the priority level */ 57 /* Set the priority level */
131 local_irq_save(flags); 58 local_irq_save(flags);
132 59
133 ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); 60 ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset);
134 ipr &= ~(0xf << ipr_shift); 61 ipr &= ~(0xf << p->ipr_shift);
135 ipr |= priority << ipr_shift; 62 ipr |= p->priority << p->ipr_shift;
136 ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + ipr_offset); 63 ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset);
137 64
138 local_irq_restore(flags); 65 local_irq_restore(flags);
139 66
140 irq_desc[irq].chip = &intc2_irq_type; 67 set_irq_chip_and_handler(p->irq, &intc2_irq_chip, handle_level_irq);
68 set_irq_chip_data(p->irq, p);
141 69
142 disable_intc2_irq(irq); 70 enable_intc2_irq(p->irq);
143} 71}
144 72
145static struct intc2_init { 73static struct intc2_data intc2_irq_table[] = {
146 unsigned short irq;
147 unsigned char ipr_offset, ipr_shift;
148 unsigned char msk_offset, msk_shift;
149 unsigned char priority;
150} intc2_init_data[] __initdata = {
151#if defined(CONFIG_CPU_SUBTYPE_ST40) 74#if defined(CONFIG_CPU_SUBTYPE_ST40)
152 {64, 0, 0, 0, 0, 13}, /* PCI serr */ 75 {64, 0, 0, 0, 0, 13}, /* PCI serr */
153 {65, 0, 4, 0, 1, 13}, /* PCI err */ 76 {65, 0, 4, 0, 1, 13}, /* PCI err */
@@ -266,19 +189,6 @@ void __init init_IRQ_intc2(void)
266{ 189{
267 int i; 190 int i;
268 191
269 for (i = 0; i < ARRAY_SIZE(intc2_init_data); i++) { 192 for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++)
270 struct intc2_init *p = intc2_init_data + i; 193 make_intc2_irq(intc2_irq_table + i);
271 make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift,
272 p-> msk_offset, p->msk_shift, p->priority);
273 }
274}
275
276/* Adds a termination callback to the interrupt */
277void intc2_add_clear_irq(int irq, int (*fn)(int))
278{
279 if (unlikely(irq < INTC2_FIRST_IRQ))
280 return;
281
282 intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn;
283} 194}
284
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index f785822cd5de..8944abdf6e1c 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * arch/sh/kernel/cpu/irq/ipr.c 2 * Interrupt handling for IPR-based IRQ.
3 * 3 *
4 * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi 4 * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi
5 * Copyright (C) 2000 Kazumoto Kojima 5 * Copyright (C) 2000 Kazumoto Kojima
6 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> 6 * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp>
7 * 7 * Copyright (C) 2006 Paul Mundt
8 * Interrupt handling for IPR-based IRQ.
9 * 8 *
10 * Supported system: 9 * Supported system:
11 * On-chip supporting modules (TMU, RTC, etc.). 10 * On-chip supporting modules (TMU, RTC, etc.).
@@ -13,12 +12,13 @@
13 * Hitachi SolutionEngine external I/O: 12 * Hitachi SolutionEngine external I/O:
14 * MS7709SE01, MS7709ASE01, and MS7750SE01 13 * MS7709SE01, MS7709ASE01, and MS7750SE01
15 * 14 *
15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file "COPYING" in the main directory of this archive
17 * for more details.
16 */ 18 */
17
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/irq.h> 20#include <linux/irq.h>
20#include <linux/module.h> 21#include <linux/module.h>
21
22#include <asm/system.h> 22#include <asm/system.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/machvec.h> 24#include <asm/machvec.h>
@@ -28,93 +28,45 @@ struct ipr_data {
28 int shift; /* Shifts of the 16-bit data */ 28 int shift; /* Shifts of the 16-bit data */
29 int priority; /* The priority */ 29 int priority; /* The priority */
30}; 30};
31static struct ipr_data ipr_data[NR_IRQS];
32
33static void enable_ipr_irq(unsigned int irq);
34static void disable_ipr_irq(unsigned int irq);
35
36/* shutdown is same as "disable" */
37#define shutdown_ipr_irq disable_ipr_irq
38
39static void mask_and_ack_ipr(unsigned int);
40static void end_ipr_irq(unsigned int irq);
41
42static unsigned int startup_ipr_irq(unsigned int irq)
43{
44 enable_ipr_irq(irq);
45 return 0; /* never anything pending */
46}
47
48static struct hw_interrupt_type ipr_irq_type = {
49 .typename = "IPR-IRQ",
50 .startup = startup_ipr_irq,
51 .shutdown = shutdown_ipr_irq,
52 .enable = enable_ipr_irq,
53 .disable = disable_ipr_irq,
54 .ack = mask_and_ack_ipr,
55 .end = end_ipr_irq
56};
57 31
58static void disable_ipr_irq(unsigned int irq) 32static void disable_ipr_irq(unsigned int irq)
59{ 33{
60 unsigned long val; 34 struct ipr_data *p = get_irq_chip_data(irq);
61 unsigned int addr = ipr_data[irq].addr;
62 unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
63
64 /* Set the priority in IPR to 0 */ 35 /* Set the priority in IPR to 0 */
65 val = ctrl_inw(addr); 36 ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr);
66 val &= mask;
67 ctrl_outw(val, addr);
68} 37}
69 38
70static void enable_ipr_irq(unsigned int irq) 39static void enable_ipr_irq(unsigned int irq)
71{ 40{
72 unsigned long val; 41 struct ipr_data *p = get_irq_chip_data(irq);
73 unsigned int addr = ipr_data[irq].addr;
74 int priority = ipr_data[irq].priority;
75 unsigned short value = (priority << ipr_data[irq].shift);
76
77 /* Set priority in IPR back to original value */ 42 /* Set priority in IPR back to original value */
78 val = ctrl_inw(addr); 43 ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr);
79 val |= value;
80 ctrl_outw(val, addr);
81} 44}
82 45
83static void mask_and_ack_ipr(unsigned int irq) 46static struct irq_chip ipr_irq_chip = {
84{ 47 .name = "ipr",
85 disable_ipr_irq(irq); 48 .mask = disable_ipr_irq,
86 49 .unmask = enable_ipr_irq,
87#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 50 .mask_ack = disable_ipr_irq,
88 defined(CONFIG_CPU_SUBTYPE_SH7706) || \ 51};
89 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
90 /* This is needed when we use edge triggered setting */
91 /* XXX: Is it really needed? */
92 if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
93 /* Clear external interrupt request */
94 int a = ctrl_inb(INTC_IRR0);
95 a &= ~(1 << (irq - IRQ0_IRQ));
96 ctrl_outb(a, INTC_IRR0);
97 }
98#endif
99}
100
101static void end_ipr_irq(unsigned int irq)
102{
103 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
104 enable_ipr_irq(irq);
105}
106 52
107void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) 53void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority)
108{ 54{
55 struct ipr_data ipr_data;
56
109 disable_irq_nosync(irq); 57 disable_irq_nosync(irq);
110 ipr_data[irq].addr = addr;
111 ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */
112 ipr_data[irq].priority = priority;
113 58
114 irq_desc[irq].chip = &ipr_irq_type; 59 ipr_data.addr = addr;
115 disable_ipr_irq(irq); 60 ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */
61 ipr_data.priority = priority;
62
63 set_irq_chip_and_handler(irq, &ipr_irq_chip, handle_level_irq);
64 set_irq_chip_data(irq, &ipr_data);
65
66 enable_ipr_irq(irq);
116} 67}
117 68
69/* XXX: This needs to die a horrible death.. */
118void __init init_IRQ(void) 70void __init init_IRQ(void)
119{ 71{
120#ifndef CONFIG_CPU_SUBTYPE_SH7780 72#ifndef CONFIG_CPU_SUBTYPE_SH7780
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index 44daf44833f9..6be46f0686b7 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -49,198 +49,3 @@ ENTRY(nmi_slot)
49#endif 49#endif
50ENTRY(user_break_point_trap) 50ENTRY(user_break_point_trap)
51 .long break_point_trap /* 1E0 */ 51 .long break_point_trap /* 1E0 */
52ENTRY(interrupt_table)
53 ! external hardware
54 .long do_IRQ ! 0000 /* 200 */
55 .long do_IRQ ! 0001
56 .long do_IRQ ! 0010
57 .long do_IRQ ! 0011
58 .long do_IRQ ! 0100
59 .long do_IRQ ! 0101
60 .long do_IRQ ! 0110
61 .long do_IRQ ! 0111
62 .long do_IRQ ! 1000 /* 300 */
63 .long do_IRQ ! 1001
64 .long do_IRQ ! 1010
65 .long do_IRQ ! 1011
66 .long do_IRQ ! 1100
67 .long do_IRQ ! 1101
68 .long do_IRQ ! 1110
69 .long exception_error
70 ! Internal hardware
71 .long do_IRQ ! TMU0 tuni0 /* 400 */
72 .long do_IRQ ! TMU1 tuni1
73 .long do_IRQ ! TMU2 tuni2
74 .long do_IRQ ! ticpi2
75 .long do_IRQ ! RTC ati
76 .long do_IRQ ! pri
77 .long do_IRQ ! cui
78 .long do_IRQ ! SCI eri
79 .long do_IRQ ! rxi /* 500 */
80 .long do_IRQ ! txi
81 .long do_IRQ ! tei
82 .long do_IRQ ! WDT iti /* 560 */
83 .long do_IRQ ! REF rcmi
84 .long do_IRQ ! rovi
85 .long do_IRQ
86 .long do_IRQ /* 5E0 */
87#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
88 defined(CONFIG_CPU_SUBTYPE_SH7709) || \
89 defined(CONFIG_CPU_SUBTYPE_SH7706) || \
90 defined(CONFIG_CPU_SUBTYPE_SH7300) || \
91 defined(CONFIG_CPU_SUBTYPE_SH7705) || \
92 defined(CONFIG_CPU_SUBTYPE_SH7710)
93 .long do_IRQ ! 32 IRQ irq0 /* 600 */
94 .long do_IRQ ! 33 irq1
95 .long do_IRQ ! 34 irq2
96 .long do_IRQ ! 35 irq3
97 .long do_IRQ ! 36 irq4
98 .long do_IRQ ! 37 irq5
99 .long do_IRQ ! 38
100 .long do_IRQ ! 39
101 .long do_IRQ ! 40 PINT pint0-7 /* 700 */
102 .long do_IRQ ! 41 pint8-15
103 .long do_IRQ ! 42
104 .long do_IRQ ! 43
105 .long do_IRQ ! 44
106 .long do_IRQ ! 45
107 .long do_IRQ ! 46
108 .long do_IRQ ! 47
109 .long do_IRQ ! 48 DMAC dei0 /* 800 */
110 .long do_IRQ ! 49 dei1
111 .long do_IRQ ! 50 dei2
112 .long do_IRQ ! 51 dei3
113 .long do_IRQ ! 52 IrDA eri1
114 .long do_IRQ ! 53 rxi1
115 .long do_IRQ ! 54 bri1
116 .long do_IRQ ! 55 txi1
117 .long do_IRQ ! 56 SCIF eri2
118 .long do_IRQ ! 57 rxi2
119 .long do_IRQ ! 58 bri2
120 .long do_IRQ ! 59 txi2
121 .long do_IRQ ! 60 ADC adi /* 980 */
122#if defined(CONFIG_CPU_SUBTYPE_SH7705)
123 .long exception_none ! 61 /* 9A0 */
124 .long exception_none ! 62
125 .long exception_none ! 63
126 .long exception_none ! 64 /* A00 */
127 .long do_IRQ ! 65 USB usi0
128 .long do_IRQ ! 66 usi1
129 .long exception_none ! 67
130 .long exception_none ! 68
131 .long exception_none ! 69
132 .long exception_none ! 70
133 .long exception_none ! 71
134 .long exception_none ! 72 /* B00 */
135 .long exception_none ! 73
136 .long exception_none ! 74
137 .long exception_none ! 75
138 .long exception_none ! 76
139 .long exception_none ! 77
140 .long exception_none ! 78
141 .long exception_none ! 79
142 .long do_IRQ ! 80 TPU0 tpi0 /* C00 */
143 .long do_IRQ ! 81 TPU1 tpi1
144 .long exception_none ! 82
145 .long exception_none ! 83
146 .long do_IRQ ! 84 TPU2 tpi2
147 .long do_IRQ ! 85 TPU3 tpi3 /* CA0 */
148#endif
149#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7300)
150 .long do_IRQ ! 61 LCDC lcdi /* 9A0 */
151 .long do_IRQ ! 62 PCC pcc0i
152 .long do_IRQ ! 63 pcc1i /* 9E0 */
153#endif
154#if defined(CONFIG_CPU_SUBTYPE_SH7710)
155 .long exception_none ! 61 /* 9A0 */
156 .long exception_none ! 62
157 .long exception_none ! 63
158 .long exception_none ! 64 /* A00 */
159 .long exception_none ! 65
160 .long exception_none ! 66
161 .long exception_none ! 67
162 .long exception_none ! 68
163 .long exception_none ! 69
164 .long exception_none ! 70
165 .long exception_none ! 71
166 .long exception_none ! 72 /* B00 */
167 .long exception_none ! 73
168 .long exception_none ! 74
169 .long exception_none ! 75
170 .long do_IRQ ! 76 DMAC2 dei4 /* B80 */
171 .long do_IRQ ! 77 DMAC2 dei5
172 .long exception_none ! 78
173 .long do_IRQ ! 79 IPSEC ipseci /* BE0 */
174 .long do_IRQ ! 80 EDMAC eint0 /* C00 */
175 .long do_IRQ ! 81 EDMAC eint1
176 .long do_IRQ ! 82 EDMAC eint2
177 .long exception_none ! 83 /* C60 */
178 .long exception_none ! 84
179 .long exception_none ! 85
180 .long exception_none ! 86
181 .long exception_none ! 87
182 .long exception_none ! 88 /* D00 */
183 .long exception_none ! 89
184 .long exception_none ! 90
185 .long exception_none ! 91
186 .long exception_none ! 92
187 .long exception_none ! 93
188 .long exception_none ! 94
189 .long exception_none ! 95
190 .long do_IRQ ! 96 SIOF eri0 /* E00 */
191 .long do_IRQ ! 97 txi0
192 .long do_IRQ ! 98 rxi0
193 .long do_IRQ ! 99 cci0
194 .long do_IRQ ! 100 eri1 /* E80 */
195 .long do_IRQ ! 101 txi1
196 .long do_IRQ ! 102 rxi2
197 .long do_IRQ ! 103 cci3
198#endif
199#if defined(CONFIG_CPU_SUBTYPE_SH7300)
200 .long do_IRQ ! 64
201 .long do_IRQ ! 65
202 .long do_IRQ ! 66
203 .long do_IRQ ! 67
204 .long do_IRQ ! 68
205 .long do_IRQ ! 69
206 .long do_IRQ ! 70
207 .long do_IRQ ! 71
208 .long do_IRQ ! 72
209 .long do_IRQ ! 73
210 .long do_IRQ ! 74
211 .long do_IRQ ! 75
212 .long do_IRQ ! 76
213 .long do_IRQ ! 77
214 .long do_IRQ ! 78
215 .long do_IRQ ! 79
216 .long do_IRQ ! 80 SCIF0(SH7300)
217 .long do_IRQ ! 81
218 .long do_IRQ ! 82
219 .long do_IRQ ! 83
220 .long do_IRQ ! 84
221 .long do_IRQ ! 85
222 .long do_IRQ ! 86
223 .long do_IRQ ! 87
224 .long do_IRQ ! 88
225 .long do_IRQ ! 89
226 .long do_IRQ ! 90
227 .long do_IRQ ! 91
228 .long do_IRQ ! 92
229 .long do_IRQ ! 93
230 .long do_IRQ ! 94
231 .long do_IRQ ! 95
232 .long do_IRQ ! 96
233 .long do_IRQ ! 97
234 .long do_IRQ ! 98
235 .long do_IRQ ! 99
236 .long do_IRQ ! 100
237 .long do_IRQ ! 101
238 .long do_IRQ ! 102
239 .long do_IRQ ! 103
240 .long do_IRQ ! 104
241 .long do_IRQ ! 105
242 .long do_IRQ ! 106
243 .long do_IRQ ! 107
244 .long do_IRQ ! 108
245#endif
246#endif
diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S
index 7146893a6cca..3f4cd043e900 100644
--- a/arch/sh/kernel/cpu/sh4/ex.S
+++ b/arch/sh/kernel/cpu/sh4/ex.S
@@ -53,503 +53,3 @@ ENTRY(nmi_slot)
53#endif 53#endif
54ENTRY(user_break_point_trap) 54ENTRY(user_break_point_trap)
55 .long break_point_trap /* 1E0 */ 55 .long break_point_trap /* 1E0 */
56ENTRY(interrupt_table)
57 ! external hardware
58 .long do_IRQ ! 0000 /* 200 */
59 .long do_IRQ ! 0001
60 .long do_IRQ ! 0010
61 .long do_IRQ ! 0011
62 .long do_IRQ ! 0100
63 .long do_IRQ ! 0101
64 .long do_IRQ ! 0110
65 .long do_IRQ ! 0111
66 .long do_IRQ ! 1000 /* 300 */
67 .long do_IRQ ! 1001
68 .long do_IRQ ! 1010
69 .long do_IRQ ! 1011
70 .long do_IRQ ! 1100
71 .long do_IRQ ! 1101
72 .long do_IRQ ! 1110
73 .long exception_error
74 ! Internal hardware
75#ifndef CONFIG_CPU_SUBTYPE_SH7780
76 .long do_IRQ ! TMU0 tuni0 /* 400 */
77 .long do_IRQ ! TMU1 tuni1
78 .long do_IRQ ! TMU2 tuni2
79 .long do_IRQ ! ticpi2
80#if defined(CONFIG_CPU_SUBTYPE_SH7760)
81 .long exception_error
82 .long exception_error
83 .long exception_error
84 .long exception_error
85 .long exception_error /* 500 */
86 .long exception_error
87 .long exception_error
88#else
89 .long do_IRQ ! RTC ati
90 .long do_IRQ ! pri
91 .long do_IRQ ! cui
92 .long do_IRQ ! SCI eri
93 .long do_IRQ ! rxi /* 500 */
94 .long do_IRQ ! txi
95 .long do_IRQ ! tei
96#endif
97 .long do_IRQ ! WDT iti /* 560 */
98 .long do_IRQ ! REF rcmi
99 .long do_IRQ ! rovi
100 .long do_IRQ
101 .long do_IRQ /* 5E0 */
102 .long do_IRQ ! 32 Hitachi UDI /* 600 */
103 .long do_IRQ ! 33 GPIO
104 .long do_IRQ ! 34 DMAC dmte0
105 .long do_IRQ ! 35 dmte1
106 .long do_IRQ ! 36 dmte2
107 .long do_IRQ ! 37 dmte3
108 .long do_IRQ ! 38 dmae
109 .long exception_error ! 39 /* 6E0 */
110#if defined(CONFIG_CPU_SUBTYPE_SH7760)
111 .long exception_error /* 700 */
112 .long exception_error
113 .long exception_error
114 .long exception_error /* 760 */
115#else
116 .long do_IRQ ! 40 SCIF eri /* 700 */
117 .long do_IRQ ! 41 rxi
118 .long do_IRQ ! 42 bri
119 .long do_IRQ ! 43 txi
120#endif
121#if CONFIG_NR_ONCHIP_DMA_CHANNELS == 8
122 .long do_IRQ ! 44 DMAC dmte4 /* 780 */
123 .long do_IRQ ! 45 dmte5
124 .long do_IRQ ! 46 dmte6
125 .long do_IRQ ! 47 dmte7 /* 7E0 */
126#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
127 .long do_IRQ ! 44 IIC1 ali /* 780 */
128 .long do_IRQ ! 45 tacki
129 .long do_IRQ ! 46 waiti
130 .long do_IRQ ! 47 dtei /* 7E0 */
131 .long do_IRQ ! 48 DMAC dei0 /* 800 */
132 .long do_IRQ ! 49 dei1 /* 820 */
133#else
134 .long exception_error ! 44 /* 780 */
135 .long exception_error ! 45
136 .long exception_error ! 46
137 .long exception_error ! 47
138#endif
139#if defined(CONFIG_SH_FPU)
140 .long do_fpu_state_restore ! 48 /* 800 */
141 .long do_fpu_state_restore ! 49 /* 820 */
142#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \
143 !defined(CONFIG_CPU_SUBTYPE_SH73180)
144 .long exception_error
145 .long exception_error
146#endif
147#if defined(CONFIG_CPU_SUBTYPE_SH7751)
148 .long exception_error /* 840 */
149 .long exception_error
150 .long exception_error
151 .long exception_error
152 .long exception_error
153 .long exception_error
154 .long exception_error /* 900 */
155 .long exception_error
156 .long exception_error
157 .long exception_error
158 .long exception_error
159 .long exception_error
160 .long exception_error
161 .long exception_error
162 .long do_IRQ ! PCI serr /* A00 */
163 .long do_IRQ ! dma3
164 .long do_IRQ ! dma2
165 .long do_IRQ ! dma1
166 .long do_IRQ ! dma0
167 .long do_IRQ ! pwon
168 .long do_IRQ ! pwdwn
169 .long do_IRQ ! err
170 .long do_IRQ ! TMU3 tuni3 /* B00 */
171 .long exception_error
172 .long exception_error
173 .long exception_error
174 .long do_IRQ ! TMU4 tuni4 /* B80 */
175#elif defined(CONFIG_CPU_SUBTYPE_SH7760)
176 .long do_IRQ ! IRQ irq6 /* 840 */
177 .long do_IRQ ! irq7
178 .long do_IRQ ! SCIF eri0
179 .long do_IRQ ! rxi0
180 .long do_IRQ ! bri0
181 .long do_IRQ ! txi0
182 .long do_IRQ ! HCAN2 cani0 /* 900 */
183 .long do_IRQ ! cani1
184 .long do_IRQ ! SSI ssii0
185 .long do_IRQ ! ssii1
186 .long do_IRQ ! HAC haci0
187 .long do_IRQ ! haci1
188 .long do_IRQ ! IIC iici0
189 .long do_IRQ ! iici1
190 .long do_IRQ ! USB usbi /* A00 */
191 .long do_IRQ ! LCDC vint
192 .long exception_error
193 .long exception_error
194 .long do_IRQ ! DMABRG dmabrgi0
195 .long do_IRQ ! dmabrgi1
196 .long do_IRQ ! dmabrgi2
197 .long exception_error
198 .long do_IRQ ! SCIF eri1 /* B00 */
199 .long do_IRQ ! rxi1
200 .long do_IRQ ! bri1
201 .long do_IRQ ! txi1
202 .long do_IRQ ! eri2
203 .long do_IRQ ! rxi2
204 .long do_IRQ ! bri2
205 .long do_IRQ ! txi2
206 .long do_IRQ ! SIM simeri /* C00 */
207 .long do_IRQ ! simrxi
208 .long do_IRQ ! simtxi
209 .long do_IRQ ! simtei
210 .long do_IRQ ! HSPI spii
211 .long exception_error
212 .long exception_error
213 .long exception_error
214 .long do_IRQ ! MMCIF mmci0 /* D00 */
215 .long do_IRQ ! mmci1
216 .long do_IRQ ! mmci2
217 .long do_IRQ ! mmci3
218 .long exception_error
219 .long exception_error
220 .long exception_error
221 .long exception_error
222 .long exception_error /* E00 */
223 .long exception_error
224 .long exception_error
225 .long exception_error
226 .long do_IRQ ! MFI mfii
227 .long exception_error
228 .long exception_error
229 .long exception_error
230 .long exception_error /* F00 */
231 .long exception_error
232 .long exception_error
233 .long exception_error
234 .long do_IRQ ! ADC adi
235 .long do_IRQ ! CMT cmti /* FA0 */
236#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343)
237 .long do_IRQ ! 50 0x840
238 .long do_IRQ ! 51 0x860
239 .long do_IRQ ! 52 0x880
240 .long do_IRQ ! 53 0x8a0
241 .long do_IRQ ! 54 0x8c0
242 .long do_IRQ ! 55 0x8e0
243 .long do_IRQ ! 56 0x900
244 .long do_IRQ ! 57 0x920
245 .long do_IRQ ! 58 0x940
246 .long do_IRQ ! 59 0x960
247 .long do_IRQ ! 60 0x980
248 .long do_IRQ ! 61 0x9a0
249 .long do_IRQ ! 62 0x9c0
250 .long do_IRQ ! 63 0x9e0
251 .long do_IRQ ! 64 0xa00
252 .long do_IRQ ! 65 0xa20
253 .long do_IRQ ! 66 0xa40
254 .long do_IRQ ! 67 0xa60
255 .long do_IRQ ! 68 0xa80
256 .long do_IRQ ! 69 0xaa0
257 .long do_IRQ ! 70 0xac0
258 .long do_IRQ ! 71 0xae0
259 .long do_IRQ ! 72 0xb00
260 .long do_IRQ ! 73 0xb20
261 .long do_IRQ ! 74 0xb40
262 .long do_IRQ ! 75 0xb60
263 .long do_IRQ ! 76 0xb80
264 .long do_IRQ ! 77 0xba0
265 .long do_IRQ ! 78 0xbc0
266 .long do_IRQ ! 79 0xbe0
267 .long do_IRQ ! 80 0xc00
268 .long do_IRQ ! 81 0xc20
269 .long do_IRQ ! 82 0xc40
270 .long do_IRQ ! 83 0xc60
271 .long do_IRQ ! 84 0xc80
272 .long do_IRQ ! 85 0xca0
273 .long do_IRQ ! 86 0xcc0
274 .long do_IRQ ! 87 0xce0
275 .long do_IRQ ! 88 0xd00
276 .long do_IRQ ! 89 0xd20
277 .long do_IRQ ! 90 0xd40
278 .long do_IRQ ! 91 0xd60
279 .long do_IRQ ! 92 0xd80
280 .long do_IRQ ! 93 0xda0
281 .long do_IRQ ! 94 0xdc0
282 .long do_IRQ ! 95 0xde0
283 .long do_IRQ ! 96 0xe00
284 .long do_IRQ ! 97 0xe20
285 .long do_IRQ ! 98 0xe40
286 .long do_IRQ ! 99 0xe60
287 .long do_IRQ ! 100 0xe80
288 .long do_IRQ ! 101 0xea0
289 .long do_IRQ ! 102 0xec0
290 .long do_IRQ ! 103 0xee0
291 .long do_IRQ ! 104 0xf00
292 .long do_IRQ ! 105 0xf20
293 .long do_IRQ ! 106 0xf40
294 .long do_IRQ ! 107 0xf60
295 .long do_IRQ ! 108 0xf80
296#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)
297 .long exception_error ! 50 0x840
298 .long exception_error ! 51 0x860
299 .long exception_error ! 52 0x880
300 .long exception_error ! 53 0x8a0
301 .long exception_error ! 54 0x8c0
302 .long exception_error ! 55 0x8e0
303 .long exception_error ! 56 0x900
304 .long exception_error ! 57 0x920
305 .long exception_error ! 58 0x940
306 .long exception_error ! 59 0x960
307 .long exception_error ! 60 0x980
308 .long exception_error ! 61 0x9a0
309 .long exception_error ! 62 0x9c0
310 .long exception_error ! 63 0x9e0
311 .long do_IRQ ! 64 0xa00 PCI serr
312 .long do_IRQ ! 65 0xa20 err
313 .long do_IRQ ! 66 0xa40 ad
314 .long do_IRQ ! 67 0xa60 pwr_dwn
315 .long exception_error ! 68 0xa80
316 .long exception_error ! 69 0xaa0
317 .long exception_error ! 70 0xac0
318 .long exception_error ! 71 0xae0
319 .long do_IRQ ! 72 0xb00 DMA INT0
320 .long do_IRQ ! 73 0xb20 INT1
321 .long do_IRQ ! 74 0xb40 INT2
322 .long do_IRQ ! 75 0xb60 INT3
323 .long do_IRQ ! 76 0xb80 INT4
324 .long exception_error ! 77 0xba0
325 .long do_IRQ ! 78 0xbc0 DMA ERR
326 .long exception_error ! 79 0xbe0
327 .long do_IRQ ! 80 0xc00 PIO0
328 .long do_IRQ ! 81 0xc20 PIO1
329 .long do_IRQ ! 82 0xc40 PIO2
330 .long exception_error ! 83 0xc60
331 .long exception_error ! 84 0xc80
332 .long exception_error ! 85 0xca0
333 .long exception_error ! 86 0xcc0
334 .long exception_error ! 87 0xce0
335 .long exception_error ! 88 0xd00
336 .long exception_error ! 89 0xd20
337 .long exception_error ! 90 0xd40
338 .long exception_error ! 91 0xd60
339 .long exception_error ! 92 0xd80
340 .long exception_error ! 93 0xda0
341 .long exception_error ! 94 0xdc0
342 .long exception_error ! 95 0xde0
343 .long exception_error ! 96 0xe00
344 .long exception_error ! 97 0xe20
345 .long exception_error ! 98 0xe40
346 .long exception_error ! 99 0xe60
347 .long exception_error ! 100 0xe80
348 .long exception_error ! 101 0xea0
349 .long exception_error ! 102 0xec0
350 .long exception_error ! 103 0xee0
351 .long exception_error ! 104 0xf00
352 .long exception_error ! 105 0xf20
353 .long exception_error ! 106 0xf40
354 .long exception_error ! 107 0xf60
355 .long exception_error ! 108 0xf80
356 .long exception_error ! 109 0xfa0
357 .long exception_error ! 110 0xfc0
358 .long exception_error ! 111 0xfe0
359 .long do_IRQ ! 112 0x1000 Mailbox
360 .long exception_error ! 113 0x1020
361 .long exception_error ! 114 0x1040
362 .long exception_error ! 115 0x1060
363 .long exception_error ! 116 0x1080
364 .long exception_error ! 117 0x10a0
365 .long exception_error ! 118 0x10c0
366 .long exception_error ! 119 0x10e0
367 .long exception_error ! 120 0x1100
368 .long exception_error ! 121 0x1120
369 .long exception_error ! 122 0x1140
370 .long exception_error ! 123 0x1160
371 .long exception_error ! 124 0x1180
372 .long exception_error ! 125 0x11a0
373 .long exception_error ! 126 0x11c0
374 .long exception_error ! 127 0x11e0
375 .long exception_error ! 128 0x1200
376 .long exception_error ! 129 0x1220
377 .long exception_error ! 130 0x1240
378 .long exception_error ! 131 0x1260
379 .long exception_error ! 132 0x1280
380 .long exception_error ! 133 0x12a0
381 .long exception_error ! 134 0x12c0
382 .long exception_error ! 135 0x12e0
383 .long exception_error ! 136 0x1300
384 .long exception_error ! 137 0x1320
385 .long exception_error ! 138 0x1340
386 .long exception_error ! 139 0x1360
387 .long do_IRQ ! 140 0x1380 EMPI INV_ADDR
388 .long exception_error ! 141 0x13a0
389 .long exception_error ! 142 0x13c0
390 .long exception_error ! 143 0x13e0
391#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
392 .long do_IRQ ! 50 0x840
393 .long do_IRQ ! 51 0x860
394 .long do_IRQ ! 52 0x880
395 .long do_IRQ ! 53 0x8a0
396 .long do_IRQ ! 54 0x8c0
397 .long do_IRQ ! 55 0x8e0
398 .long do_IRQ ! 56 0x900
399 .long do_IRQ ! 57 0x920
400 .long do_IRQ ! 58 0x940
401 .long do_IRQ ! 59 0x960
402 .long do_IRQ ! 60 0x980
403 .long do_IRQ ! 61 0x9a0
404 .long do_IRQ ! 62 0x9c0
405 .long do_IRQ ! 63 0x9e0
406 .long do_IRQ ! 64 0xa00
407 .long do_IRQ ! 65 0xa20
408 .long do_IRQ ! 66 0xa4d
409 .long do_IRQ ! 67 0xa60
410 .long do_IRQ ! 68 0xa80
411 .long do_IRQ ! 69 0xaa0
412 .long do_IRQ ! 70 0xac0
413 .long do_IRQ ! 71 0xae0
414 .long do_IRQ ! 72 0xb00
415 .long do_IRQ ! 73 0xb20
416 .long do_IRQ ! 74 0xb40
417 .long do_IRQ ! 75 0xb60
418 .long do_IRQ ! 76 0xb80
419 .long do_IRQ ! 77 0xba0
420 .long do_IRQ ! 78 0xbc0
421 .long do_IRQ ! 79 0xbe0
422 .long do_IRQ ! 80 0xc00
423 .long do_IRQ ! 81 0xc20
424 .long do_IRQ ! 82 0xc40
425 .long do_IRQ ! 83 0xc60
426 .long do_IRQ ! 84 0xc80
427 .long do_IRQ ! 85 0xca0
428 .long do_IRQ ! 86 0xcc0
429 .long do_IRQ ! 87 0xce0
430 .long do_IRQ ! 88 0xd00
431 .long do_IRQ ! 89 0xd20
432 .long do_IRQ ! 90 0xd40
433 .long do_IRQ ! 91 0xd60
434 .long do_IRQ ! 92 0xd80
435 .long do_IRQ ! 93 0xda0
436 .long do_IRQ ! 94 0xdc0
437 .long do_IRQ ! 95 0xde0
438 .long do_IRQ ! 96 0xe00
439 .long do_IRQ ! 97 0xe20
440 .long do_IRQ ! 98 0xe40
441 .long do_IRQ ! 99 0xe60
442 .long do_IRQ ! 100 0xe80
443 .long do_IRQ ! 101 0xea0
444 .long do_IRQ ! 102 0xec0
445 .long do_IRQ ! 103 0xee0
446 .long do_IRQ ! 104 0xf00
447 .long do_IRQ ! 105 0xf20
448 .long do_IRQ ! 106 0xf40
449 .long do_IRQ ! 107 0xf60
450 .long do_IRQ ! 108 0xf80
451#endif
452#else
453 .long exception_error /* 400 */
454 .long exception_error
455 .long exception_error
456 .long exception_error
457 .long do_IRQ ! RTC ati
458 .long do_IRQ ! pri
459 .long do_IRQ ! cui
460 .long exception_error
461 .long exception_error /* 500 */
462 .long exception_error
463 .long exception_error
464 .long do_IRQ ! WDT iti /* 560 */
465 .long do_IRQ ! TMU-ch0
466 .long do_IRQ ! TMU-ch1
467 .long do_IRQ ! TMU-ch2
468 .long do_IRQ ! ticpi2 /* 5E0 */
469 .long do_IRQ ! 32 Hitachi UDI /* 600 */
470 .long exception_error
471 .long do_IRQ ! 34 DMAC dmte0
472 .long do_IRQ ! 35 dmte1
473 .long do_IRQ ! 36 dmte2
474 .long do_IRQ ! 37 dmte3
475 .long do_IRQ ! 38 dmae
476 .long exception_error ! 39 /* 6E0 */
477 .long do_IRQ ! 40 SCIF-ch0 eri /* 700 */
478 .long do_IRQ ! 41 rxi
479 .long do_IRQ ! 42 bri
480 .long do_IRQ ! 43 txi
481 .long do_IRQ ! 44 DMAC dmte4 /* 780 */
482 .long do_IRQ ! 45 dmte5
483 .long do_IRQ ! 46 dmte6
484 .long do_IRQ ! 47 dmte7 /* 7E0 */
485#if defined(CONFIG_SH_FPU)
486 .long do_fpu_state_restore ! 48 /* 800 */
487 .long do_fpu_state_restore ! 49 /* 820 */
488#else
489 .long exception_error
490 .long exception_error
491#endif
492 .long exception_error /* 840 */
493 .long exception_error
494 .long exception_error
495 .long exception_error
496 .long exception_error
497 .long exception_error
498 .long do_IRQ ! 56 CMT /* 900 */
499 .long exception_error
500 .long exception_error
501 .long exception_error
502 .long do_IRQ ! 60 HAC
503 .long exception_error
504 .long exception_error
505 .long exception_error
506 .long do_IRQ ! PCI serr /* A00 */
507 .long do_IRQ ! INTA
508 .long do_IRQ ! INTB
509 .long do_IRQ ! INTC
510 .long do_IRQ ! INTD
511 .long do_IRQ ! err
512 .long do_IRQ ! pwd3
513 .long do_IRQ ! pwd2
514 .long do_IRQ ! pwd1 /* B00 */
515 .long do_IRQ ! pwd0
516 .long exception_error
517 .long exception_error
518 .long do_IRQ ! SCIF-ch1 eri /* B80 */
519 .long do_IRQ ! rxi
520 .long do_IRQ ! bri
521 .long do_IRQ ! txi
522 .long do_IRQ ! SIOF /* C00 */
523 .long exception_error
524 .long exception_error
525 .long exception_error
526 .long do_IRQ ! HSPI /* C80 */
527 .long exception_error
528 .long exception_error
529 .long exception_error
530 .long do_IRQ ! MMCIF fatat /* D00 */
531 .long do_IRQ ! tran
532 .long do_IRQ ! err
533 .long do_IRQ ! frdy
534 .long do_IRQ ! DMAC dmint8 /* D80 */
535 .long do_IRQ ! dmint9
536 .long do_IRQ ! dmint10
537 .long do_IRQ ! dmint11
538 .long do_IRQ ! TMU-ch3 /* E00 */
539 .long do_IRQ ! TMU-ch4
540 .long do_IRQ ! TMU-ch5
541 .long exception_error
542 .long do_IRQ ! SSI
543 .long exception_error
544 .long exception_error
545 .long exception_error
546 .long do_IRQ ! FLCTL flste /* F00 */
547 .long do_IRQ ! fltend
548 .long do_IRQ ! fltrq0
549 .long do_IRQ ! fltrq1
550 .long do_IRQ ! GPIO gpioi0 /* F80 */
551 .long do_IRQ ! gpioi1
552 .long do_IRQ ! gpioi2
553 .long do_IRQ ! gpioi3
554#endif
555
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 97c571fbcdf1..39aaefb2d83f 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -1,9 +1,8 @@
1/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ 1/*
2 *
3 * linux/arch/sh/entry.S 2 * linux/arch/sh/entry.S
4 * 3 *
5 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
6 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 - 2006 Paul Mundt
7 * 6 *
8 * This file is subject to the terms and conditions of the GNU General Public 7 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 8 * License. See the file "COPYING" in the main directory of this archive
@@ -78,7 +77,6 @@ OFF_TRA = (16*4+6*4)
78#define k3 r3 77#define k3 r3
79#define k4 r4 78#define k4 r4
80 79
81#define k_ex_code r2_bank /* r2_bank1 */
82#define g_imask r6 /* r6_bank1 */ 80#define g_imask r6 /* r6_bank1 */
83#define k_g_imask r6_bank /* r6_bank1 */ 81#define k_g_imask r6_bank /* r6_bank1 */
84#define current r7 /* r7_bank1 */ 82#define current r7 /* r7_bank1 */
@@ -691,7 +689,7 @@ interrupt:
6910: 6890:
692#endif /* defined(CONFIG_KGDB_NMI) */ 690#endif /* defined(CONFIG_KGDB_NMI) */
693 bra handle_exception 691 bra handle_exception
694 mov.l @k2, k2 692 mov #-1, k2 ! interrupt exception marker
695 693
696 .align 2 694 .align 2
6971: .long EXPEVT 6951: .long EXPEVT
@@ -717,8 +715,7 @@ ENTRY(handle_exception)
717 add current, k1 715 add current, k1
718 mov k1, r15 ! change to kernel stack 716 mov k1, r15 ! change to kernel stack
719 ! 717 !
7201: mov #-1, k4 7181: mov.l 2f, k1
721 mov.l 2f, k1
722 ! 719 !
723#ifdef CONFIG_SH_DSP 720#ifdef CONFIG_SH_DSP
724 mov.l r2, @-r15 ! Save r2, we need another reg 721 mov.l r2, @-r15 ! Save r2, we need another reg
@@ -763,6 +760,8 @@ skip_save:
763#endif 760#endif
764 ! Save the user registers on the stack. 761 ! Save the user registers on the stack.
765 mov.l k2, @-r15 ! EXPEVT 762 mov.l k2, @-r15 ! EXPEVT
763
764 mov #-1, k4
766 mov.l k4, @-r15 ! set TRA (default: -1) 765 mov.l k4, @-r15 ! set TRA (default: -1)
767 ! 766 !
768 sts.l macl, @-r15 767 sts.l macl, @-r15
@@ -797,8 +796,21 @@ skip_save:
797 mov.l r2, @-r15 796 mov.l r2, @-r15
798 mov.l r1, @-r15 797 mov.l r1, @-r15
799 mov.l r0, @-r15 798 mov.l r0, @-r15
800 ! Then, dispatch to the handler, according to the exception code. 799
801 stc k_ex_code, r8 800 /*
801 * This gets a bit tricky.. in the INTEVT case we don't want to use
802 * the VBR offset as a destination in the jump call table, since all
803 * of the destinations are the same. In this case, (interrupt) sets
804 * a marker in r2 (now r2_bank since SR.RB changed), which we check
805 * to determine the exception type. For all other exceptions, we
806 * forcibly read EXPEVT from memory and fix up the jump address, in
807 * the interrupt exception case we jump to do_IRQ() and defer the
808 * INTEVT read until there. As a bonus, we can also clean up the SR.RB
809 * checks that do_IRQ() was doing..
810 */
811 stc r2_bank, r8
812 cmp/pz r8
813 bf interrupt_exception
802 shlr2 r8 814 shlr2 r8
803 shlr r8 815 shlr r8
804 mov.l 4f, r9 816 mov.l 4f, r9
@@ -806,6 +818,8 @@ skip_save:
806 mov.l @r9, r9 818 mov.l @r9, r9
807 jmp @r9 819 jmp @r9
808 nop 820 nop
821 rts
822 nop
809 823
810 .align 2 824 .align 2
8111: .long 0x00001000 ! DSP=1 8251: .long 0x00001000 ! DSP=1
@@ -813,8 +827,17 @@ skip_save:
8133: .long 0xcfffffff ! RB=0, BL=0 8273: .long 0xcfffffff ! RB=0, BL=0
8144: .long exception_handling_table 8284: .long exception_handling_table
815 829
830interrupt_exception:
831 mov.l 1f, r9
832 jmp @r9
833 nop
834 rts
835 nop
836
837 .align 2
8381: .long do_IRQ
839
816 .align 2 840 .align 2
817ENTRY(exception_none) 841ENTRY(exception_none)
818 rts 842 rts
819 nop 843 nop
820
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index c7ebd6aec951..acf2602569c4 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -11,12 +11,15 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/kernel_stat.h> 12#include <linux/kernel_stat.h>
13#include <linux/seq_file.h> 13#include <linux/seq_file.h>
14#include <linux/io.h>
14#include <asm/irq.h> 15#include <asm/irq.h>
15#include <asm/processor.h> 16#include <asm/processor.h>
16#include <asm/uaccess.h> 17#include <asm/uaccess.h>
17#include <asm/thread_info.h> 18#include <asm/thread_info.h>
18#include <asm/cpu/mmu_context.h> 19#include <asm/cpu/mmu_context.h>
19 20
21atomic_t irq_err_count;
22
20/* 23/*
21 * 'what should we do if we get a hw irq event on an illegal vector'. 24 * 'what should we do if we get a hw irq event on an illegal vector'.
22 * each architecture has to answer this themselves, it doesn't deserve 25 * each architecture has to answer this themselves, it doesn't deserve
@@ -24,6 +27,7 @@
24 */ 27 */
25void ack_bad_irq(unsigned int irq) 28void ack_bad_irq(unsigned int irq)
26{ 29{
30 atomic_inc(&irq_err_count);
27 printk("unexpected IRQ trap at vector %02x\n", irq); 31 printk("unexpected IRQ trap at vector %02x\n", irq);
28} 32}
29 33
@@ -47,8 +51,10 @@ int show_interrupts(struct seq_file *p, void *v)
47 if (!action) 51 if (!action)
48 goto unlock; 52 goto unlock;
49 seq_printf(p, "%3d: ",i); 53 seq_printf(p, "%3d: ",i);
50 seq_printf(p, "%10u ", kstat_irqs(i)); 54 for_each_online_cpu(j)
51 seq_printf(p, " %14s", irq_desc[i].chip->typename); 55 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
56 seq_printf(p, " %14s", irq_desc[i].chip->name);
57 seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq));
52 seq_printf(p, " %s", action->name); 58 seq_printf(p, " %s", action->name);
53 59
54 for (action=action->next; action; action = action->next) 60 for (action=action->next; action; action = action->next)
@@ -56,7 +62,9 @@ int show_interrupts(struct seq_file *p, void *v)
56 seq_putc(p, '\n'); 62 seq_putc(p, '\n');
57unlock: 63unlock:
58 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 64 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
59 } 65 } else if (i == NR_IRQS)
66 seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
67
60 return 0; 68 return 0;
61} 69}
62#endif 70#endif
@@ -78,7 +86,8 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
78 unsigned long r6, unsigned long r7, 86 unsigned long r6, unsigned long r7,
79 struct pt_regs regs) 87 struct pt_regs regs)
80{ 88{
81 int irq = r4; 89 struct pt_regs *old_regs = set_irq_regs(&regs);
90 int irq;
82#ifdef CONFIG_4KSTACKS 91#ifdef CONFIG_4KSTACKS
83 union irq_ctx *curctx, *irqctx; 92 union irq_ctx *curctx, *irqctx;
84#endif 93#endif
@@ -102,20 +111,9 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
102#endif 111#endif
103 112
104#ifdef CONFIG_CPU_HAS_INTEVT 113#ifdef CONFIG_CPU_HAS_INTEVT
105 __asm__ __volatile__ ( 114 irq = (ctrl_inl(INTEVT) >> 5) - 16;
106#ifdef CONFIG_CPU_HAS_SR_RB
107 "stc r2_bank, %0\n\t"
108#else 115#else
109 "mov.l @%1, %0\n\t" 116 irq = r4;
110#endif
111 "shlr2 %0\n\t"
112 "shlr2 %0\n\t"
113 "shlr %0\n\t"
114 "add #-16, %0\n\t"
115 : "=z" (irq), "=r" (r4)
116 : "1" (INTEVT)
117 : "memory"
118 );
119#endif 117#endif
120 118
121 irq = irq_demux(irq); 119 irq = irq_demux(irq);
@@ -139,25 +137,25 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
139 137
140 __asm__ __volatile__ ( 138 __asm__ __volatile__ (
141 "mov %0, r4 \n" 139 "mov %0, r4 \n"
142 "mov %1, r5 \n"
143 "mov r15, r9 \n" 140 "mov r15, r9 \n"
144 "jsr @%2 \n" 141 "jsr @%1 \n"
145 /* swith to the irq stack */ 142 /* swith to the irq stack */
146 " mov %3, r15 \n" 143 " mov %2, r15 \n"
147 /* restore the stack (ring zero) */ 144 /* restore the stack (ring zero) */
148 "mov r9, r15 \n" 145 "mov r9, r15 \n"
149 : /* no outputs */ 146 : /* no outputs */
150 : "r" (irq), "r" (&regs), "r" (__do_IRQ), "r" (isp) 147 : "r" (irq), "r" (generic_handle_irq), "r" (isp)
151 /* XXX: A somewhat excessive clobber list? -PFM */ 148 /* XXX: A somewhat excessive clobber list? -PFM */
152 : "memory", "r0", "r1", "r2", "r3", "r4", 149 : "memory", "r0", "r1", "r2", "r3", "r4",
153 "r5", "r6", "r7", "r8", "t", "pr" 150 "r5", "r6", "r7", "r8", "t", "pr"
154 ); 151 );
155 } else 152 } else
156#endif 153#endif
157 __do_IRQ(irq, &regs); 154 generic_handle_irq(irq);
158 155
159 irq_exit(); 156 irq_exit();
160 157
158 set_irq_regs(old_regs);
161 return 1; 159 return 1;
162} 160}
163 161
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 0b1d5dd7a93b..91516dca4a85 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -5,6 +5,7 @@
5 * Copyright (C) 1995 Linus Torvalds 5 * Copyright (C) 1995 Linus Torvalds
6 * 6 *
7 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima 7 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
8 * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
8 */ 9 */
9 10
10/* 11/*
@@ -290,6 +291,24 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
290static void 291static void
291ubc_set_tracing(int asid, unsigned long pc) 292ubc_set_tracing(int asid, unsigned long pc)
292{ 293{
294#if defined(CONFIG_CPU_SH4A)
295 unsigned long val;
296
297 val = (UBC_CBR_ID_INST | UBC_CBR_RW_READ | UBC_CBR_CE);
298 val |= (UBC_CBR_AIE | UBC_CBR_AIV_SET(asid));
299
300 ctrl_outl(val, UBC_CBR0);
301 ctrl_outl(pc, UBC_CAR0);
302 ctrl_outl(0x0, UBC_CAMR0);
303 ctrl_outl(0x0, UBC_CBCR);
304
305 val = (UBC_CRR_RES | UBC_CRR_PCB | UBC_CRR_BIE);
306 ctrl_outl(val, UBC_CRR0);
307
308 /* Read UBC register that we writed last. For chekking UBC Register changed */
309 val = ctrl_inl(UBC_CRR0);
310
311#else /* CONFIG_CPU_SH4A */
293 ctrl_outl(pc, UBC_BARA); 312 ctrl_outl(pc, UBC_BARA);
294 313
295#ifdef CONFIG_MMU 314#ifdef CONFIG_MMU
@@ -307,6 +326,7 @@ ubc_set_tracing(int asid, unsigned long pc)
307 ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA); 326 ctrl_outw(BBR_INST | BBR_READ, UBC_BBRA);
308 ctrl_outw(BRCR_PCBA, UBC_BRCR); 327 ctrl_outw(BRCR_PCBA, UBC_BRCR);
309 } 328 }
329#endif /* CONFIG_CPU_SH4A */
310} 330}
311 331
312/* 332/*
@@ -359,8 +379,13 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
359#endif 379#endif
360 ubc_set_tracing(asid, next->thread.ubc_pc); 380 ubc_set_tracing(asid, next->thread.ubc_pc);
361 } else { 381 } else {
382#if defined(CONFIG_CPU_SH4A)
383 ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
384 ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
385#else
362 ctrl_outw(0, UBC_BBRA); 386 ctrl_outw(0, UBC_BBRA);
363 ctrl_outw(0, UBC_BBRB); 387 ctrl_outw(0, UBC_BBRB);
388#endif
364 } 389 }
365 390
366 return prev; 391 return prev;
@@ -460,8 +485,13 @@ asmlinkage void break_point_trap(unsigned long r4, unsigned long r5,
460 struct pt_regs regs) 485 struct pt_regs regs)
461{ 486{
462 /* Clear tracing. */ 487 /* Clear tracing. */
488#if defined(CONFIG_CPU_SH4A)
489 ctrl_outl(UBC_CBR_INIT, UBC_CBR0);
490 ctrl_outl(UBC_CRR_INIT, UBC_CRR0);
491#else
463 ctrl_outw(0, UBC_BBRA); 492 ctrl_outw(0, UBC_BBRA);
464 ctrl_outw(0, UBC_BBRB); 493 ctrl_outw(0, UBC_BBRB);
494#endif
465 current->thread.ubc_pc = 0; 495 current->thread.ubc_pc = 0;
466 ubc_usercnt -= 1; 496 ubc_usercnt -= 1;
467 497
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 450c68f1df05..57e708d7b52d 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -47,6 +47,7 @@ unsigned long long __attribute__ ((weak)) sched_clock(void)
47 return (unsigned long long)jiffies * (1000000000 / HZ); 47 return (unsigned long long)jiffies * (1000000000 / HZ);
48} 48}
49 49
50#ifndef CONFIG_GENERIC_TIME
50void do_gettimeofday(struct timeval *tv) 51void do_gettimeofday(struct timeval *tv)
51{ 52{
52 unsigned long seq; 53 unsigned long seq;
@@ -99,6 +100,7 @@ int do_settimeofday(struct timespec *tv)
99 return 0; 100 return 0;
100} 101}
101EXPORT_SYMBOL(do_settimeofday); 102EXPORT_SYMBOL(do_settimeofday);
103#endif /* !CONFIG_GENERIC_TIME */
102 104
103/* last time the RTC clock got updated */ 105/* last time the RTC clock got updated */
104static long last_rtc_update; 106static long last_rtc_update;
@@ -107,13 +109,14 @@ static long last_rtc_update;
107 * handle_timer_tick() needs to keep up the real-time clock, 109 * handle_timer_tick() needs to keep up the real-time clock,
108 * as well as call the "do_timer()" routine every clocktick 110 * as well as call the "do_timer()" routine every clocktick
109 */ 111 */
110void handle_timer_tick(struct pt_regs *regs) 112void handle_timer_tick(void)
111{ 113{
112 do_timer(1); 114 do_timer(1);
113#ifndef CONFIG_SMP 115#ifndef CONFIG_SMP
114 update_process_times(user_mode(regs)); 116 update_process_times(user_mode(get_irq_regs()));
115#endif 117#endif
116 profile_tick(CPU_PROFILING, regs); 118 if (current->pid)
119 profile_tick(CPU_PROFILING);
117 120
118#ifdef CONFIG_HEARTBEAT 121#ifdef CONFIG_HEARTBEAT
119 if (sh_mv.mv_heartbeat != NULL) 122 if (sh_mv.mv_heartbeat != NULL)
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index 205816fcf0da..24927015dc31 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -80,8 +80,7 @@ static unsigned long tmu_timer_get_offset(void)
80 return count; 80 return count;
81} 81}
82 82
83static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id, 83static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
84 struct pt_regs *regs)
85{ 84{
86 unsigned long timer_status; 85 unsigned long timer_status;
87 86
@@ -98,7 +97,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id,
98 * locally disabled. -arca 97 * locally disabled. -arca
99 */ 98 */
100 write_seqlock(&xtime_lock); 99 write_seqlock(&xtime_lock);
101 handle_timer_tick(regs); 100 handle_timer_tick();
102 write_sequnlock(&xtime_lock); 101 write_sequnlock(&xtime_lock);
103 102
104 return IRQ_HANDLED; 103 return IRQ_HANDLED;
@@ -111,60 +110,6 @@ static struct irqaction tmu_irq = {
111 .mask = CPU_MASK_NONE, 110 .mask = CPU_MASK_NONE,
112}; 111};
113 112
114/*
115 * Hah! We'll see if this works (switching from usecs to nsecs).
116 */
117static unsigned long tmu_timer_get_frequency(void)
118{
119 u32 freq;
120 struct timespec ts1, ts2;
121 unsigned long diff_nsec;
122 unsigned long factor;
123
124 /* Setup the timer: We don't want to generate interrupts, just
125 * have it count down at its natural rate.
126 */
127 ctrl_outb(0, TMU_TSTR);
128#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760)
129 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
130#endif
131 ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR);
132 ctrl_outl(0xffffffff, TMU0_TCOR);
133 ctrl_outl(0xffffffff, TMU0_TCNT);
134
135 rtc_sh_get_time(&ts2);
136
137 do {
138 rtc_sh_get_time(&ts1);
139 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
140
141 /* actually start the timer */
142 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
143
144 do {
145 rtc_sh_get_time(&ts2);
146 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
147
148 freq = 0xffffffff - ctrl_inl(TMU0_TCNT);
149 if (ts2.tv_nsec < ts1.tv_nsec) {
150 ts2.tv_nsec += 1000000000;
151 ts2.tv_sec--;
152 }
153
154 diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec);
155
156 /* this should work well if the RTC has a precision of n Hz, where
157 * n is an integer. I don't think we have to worry about the other
158 * cases. */
159 factor = (1000000000 + diff_nsec/2) / diff_nsec;
160
161 if (factor * diff_nsec > 1100000000 ||
162 factor * diff_nsec < 900000000)
163 panic("weird RTC (diff_nsec %ld)", diff_nsec);
164
165 return freq * factor;
166}
167
168static void tmu_clk_init(struct clk *clk) 113static void tmu_clk_init(struct clk *clk)
169{ 114{
170 u8 divisor = TMU0_TCR_INIT & 0x7; 115 u8 divisor = TMU0_TCR_INIT & 0x7;
@@ -232,12 +177,12 @@ struct sys_timer_ops tmu_timer_ops = {
232 .init = tmu_timer_init, 177 .init = tmu_timer_init,
233 .start = tmu_timer_start, 178 .start = tmu_timer_start,
234 .stop = tmu_timer_stop, 179 .stop = tmu_timer_stop,
235 .get_frequency = tmu_timer_get_frequency, 180#ifndef CONFIG_GENERIC_TIME
236 .get_offset = tmu_timer_get_offset, 181 .get_offset = tmu_timer_get_offset,
182#endif
237}; 183};
238 184
239struct sys_timer tmu_timer = { 185struct sys_timer tmu_timer = {
240 .name = "tmu", 186 .name = "tmu",
241 .ops = &tmu_timer_ops, 187 .ops = &tmu_timer_ops,
242}; 188};
243
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index c81e6b67ad30..38c82d890ffd 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -28,6 +28,7 @@ void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
28 split_page(page, order); 28 split_page(page, order);
29 29
30 ret = page_address(page); 30 ret = page_address(page);
31 memset(ret, 0, size);
31 *handle = virt_to_phys(ret); 32 *handle = virt_to_phys(ret);
32 33
33 /* 34 /*
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index b4e50ae323bf..207f1b6eef53 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -34,6 +34,7 @@
34#include <asm/pcic.h> 34#include <asm/pcic.h>
35#include <asm/timer.h> 35#include <asm/timer.h>
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37#include <asm/irq_regs.h>
37 38
38 39
39unsigned int pcic_pin_to_irq(unsigned int pin, char *name); 40unsigned int pcic_pin_to_irq(unsigned int pin, char *name);
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 0251cab4708b..f5ee1ac834bc 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -121,16 +121,6 @@ static struct console prom_debug_console = {
121 .index = -1, 121 .index = -1,
122}; 122};
123 123
124int obp_system_intr(void)
125{
126 if (boot_flags & BOOTME_DEBUG) {
127 printk("OBP: system interrupted\n");
128 prom_halt();
129 return 1;
130 }
131 return 0;
132}
133
134/* 124/*
135 * Process kernel command line switches that are specific to the 125 * Process kernel command line switches that are specific to the
136 * SPARC or that require special low-level processing. 126 * SPARC or that require special low-level processing.
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 346c19a949fd..1dd78c84888a 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -36,11 +36,11 @@ SECTIONS
36 36
37 . = ALIGN(4096); 37 . = ALIGN(4096);
38 __init_begin = .; 38 __init_begin = .;
39 _sinittext = .;
39 .init.text : { 40 .init.text : {
40 _sinittext = .;
41 *(.init.text) 41 *(.init.text)
42 _einittext = .;
43 } 42 }
43 _einittext = .;
44 __init_text_end = .; 44 __init_text_end = .;
45 .init.data : { *(.init.data) } 45 .init.data : { *(.init.data) }
46 . = ALIGN(16); 46 . = ALIGN(16);
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index b27a506309ee..0df7121cef07 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -402,7 +402,7 @@ void srmmu_nocache_calcsize(void)
402 srmmu_nocache_end = SRMMU_NOCACHE_VADDR + srmmu_nocache_size; 402 srmmu_nocache_end = SRMMU_NOCACHE_VADDR + srmmu_nocache_size;
403} 403}
404 404
405void srmmu_nocache_init(void) 405void __init srmmu_nocache_init(void)
406{ 406{
407 unsigned int bitmap_bits; 407 unsigned int bitmap_bits;
408 pgd_t *pgd; 408 pgd_t *pgd;
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 958287448cfe..cc8ad480a204 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -91,16 +91,6 @@ void kernel_enter_debugger(void)
91{ 91{
92} 92}
93 93
94int obp_system_intr(void)
95{
96 if (boot_flags & BOOTME_DEBUG) {
97 printk("OBP: system interrupted\n");
98 prom_halt();
99 return 1;
100 }
101 return 0;
102}
103
104/* 94/*
105 * Process kernel command line switches that are specific to the 95 * Process kernel command line switches that are specific to the
106 * SPARC or that require special low-level processing. 96 * SPARC or that require special low-level processing.
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index c3cdcab29688..44b55f833875 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -660,7 +660,7 @@ next:
660 } 660 }
661 if (old_vector >= 0) { 661 if (old_vector >= 0) {
662 int old_cpu; 662 int old_cpu;
663 for_each_cpu_mask(old_cpu, domain) 663 for_each_cpu_mask(old_cpu, irq_domain[irq])
664 per_cpu(vector_irq, old_cpu)[old_vector] = -1; 664 per_cpu(vector_irq, old_cpu)[old_vector] = -1;
665 } 665 }
666 for_each_cpu_mask(new_cpu, domain) 666 for_each_cpu_mask(new_cpu, domain)
diff --git a/arch/x86_64/kernel/vsmp.c b/arch/x86_64/kernel/vsmp.c
index 044e852bd25e..414caf0c5f9a 100644
--- a/arch/x86_64/kernel/vsmp.c
+++ b/arch/x86_64/kernel/vsmp.c
@@ -14,6 +14,7 @@
14#include <linux/pci_ids.h> 14#include <linux/pci_ids.h>
15#include <linux/pci_regs.h> 15#include <linux/pci_regs.h>
16#include <asm/pci-direct.h> 16#include <asm/pci-direct.h>
17#include <asm/io.h>
17 18
18static int __init vsmp_init(void) 19static int __init vsmp_init(void)
19{ 20{
diff --git a/block/elevator.c b/block/elevator.c
index 487dd3da8853..8ccd163254b8 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -93,21 +93,18 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio)
93 93
94static struct elevator_type *elevator_find(const char *name) 94static struct elevator_type *elevator_find(const char *name)
95{ 95{
96 struct elevator_type *e = NULL; 96 struct elevator_type *e;
97 struct list_head *entry; 97 struct list_head *entry;
98 98
99 list_for_each(entry, &elv_list) { 99 list_for_each(entry, &elv_list) {
100 struct elevator_type *__e;
101 100
102 __e = list_entry(entry, struct elevator_type, list); 101 e = list_entry(entry, struct elevator_type, list);
103 102
104 if (!strcmp(__e->elevator_name, name)) { 103 if (!strcmp(e->elevator_name, name))
105 e = __e; 104 return e;
106 break;
107 }
108 } 105 }
109 106
110 return e; 107 return NULL;
111} 108}
112 109
113static void elevator_put(struct elevator_type *e) 110static void elevator_put(struct elevator_type *e)
@@ -1088,7 +1085,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
1088 struct list_head *entry; 1085 struct list_head *entry;
1089 int len = 0; 1086 int len = 0;
1090 1087
1091 spin_lock_irq(q->queue_lock); 1088 spin_lock_irq(&elv_list_lock);
1092 list_for_each(entry, &elv_list) { 1089 list_for_each(entry, &elv_list) {
1093 struct elevator_type *__e; 1090 struct elevator_type *__e;
1094 1091
@@ -1098,7 +1095,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
1098 else 1095 else
1099 len += sprintf(name+len, "%s ", __e->elevator_name); 1096 len += sprintf(name+len, "%s ", __e->elevator_name);
1100 } 1097 }
1101 spin_unlock_irq(q->queue_lock); 1098 spin_unlock_irq(&elv_list_lock);
1102 1099
1103 len += sprintf(len+name, "\n"); 1100 len += sprintf(len+name, "\n");
1104 return len; 1101 return len;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 69bbb6206a00..bddfebdf91d8 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -597,7 +597,7 @@ static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq)
597 struct cdrom_info *cd = drive->driver_data; 597 struct cdrom_info *cd = drive->driver_data;
598 598
599 ide_init_drive_cmd(rq); 599 ide_init_drive_cmd(rq);
600 rq->cmd_type = REQ_TYPE_BLOCK_PC; 600 rq->cmd_type = REQ_TYPE_ATA_PC;
601 rq->rq_disk = cd->disk; 601 rq->rq_disk = cd->disk;
602} 602}
603 603
@@ -716,7 +716,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
716 ide_error(drive, "request sense failure", stat); 716 ide_error(drive, "request sense failure", stat);
717 return 1; 717 return 1;
718 718
719 } else if (blk_pc_request(rq)) { 719 } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
720 /* All other functions, except for READ. */ 720 /* All other functions, except for READ. */
721 unsigned long flags; 721 unsigned long flags;
722 722
@@ -2023,7 +2023,8 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
2023 } 2023 }
2024 info->last_block = block; 2024 info->last_block = block;
2025 return action; 2025 return action;
2026 } else if (rq->cmd_type == REQ_TYPE_SENSE) { 2026 } else if (rq->cmd_type == REQ_TYPE_SENSE ||
2027 rq->cmd_type == REQ_TYPE_ATA_PC) {
2027 return cdrom_do_packet_command(drive); 2028 return cdrom_do_packet_command(drive);
2028 } else if (blk_pc_request(rq)) { 2029 } else if (blk_pc_request(rq)) {
2029 return cdrom_do_block_pc(drive, rq); 2030 return cdrom_do_block_pc(drive, rq);
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 8b6efcc05058..143302a8e79c 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -160,7 +160,7 @@ static int sh_rtc_open(struct device *dev)
160 tmp |= RCR1_CIE; 160 tmp |= RCR1_CIE;
161 writeb(tmp, rtc->regbase + RCR1); 161 writeb(tmp, rtc->regbase + RCR1);
162 162
163 ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, SA_INTERRUPT, 163 ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED,
164 "sh-rtc period", dev); 164 "sh-rtc period", dev);
165 if (unlikely(ret)) { 165 if (unlikely(ret)) {
166 dev_err(dev, "request period IRQ failed with %d, IRQ %d\n", 166 dev_err(dev, "request period IRQ failed with %d, IRQ %d\n",
@@ -168,7 +168,7 @@ static int sh_rtc_open(struct device *dev)
168 return ret; 168 return ret;
169 } 169 }
170 170
171 ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, SA_INTERRUPT, 171 ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED,
172 "sh-rtc carry", dev); 172 "sh-rtc carry", dev);
173 if (unlikely(ret)) { 173 if (unlikely(ret)) {
174 dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n", 174 dev_err(dev, "request carry IRQ failed with %d, IRQ %d\n",
@@ -177,7 +177,7 @@ static int sh_rtc_open(struct device *dev)
177 goto err_bad_carry; 177 goto err_bad_carry;
178 } 178 }
179 179
180 ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, SA_INTERRUPT, 180 ret = request_irq(rtc->alarm_irq, sh_rtc_interrupt, IRQF_DISABLED,
181 "sh-rtc alarm", dev); 181 "sh-rtc alarm", dev);
182 if (unlikely(ret)) { 182 if (unlikely(ret)) {
183 dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n", 183 dev_err(dev, "request alarm IRQ failed with %d, IRQ %d\n",
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index d27e4f6d7045..0d3660c28f7d 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -4,10 +4,8 @@
4 * Copyright (C) 2001 David S. Miller (davem@redhat.com) 4 * Copyright (C) 2001 David S. Miller (davem@redhat.com)
5 */ 5 */
6 6
7#include <linux/kernel.h>
8#include <linux/kthread.h> 7#include <linux/kthread.h>
9#include <linux/sched.h> 8#include <linux/syscalls.h>
10#include <linux/slab.h>
11#include <linux/delay.h> 9#include <linux/delay.h>
12#include <asm/oplib.h> 10#include <asm/oplib.h>
13#include <asm/ebus.h> 11#include <asm/ebus.h>
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 728a133d0fc5..6b6a855f3795 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -20,16 +20,12 @@
20 */ 20 */
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/sched.h> 23#include <linux/init.h>
24#include <linux/kthread.h> 24#include <linux/kthread.h>
25#include <linux/errno.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/ioport.h> 26#include <linux/ioport.h>
28#include <linux/init.h>
29#include <linux/miscdevice.h> 27#include <linux/miscdevice.h>
30#include <linux/mm.h> 28#include <linux/syscalls.h>
31#include <linux/slab.h>
32#include <linux/kernel.h>
33 29
34#include <asm/ebus.h> 30#include <asm/ebus.h>
35#include <asm/uaccess.h> 31#include <asm/uaccess.h>
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 266aa325569e..cfcc3caf49d8 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -808,7 +808,7 @@ static int sci_request_irq(struct sci_port *port)
808 } 808 }
809 809
810 if (request_irq(port->irqs[0], sci_mpxed_interrupt, 810 if (request_irq(port->irqs[0], sci_mpxed_interrupt,
811 SA_INTERRUPT, "sci", port)) { 811 IRQF_DISABLED, "sci", port)) {
812 printk(KERN_ERR "sci: Cannot allocate irq.\n"); 812 printk(KERN_ERR "sci: Cannot allocate irq.\n");
813 return -ENODEV; 813 return -ENODEV;
814 } 814 }
@@ -817,7 +817,7 @@ static int sci_request_irq(struct sci_port *port)
817 if (!port->irqs[i]) 817 if (!port->irqs[i])
818 continue; 818 continue;
819 if (request_irq(port->irqs[i], handlers[i], 819 if (request_irq(port->irqs[i], handlers[i],
820 SA_INTERRUPT, desc[i], port)) { 820 IRQF_DISABLED, desc[i], port)) {
821 printk(KERN_ERR "sci: Cannot allocate irq.\n"); 821 printk(KERN_ERR "sci: Cannot allocate irq.\n");
822 return -ENODEV; 822 return -ENODEV;
823 } 823 }
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 73dd2eedaaad..b2cc703b2b9e 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1182,7 +1182,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
1182 return 0; 1182 return 0;
1183} 1183}
1184 1184
1185static struct console sunzilog_console = { 1185static struct console sunzilog_console_ops = {
1186 .name = "ttyS", 1186 .name = "ttyS",
1187 .write = sunzilog_console_write, 1187 .write = sunzilog_console_write,
1188 .device = uart_console_device, 1188 .device = uart_console_device,
@@ -1208,10 +1208,10 @@ static inline struct console *SUNZILOG_CONSOLE(void)
1208 if (i == NUM_CHANNELS) 1208 if (i == NUM_CHANNELS)
1209 return NULL; 1209 return NULL;
1210 1210
1211 sunzilog_console.index = i; 1211 sunzilog_console_ops.index = i;
1212 sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS; 1212 sunzilog_port_table[i].flags |= SUNZILOG_FLAG_IS_CONS;
1213 1213
1214 return &sunzilog_console; 1214 return &sunzilog_console_ops;
1215} 1215}
1216 1216
1217#else 1217#else
diff --git a/fs/Kconfig b/fs/Kconfig
index db4d13324c36..6a3df055280a 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -1986,7 +1986,7 @@ config CIFS_EXPERIMENTAL
1986config CIFS_UPCALL 1986config CIFS_UPCALL
1987 bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)" 1987 bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
1988 depends on CIFS_EXPERIMENTAL 1988 depends on CIFS_EXPERIMENTAL
1989 select CONNECTOR 1989 depends on CONNECTOR
1990 help 1990 help
1991 Enables an upcall mechanism for CIFS which will be used to contact 1991 Enables an upcall mechanism for CIFS which will be used to contact
1992 userspace helper utilities to provide SPNEGO packaged Kerberos 1992 userspace helper utilities to provide SPNEGO packaged Kerberos
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 06435f3665f4..561006127902 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1152,7 +1152,7 @@ static int dump_write(struct file *file, const void *addr, int nr)
1152static int dump_seek(struct file *file, loff_t off) 1152static int dump_seek(struct file *file, loff_t off)
1153{ 1153{
1154 if (file->f_op->llseek && file->f_op->llseek != no_llseek) { 1154 if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
1155 if (file->f_op->llseek(file, off, 1) != off) 1155 if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
1156 return 0; 1156 return 0;
1157 } else { 1157 } else {
1158 char *buf = (char *)get_zeroed_page(GFP_KERNEL); 1158 char *buf = (char *)get_zeroed_page(GFP_KERNEL);
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index d0776ac2b804..5eff35d6e564 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -31,8 +31,8 @@ struct cifs_sid {
31} __attribute__((packed)); 31} __attribute__((packed));
32 32
33/* everyone */ 33/* everyone */
34extern const struct cifs_sid sid_everyone; 34/* extern const struct cifs_sid sid_everyone;*/
35/* group users */ 35/* group users */
36extern const struct cifs_sid sid_user; 36/* extern const struct cifs_sid sid_user;*/
37 37
38#endif /* _CIFSACL_H */ 38#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsencrypt.h b/fs/cifs/cifsencrypt.h
index 03e359b32861..152fa2dcfc6c 100644
--- a/fs/cifs/cifsencrypt.h
+++ b/fs/cifs/cifsencrypt.h
@@ -27,8 +27,6 @@ extern void mdfour(unsigned char *out, unsigned char *in, int n);
27/* smbdes.c */ 27/* smbdes.c */
28extern void E_P16(unsigned char *p14, unsigned char *p16); 28extern void E_P16(unsigned char *p14, unsigned char *p16);
29extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); 29extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
30extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
31extern void E_old_pw_hash(unsigned char *, unsigned char *, unsigned char *);
32 30
33 31
34 32
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index c00c654f2e11..84976cdbe713 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -63,6 +63,7 @@ extern struct task_struct * oplockThread; /* remove sparse warning */
63struct task_struct * oplockThread = NULL; 63struct task_struct * oplockThread = NULL;
64extern struct task_struct * dnotifyThread; /* remove sparse warning */ 64extern struct task_struct * dnotifyThread; /* remove sparse warning */
65struct task_struct * dnotifyThread = NULL; 65struct task_struct * dnotifyThread = NULL;
66static struct super_operations cifs_super_ops;
66unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; 67unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
67module_param(CIFSMaxBufSize, int, 0); 68module_param(CIFSMaxBufSize, int, 0);
68MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); 69MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
@@ -198,10 +199,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
198 /* Only need to call the old QFSInfo if failed 199 /* Only need to call the old QFSInfo if failed
199 on newer one */ 200 on newer one */
200 if(rc) 201 if(rc)
201 rc = CIFSSMBQFSInfo(xid, pTcon, buf); 202 if(pTcon->ses->capabilities & CAP_NT_SMBS)
203 rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
202 204
203 /* Old Windows servers do not support level 103, retry with level 205 /* Some old Windows servers also do not support level 103, retry with
204 one if old server failed the previous call */ 206 older level one if old server failed the previous call or we
207 bypassed it because we detected that this was an older LANMAN sess */
205 if(rc) 208 if(rc)
206 rc = SMBOldQFSInfo(xid, pTcon, buf); 209 rc = SMBOldQFSInfo(xid, pTcon, buf);
207 /* 210 /*
@@ -435,13 +438,21 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
435 return; 438 return;
436} 439}
437 440
441#ifdef CONFIG_CIFS_STATS2
442static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
443{
444 /* BB FIXME */
445 return 0;
446}
447#endif
448
438static int cifs_remount(struct super_block *sb, int *flags, char *data) 449static int cifs_remount(struct super_block *sb, int *flags, char *data)
439{ 450{
440 *flags |= MS_NODIRATIME; 451 *flags |= MS_NODIRATIME;
441 return 0; 452 return 0;
442} 453}
443 454
444struct super_operations cifs_super_ops = { 455static struct super_operations cifs_super_ops = {
445 .read_inode = cifs_read_inode, 456 .read_inode = cifs_read_inode,
446 .put_super = cifs_put_super, 457 .put_super = cifs_put_super,
447 .statfs = cifs_statfs, 458 .statfs = cifs_statfs,
@@ -454,6 +465,9 @@ struct super_operations cifs_super_ops = {
454 .show_options = cifs_show_options, 465 .show_options = cifs_show_options,
455 .umount_begin = cifs_umount_begin, 466 .umount_begin = cifs_umount_begin,
456 .remount_fs = cifs_remount, 467 .remount_fs = cifs_remount,
468#ifdef CONFIG_CIFS_STATS2
469 .show_stats = cifs_show_stats,
470#endif
457}; 471};
458 472
459static int 473static int
@@ -495,7 +509,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
495static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) 509static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
496{ 510{
497 /* origin == SEEK_END => we must revalidate the cached file length */ 511 /* origin == SEEK_END => we must revalidate the cached file length */
498 if (origin == 2) { 512 if (origin == SEEK_END) {
499 int retval = cifs_revalidate(file->f_dentry); 513 int retval = cifs_revalidate(file->f_dentry);
500 if (retval < 0) 514 if (retval < 0)
501 return (loff_t)retval; 515 return (loff_t)retval;
@@ -903,7 +917,7 @@ init_cifs(void)
903#ifdef CONFIG_PROC_FS 917#ifdef CONFIG_PROC_FS
904 cifs_proc_init(); 918 cifs_proc_init();
905#endif 919#endif
906 INIT_LIST_HEAD(&GlobalServerList); /* BB not implemented yet */ 920/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */
907 INIT_LIST_HEAD(&GlobalSMBSessionList); 921 INIT_LIST_HEAD(&GlobalSMBSessionList);
908 INIT_LIST_HEAD(&GlobalTreeConnectionList); 922 INIT_LIST_HEAD(&GlobalTreeConnectionList);
909 INIT_LIST_HEAD(&GlobalOplock_Q); 923 INIT_LIST_HEAD(&GlobalOplock_Q);
@@ -931,6 +945,7 @@ init_cifs(void)
931 GlobalCurrentXid = 0; 945 GlobalCurrentXid = 0;
932 GlobalTotalActiveXid = 0; 946 GlobalTotalActiveXid = 0;
933 GlobalMaxActiveXid = 0; 947 GlobalMaxActiveXid = 0;
948 memset(Local_System_Name, 0, 15);
934 rwlock_init(&GlobalSMBSeslock); 949 rwlock_init(&GlobalSMBSeslock);
935 spin_lock_init(&GlobalMid_Lock); 950 spin_lock_init(&GlobalMid_Lock);
936 951
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index bea875d9a46a..a243f779b363 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -36,7 +36,7 @@ extern const struct address_space_operations cifs_addr_ops;
36extern const struct address_space_operations cifs_addr_ops_smallbuf; 36extern const struct address_space_operations cifs_addr_ops_smallbuf;
37 37
38/* Functions related to super block operations */ 38/* Functions related to super block operations */
39extern struct super_operations cifs_super_ops; 39/* extern struct super_operations cifs_super_ops;*/
40extern void cifs_read_inode(struct inode *); 40extern void cifs_read_inode(struct inode *);
41extern void cifs_delete_inode(struct inode *); 41extern void cifs_delete_inode(struct inode *);
42/* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */ 42/* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b24006c47df1..74d3ccbb103b 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -153,7 +153,7 @@ struct TCP_Server_Info {
153 char sessid[4]; /* unique token id for this session */ 153 char sessid[4]; /* unique token id for this session */
154 /* (returned on Negotiate */ 154 /* (returned on Negotiate */
155 int capabilities; /* allow selective disabling of caps by smb sess */ 155 int capabilities; /* allow selective disabling of caps by smb sess */
156 __u16 timeZone; 156 int timeAdj; /* Adjust for difference in server time zone in sec */
157 __u16 CurrentMid; /* multiplex id - rotating counter */ 157 __u16 CurrentMid; /* multiplex id - rotating counter */
158 char cryptKey[CIFS_CRYPTO_KEY_SIZE]; 158 char cryptKey[CIFS_CRYPTO_KEY_SIZE];
159 /* 16th byte of RFC1001 workstation name is always null */ 159 /* 16th byte of RFC1001 workstation name is always null */
@@ -203,9 +203,14 @@ struct cifsSesInfo {
203 char * domainName; 203 char * domainName;
204 char * password; 204 char * password;
205}; 205};
206/* session flags */ 206/* no more than one of the following three session flags may be set */
207#define CIFS_SES_NT4 1 207#define CIFS_SES_NT4 1
208 208#define CIFS_SES_OS2 2
209#define CIFS_SES_W9X 4
210/* following flag is set for old servers such as OS2 (and Win95?)
211 which do not negotiate NTLM or POSIX dialects, but instead
212 negotiate one of the older LANMAN dialects */
213#define CIFS_SES_LANMAN 8
209/* 214/*
210 * there is one of these for each connection to a resource on a particular 215 * there is one of these for each connection to a resource on a particular
211 * session 216 * session
@@ -512,7 +517,8 @@ require use of the stronger protocol */
512 * This list helps improve performance and eliminate the messages indicating 517 * This list helps improve performance and eliminate the messages indicating
513 * that we had a communications error talking to the server in this list. 518 * that we had a communications error talking to the server in this list.
514 */ 519 */
515GLOBAL_EXTERN struct servers_not_supported *NotSuppList; /*@z4a */ 520/* Feature not supported */
521/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */
516 522
517/* 523/*
518 * The following is a hash table of all the users we know about. 524 * The following is a hash table of all the users we know about.
@@ -568,7 +574,6 @@ GLOBAL_EXTERN unsigned int lookupCacheEnabled;
568GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 574GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
569 with more secure ntlmssp2 challenge/resp */ 575 with more secure ntlmssp2 challenge/resp */
570GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ 576GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */
571GLOBAL_EXTERN unsigned int secFlags;
572GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ 577GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
573GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ 578GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */
574GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ 579GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 81df2bf8e75a..6df9dadba647 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -26,7 +26,8 @@
26 26
27#ifdef CONFIG_CIFS_WEAK_PW_HASH 27#ifdef CONFIG_CIFS_WEAK_PW_HASH
28#define LANMAN_PROT 0 28#define LANMAN_PROT 0
29#define CIFS_PROT 1 29#define LANMAN2_PROT 1
30#define CIFS_PROT 2
30#else 31#else
31#define CIFS_PROT 0 32#define CIFS_PROT 0
32#endif 33#endif
@@ -408,6 +409,8 @@ typedef struct negotiate_req {
408 409
409/* Dialect index is 13 for LANMAN */ 410/* Dialect index is 13 for LANMAN */
410 411
412#define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */
413
411typedef struct lanman_neg_rsp { 414typedef struct lanman_neg_rsp {
412 struct smb_hdr hdr; /* wct = 13 */ 415 struct smb_hdr hdr; /* wct = 13 */
413 __le16 DialectIndex; 416 __le16 DialectIndex;
@@ -417,7 +420,10 @@ typedef struct lanman_neg_rsp {
417 __le16 MaxNumberVcs; 420 __le16 MaxNumberVcs;
418 __le16 RawMode; 421 __le16 RawMode;
419 __le32 SessionKey; 422 __le32 SessionKey;
420 __le32 ServerTime; 423 struct {
424 __le16 Time;
425 __le16 Date;
426 } __attribute__((packed)) SrvTime;
421 __le16 ServerTimeZone; 427 __le16 ServerTimeZone;
422 __le16 EncryptionKeyLength; 428 __le16 EncryptionKeyLength;
423 __le16 Reserved; 429 __le16 Reserved;
@@ -674,7 +680,7 @@ typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
674typedef struct smb_com_close_req { 680typedef struct smb_com_close_req {
675 struct smb_hdr hdr; /* wct = 3 */ 681 struct smb_hdr hdr; /* wct = 3 */
676 __u16 FileID; 682 __u16 FileID;
677 __u32 LastWriteTime; /* should be zero */ 683 __u32 LastWriteTime; /* should be zero or -1 */
678 __u16 ByteCount; /* 0 */ 684 __u16 ByteCount; /* 0 */
679} __attribute__((packed)) CLOSE_REQ; 685} __attribute__((packed)) CLOSE_REQ;
680 686
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index b35c55c3c8bb..f1f8225102f0 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -50,12 +50,12 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
50extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 50extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
51 struct kvec *, int /* nvec to send */, 51 struct kvec *, int /* nvec to send */,
52 int * /* type of buf returned */ , const int long_op); 52 int * /* type of buf returned */ , const int long_op);
53extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *, 53extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
54 struct cifsTconInfo *,
54 struct smb_hdr * /* input */ , 55 struct smb_hdr * /* input */ ,
55 struct smb_hdr * /* out */ , 56 struct smb_hdr * /* out */ ,
56 int * /* bytes returned */); 57 int * /* bytes returned */);
57extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); 58extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
58extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
59extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); 59extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
60extern int is_size_safe_to_change(struct cifsInodeInfo *); 60extern int is_size_safe_to_change(struct cifsInodeInfo *);
61extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); 61extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
@@ -80,6 +80,9 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
80extern void DeleteOplockQEntry(struct oplock_q_entry *); 80extern void DeleteOplockQEntry(struct oplock_q_entry *);
81extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); 81extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
82extern u64 cifs_UnixTimeToNT(struct timespec); 82extern u64 cifs_UnixTimeToNT(struct timespec);
83extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
84extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
85
83extern int cifs_get_inode_info(struct inode **pinode, 86extern int cifs_get_inode_info(struct inode **pinode,
84 const unsigned char *search_path, 87 const unsigned char *search_path,
85 FILE_ALL_INFO * pfile_info, 88 FILE_ALL_INFO * pfile_info,
@@ -116,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
116extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 119extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
117 const unsigned char *searchName, 120 const unsigned char *searchName,
118 FILE_ALL_INFO * findData, 121 FILE_ALL_INFO * findData,
122 int legacy /* whether to use old info level */,
119 const struct nls_table *nls_codepage, int remap); 123 const struct nls_table *nls_codepage, int remap);
120extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 124extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
121 const unsigned char *searchName, 125 const unsigned char *searchName,
@@ -279,8 +283,6 @@ extern void sesInfoFree(struct cifsSesInfo *);
279extern struct cifsTconInfo *tconInfoAlloc(void); 283extern struct cifsTconInfo *tconInfoAlloc(void);
280extern void tconInfoFree(struct cifsTconInfo *); 284extern void tconInfoFree(struct cifsTconInfo *);
281 285
282extern int cifs_reconnect(struct TCP_Server_Info *server);
283
284extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); 286extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
285extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 287extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
286 __u32 *); 288 __u32 *);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 075d8fb3d376..5dc5a966bd5f 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -46,6 +46,7 @@ static struct {
46} protocols[] = { 46} protocols[] = {
47#ifdef CONFIG_CIFS_WEAK_PW_HASH 47#ifdef CONFIG_CIFS_WEAK_PW_HASH
48 {LANMAN_PROT, "\2LM1.2X002"}, 48 {LANMAN_PROT, "\2LM1.2X002"},
49 {LANMAN2_PROT, "\2LANMAN2.1"},
49#endif /* weak password hashing for legacy clients */ 50#endif /* weak password hashing for legacy clients */
50 {CIFS_PROT, "\2NT LM 0.12"}, 51 {CIFS_PROT, "\2NT LM 0.12"},
51 {POSIX_PROT, "\2POSIX 2"}, 52 {POSIX_PROT, "\2POSIX 2"},
@@ -58,6 +59,7 @@ static struct {
58} protocols[] = { 59} protocols[] = {
59#ifdef CONFIG_CIFS_WEAK_PW_HASH 60#ifdef CONFIG_CIFS_WEAK_PW_HASH
60 {LANMAN_PROT, "\2LM1.2X002"}, 61 {LANMAN_PROT, "\2LM1.2X002"},
62 {LANMAN2_PROT, "\2LANMAN2.1"},
61#endif /* weak password hashing for legacy clients */ 63#endif /* weak password hashing for legacy clients */
62 {CIFS_PROT, "\2NT LM 0.12"}, 64 {CIFS_PROT, "\2NT LM 0.12"},
63 {BAD_PROT, "\2"} 65 {BAD_PROT, "\2"}
@@ -67,13 +69,13 @@ static struct {
67/* define the number of elements in the cifs dialect array */ 69/* define the number of elements in the cifs dialect array */
68#ifdef CONFIG_CIFS_POSIX 70#ifdef CONFIG_CIFS_POSIX
69#ifdef CONFIG_CIFS_WEAK_PW_HASH 71#ifdef CONFIG_CIFS_WEAK_PW_HASH
70#define CIFS_NUM_PROT 3 72#define CIFS_NUM_PROT 4
71#else 73#else
72#define CIFS_NUM_PROT 2 74#define CIFS_NUM_PROT 2
73#endif /* CIFS_WEAK_PW_HASH */ 75#endif /* CIFS_WEAK_PW_HASH */
74#else /* not posix */ 76#else /* not posix */
75#ifdef CONFIG_CIFS_WEAK_PW_HASH 77#ifdef CONFIG_CIFS_WEAK_PW_HASH
76#define CIFS_NUM_PROT 2 78#define CIFS_NUM_PROT 3
77#else 79#else
78#define CIFS_NUM_PROT 1 80#define CIFS_NUM_PROT 1
79#endif /* CONFIG_CIFS_WEAK_PW_HASH */ 81#endif /* CONFIG_CIFS_WEAK_PW_HASH */
@@ -446,7 +448,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
446 goto neg_err_exit; 448 goto neg_err_exit;
447#ifdef CONFIG_CIFS_WEAK_PW_HASH 449#ifdef CONFIG_CIFS_WEAK_PW_HASH
448 } else if((pSMBr->hdr.WordCount == 13) 450 } else if((pSMBr->hdr.WordCount == 13)
449 && (pSMBr->DialectIndex == LANMAN_PROT)) { 451 && ((pSMBr->DialectIndex == LANMAN_PROT)
452 || (pSMBr->DialectIndex == LANMAN2_PROT))) {
453 __s16 tmp;
450 struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr; 454 struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr;
451 455
452 if((secFlags & CIFSSEC_MAY_LANMAN) || 456 if((secFlags & CIFSSEC_MAY_LANMAN) ||
@@ -472,12 +476,44 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
472 server->maxRw = 0;/* we do not need to use raw anyway */ 476 server->maxRw = 0;/* we do not need to use raw anyway */
473 server->capabilities = CAP_MPX_MODE; 477 server->capabilities = CAP_MPX_MODE;
474 } 478 }
475 server->timeZone = le16_to_cpu(rsp->ServerTimeZone); 479 tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
480 if (tmp == -1) {
481 /* OS/2 often does not set timezone therefore
482 * we must use server time to calc time zone.
483 * Could deviate slightly from the right zone.
484 * Smallest defined timezone difference is 15 minutes
485 * (i.e. Nepal). Rounding up/down is done to match
486 * this requirement.
487 */
488 int val, seconds, remain, result;
489 struct timespec ts, utc;
490 utc = CURRENT_TIME;
491 ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
492 le16_to_cpu(rsp->SrvTime.Time));
493 cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d",
494 (int)ts.tv_sec, (int)utc.tv_sec,
495 (int)(utc.tv_sec - ts.tv_sec)));
496 val = (int)(utc.tv_sec - ts.tv_sec);
497 seconds = val < 0 ? -val : val;
498 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
499 remain = seconds % MIN_TZ_ADJ;
500 if(remain >= (MIN_TZ_ADJ / 2))
501 result += MIN_TZ_ADJ;
502 if(val < 0)
503 result = - result;
504 server->timeAdj = result;
505 } else {
506 server->timeAdj = (int)tmp;
507 server->timeAdj *= 60; /* also in seconds */
508 }
509 cFYI(1,("server->timeAdj: %d seconds", server->timeAdj));
510
476 511
477 /* BB get server time for time conversions and add 512 /* BB get server time for time conversions and add
478 code to use it and timezone since this is not UTC */ 513 code to use it and timezone since this is not UTC */
479 514
480 if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 515 if (rsp->EncryptionKeyLength ==
516 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
481 memcpy(server->cryptKey, rsp->EncryptionKey, 517 memcpy(server->cryptKey, rsp->EncryptionKey,
482 CIFS_CRYPTO_KEY_SIZE); 518 CIFS_CRYPTO_KEY_SIZE);
483 } else if (server->secMode & SECMODE_PW_ENCRYPT) { 519 } else if (server->secMode & SECMODE_PW_ENCRYPT) {
@@ -531,7 +567,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
531 cFYI(0, ("Max buf = %d", ses->server->maxBuf)); 567 cFYI(0, ("Max buf = %d", ses->server->maxBuf));
532 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); 568 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
533 server->capabilities = le32_to_cpu(pSMBr->Capabilities); 569 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
534 server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); 570 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
571 server->timeAdj *= 60;
535 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 572 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
536 memcpy(server->cryptKey, pSMBr->u.EncryptionKey, 573 memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
537 CIFS_CRYPTO_KEY_SIZE); 574 CIFS_CRYPTO_KEY_SIZE);
@@ -1617,7 +1654,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1617 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ 1654 pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
1618 1655
1619 pSMB->FileID = (__u16) smb_file_id; 1656 pSMB->FileID = (__u16) smb_file_id;
1620 pSMB->LastWriteTime = 0; 1657 pSMB->LastWriteTime = 0xFFFFFFFF;
1621 pSMB->ByteCount = 0; 1658 pSMB->ByteCount = 0;
1622 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, 1659 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1623 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 1660 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2773,9 +2810,11 @@ GetExtAttrOut:
2773 2810
2774 2811
2775/* security id for everyone */ 2812/* security id for everyone */
2776const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; 2813const static struct cifs_sid sid_everyone =
2814 {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
2777/* group users */ 2815/* group users */
2778const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; 2816const static struct cifs_sid sid_user =
2817 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
2779 2818
2780/* Convert CIFS ACL to POSIX form */ 2819/* Convert CIFS ACL to POSIX form */
2781static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) 2820static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
@@ -2856,7 +2895,6 @@ qsec_out:
2856 return rc; 2895 return rc;
2857} 2896}
2858 2897
2859
2860/* Legacy Query Path Information call for lookup to old servers such 2898/* Legacy Query Path Information call for lookup to old servers such
2861 as Win9x/WinME */ 2899 as Win9x/WinME */
2862int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 2900int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
@@ -2898,7 +2936,16 @@ QInfRetry:
2898 if (rc) { 2936 if (rc) {
2899 cFYI(1, ("Send error in QueryInfo = %d", rc)); 2937 cFYI(1, ("Send error in QueryInfo = %d", rc));
2900 } else if (pFinfo) { /* decode response */ 2938 } else if (pFinfo) { /* decode response */
2939 struct timespec ts;
2940 __u32 time = le32_to_cpu(pSMBr->last_write_time);
2941 /* BB FIXME - add time zone adjustment BB */
2901 memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); 2942 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
2943 ts.tv_nsec = 0;
2944 ts.tv_sec = time;
2945 /* decode time fields */
2946 pFinfo->ChangeTime = cifs_UnixTimeToNT(ts);
2947 pFinfo->LastWriteTime = pFinfo->ChangeTime;
2948 pFinfo->LastAccessTime = 0;
2902 pFinfo->AllocationSize = 2949 pFinfo->AllocationSize =
2903 cpu_to_le64(le32_to_cpu(pSMBr->size)); 2950 cpu_to_le64(le32_to_cpu(pSMBr->size));
2904 pFinfo->EndOfFile = pFinfo->AllocationSize; 2951 pFinfo->EndOfFile = pFinfo->AllocationSize;
@@ -2922,6 +2969,7 @@ int
2922CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 2969CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
2923 const unsigned char *searchName, 2970 const unsigned char *searchName,
2924 FILE_ALL_INFO * pFindData, 2971 FILE_ALL_INFO * pFindData,
2972 int legacy /* old style infolevel */,
2925 const struct nls_table *nls_codepage, int remap) 2973 const struct nls_table *nls_codepage, int remap)
2926{ 2974{
2927/* level 263 SMB_QUERY_FILE_ALL_INFO */ 2975/* level 263 SMB_QUERY_FILE_ALL_INFO */
@@ -2970,7 +3018,10 @@ QPathInfoRetry:
2970 byte_count = params + 1 /* pad */ ; 3018 byte_count = params + 1 /* pad */ ;
2971 pSMB->TotalParameterCount = cpu_to_le16(params); 3019 pSMB->TotalParameterCount = cpu_to_le16(params);
2972 pSMB->ParameterCount = pSMB->TotalParameterCount; 3020 pSMB->ParameterCount = pSMB->TotalParameterCount;
2973 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); 3021 if(legacy)
3022 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
3023 else
3024 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
2974 pSMB->Reserved4 = 0; 3025 pSMB->Reserved4 = 0;
2975 pSMB->hdr.smb_buf_length += byte_count; 3026 pSMB->hdr.smb_buf_length += byte_count;
2976 pSMB->ByteCount = cpu_to_le16(byte_count); 3027 pSMB->ByteCount = cpu_to_le16(byte_count);
@@ -2982,13 +3033,24 @@ QPathInfoRetry:
2982 } else { /* decode response */ 3033 } else { /* decode response */
2983 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3034 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
2984 3035
2985 if (rc || (pSMBr->ByteCount < 40)) 3036 if (rc) /* BB add auto retry on EOPNOTSUPP? */
3037 rc = -EIO;
3038 else if (!legacy && (pSMBr->ByteCount < 40))
2986 rc = -EIO; /* bad smb */ 3039 rc = -EIO; /* bad smb */
3040 else if(legacy && (pSMBr->ByteCount < 24))
3041 rc = -EIO; /* 24 or 26 expected but we do not read last field */
2987 else if (pFindData){ 3042 else if (pFindData){
3043 int size;
2988 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); 3044 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3045 if(legacy) /* we do not read the last field, EAsize, fortunately
3046 since it varies by subdialect and on Set vs. Get, is
3047 two bytes or 4 bytes depending but we don't care here */
3048 size = sizeof(FILE_INFO_STANDARD);
3049 else
3050 size = sizeof(FILE_ALL_INFO);
2989 memcpy((char *) pFindData, 3051 memcpy((char *) pFindData,
2990 (char *) &pSMBr->hdr.Protocol + 3052 (char *) &pSMBr->hdr.Protocol +
2991 data_offset, sizeof (FILE_ALL_INFO)); 3053 data_offset, size);
2992 } else 3054 } else
2993 rc = -ENOMEM; 3055 rc = -ENOMEM;
2994 } 3056 }
@@ -3613,6 +3675,14 @@ getDFSRetry:
3613 strncpy(pSMB->RequestFileName, searchName, name_len); 3675 strncpy(pSMB->RequestFileName, searchName, name_len);
3614 } 3676 }
3615 3677
3678 if(ses->server) {
3679 if(ses->server->secMode &
3680 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3681 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3682 }
3683
3684 pSMB->hdr.Uid = ses->Suid;
3685
3616 params = 2 /* level */ + name_len /*includes null */ ; 3686 params = 2 /* level */ + name_len /*includes null */ ;
3617 pSMB->TotalDataCount = 0; 3687 pSMB->TotalDataCount = 0;
3618 pSMB->DataCount = 0; 3688 pSMB->DataCount = 0;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c78762051da4..4093d5332930 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -109,7 +109,7 @@ static int ipv6_connect(struct sockaddr_in6 *psin_server,
109 * wake up waiters on reconnection? - (not needed currently) 109 * wake up waiters on reconnection? - (not needed currently)
110 */ 110 */
111 111
112int 112static int
113cifs_reconnect(struct TCP_Server_Info *server) 113cifs_reconnect(struct TCP_Server_Info *server)
114{ 114{
115 int rc = 0; 115 int rc = 0;
@@ -771,13 +771,18 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
771 separator[0] = ','; 771 separator[0] = ',';
772 separator[1] = 0; 772 separator[1] = 0;
773 773
774 memset(vol->source_rfc1001_name,0x20,15); 774 if (Local_System_Name[0] != 0)
775 for(i=0;i < strnlen(utsname()->nodename,15);i++) { 775 memcpy(vol->source_rfc1001_name, Local_System_Name,15);
776 /* does not have to be a perfect mapping since the field is 776 else {
777 informational, only used for servers that do not support 777 char *nodename = utsname()->nodename;
778 port 445 and it can be overridden at mount time */ 778 int n = strnlen(nodename,15);
779 vol->source_rfc1001_name[i] = 779 memset(vol->source_rfc1001_name,0x20,15);
780 toupper(utsname()->nodename[i]); 780 for(i=0 ; i < n ; i++) {
781 /* does not have to be perfect mapping since field is
782 informational, only used for servers that do not support
783 port 445 and it can be overridden at mount time */
784 vol->source_rfc1001_name[i] = toupper(nodename[i]);
785 }
781 } 786 }
782 vol->source_rfc1001_name[15] = 0; 787 vol->source_rfc1001_name[15] = 0;
783 /* null target name indicates to use *SMBSERVR default called name 788 /* null target name indicates to use *SMBSERVR default called name
@@ -3215,7 +3220,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3215 } 3220 }
3216 /* else do not bother copying these informational fields */ 3221 /* else do not bother copying these informational fields */
3217 } 3222 }
3218 if(smb_buffer_response->WordCount == 3) 3223 if((smb_buffer_response->WordCount == 3) ||
3224 (smb_buffer_response->WordCount == 7))
3225 /* field is in same location */
3219 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 3226 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3220 else 3227 else
3221 tcon->Flags = 0; 3228 tcon->Flags = 0;
@@ -3312,19 +3319,21 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3312 first_time = 1; 3319 first_time = 1;
3313 } 3320 }
3314 if (!rc) { 3321 if (!rc) {
3322 pSesInfo->flags = 0;
3315 pSesInfo->capabilities = pSesInfo->server->capabilities; 3323 pSesInfo->capabilities = pSesInfo->server->capabilities;
3316 if(linuxExtEnabled == 0) 3324 if(linuxExtEnabled == 0)
3317 pSesInfo->capabilities &= (~CAP_UNIX); 3325 pSesInfo->capabilities &= (~CAP_UNIX);
3318 /* pSesInfo->sequence_number = 0;*/ 3326 /* pSesInfo->sequence_number = 0;*/
3319 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d", 3327 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3320 pSesInfo->server->secMode, 3328 pSesInfo->server->secMode,
3321 pSesInfo->server->capabilities, 3329 pSesInfo->server->capabilities,
3322 pSesInfo->server->timeZone)); 3330 pSesInfo->server->timeAdj));
3323 if(experimEnabled < 2) 3331 if(experimEnabled < 2)
3324 rc = CIFS_SessSetup(xid, pSesInfo, 3332 rc = CIFS_SessSetup(xid, pSesInfo,
3325 first_time, nls_info); 3333 first_time, nls_info);
3326 else if (extended_security 3334 else if (extended_security
3327 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3335 && (pSesInfo->capabilities
3336 & CAP_EXTENDED_SECURITY)
3328 && (pSesInfo->server->secType == NTLMSSP)) { 3337 && (pSesInfo->server->secType == NTLMSSP)) {
3329 rc = -EOPNOTSUPP; 3338 rc = -EOPNOTSUPP;
3330 } else if (extended_security 3339 } else if (extended_security
@@ -3338,7 +3347,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3338 if (!rc) { 3347 if (!rc) {
3339 if(ntlmv2_flag) { 3348 if(ntlmv2_flag) {
3340 char * v2_response; 3349 char * v2_response;
3341 cFYI(1,("Can use more secure NTLM version 2 password hash")); 3350 cFYI(1,("more secure NTLM ver2 hash"));
3342 if(CalcNTLMv2_partial_mac_key(pSesInfo, 3351 if(CalcNTLMv2_partial_mac_key(pSesInfo,
3343 nls_info)) { 3352 nls_info)) {
3344 rc = -ENOMEM; 3353 rc = -ENOMEM;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 6b90ef98e4cf..35d54bb0869a 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -337,6 +337,7 @@ int cifs_get_inode_info(struct inode **pinode,
337 pfindData = (FILE_ALL_INFO *)buf; 337 pfindData = (FILE_ALL_INFO *)buf;
338 /* could do find first instead but this returns more info */ 338 /* could do find first instead but this returns more info */
339 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 339 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
340 0 /* not legacy */,
340 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 341 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
341 CIFS_MOUNT_MAP_SPECIAL_CHR); 342 CIFS_MOUNT_MAP_SPECIAL_CHR);
342 /* BB optimize code so we do not make the above call 343 /* BB optimize code so we do not make the above call
@@ -384,8 +385,10 @@ int cifs_get_inode_info(struct inode **pinode,
384 /* get new inode */ 385 /* get new inode */
385 if (*pinode == NULL) { 386 if (*pinode == NULL) {
386 *pinode = new_inode(sb); 387 *pinode = new_inode(sb);
387 if (*pinode == NULL) 388 if (*pinode == NULL) {
389 kfree(buf);
388 return -ENOMEM; 390 return -ENOMEM;
391 }
389 /* Is an i_ino of zero legal? Can we use that to check 392 /* Is an i_ino of zero legal? Can we use that to check
390 if the server supports returning inode numbers? Are 393 if the server supports returning inode numbers? Are
391 there other sanity checks we can use to ensure that 394 there other sanity checks we can use to ensure that
@@ -431,8 +434,11 @@ int cifs_get_inode_info(struct inode **pinode,
431 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 434 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
432 435
433 /* Linux can not store file creation time so ignore it */ 436 /* Linux can not store file creation time so ignore it */
434 inode->i_atime = 437 if(pfindData->LastAccessTime)
435 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); 438 inode->i_atime = cifs_NTtimeToUnix
439 (le64_to_cpu(pfindData->LastAccessTime));
440 else /* do not need to use current_fs_time - time not stored */
441 inode->i_atime = CURRENT_TIME;
436 inode->i_mtime = 442 inode->i_mtime =
437 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 443 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
438 inode->i_ctime = 444 inode->i_ctime =
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index a57f5d6e6213..0bee8b7e521a 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -254,7 +254,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
254 tmpbuffer, 254 tmpbuffer,
255 len - 1, 255 len - 1,
256 cifs_sb->local_nls); 256 cifs_sb->local_nls);
257 else { 257 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
258 cERROR(1,("SFU style symlinks not implemented yet"));
259 /* add open and read as in fs/cifs/inode.c */
260
261 } else {
258 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, 262 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
259 OPEN_REPARSE_POINT,&fid, &oplock, NULL, 263 OPEN_REPARSE_POINT,&fid, &oplock, NULL,
260 cifs_sb->local_nls, 264 cifs_sb->local_nls,
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c
index 7aa23490541f..ccebf9b7eb86 100644
--- a/fs/cifs/md5.c
+++ b/fs/cifs/md5.c
@@ -252,10 +252,11 @@ MD5Transform(__u32 buf[4], __u32 const in[16])
252 buf[3] += d; 252 buf[3] += d;
253} 253}
254 254
255#if 0 /* currently unused */
255/*********************************************************************** 256/***********************************************************************
256 the rfc 2104 version of hmac_md5 initialisation. 257 the rfc 2104 version of hmac_md5 initialisation.
257***********************************************************************/ 258***********************************************************************/
258void 259static void
259hmac_md5_init_rfc2104(unsigned char *key, int key_len, 260hmac_md5_init_rfc2104(unsigned char *key, int key_len,
260 struct HMACMD5Context *ctx) 261 struct HMACMD5Context *ctx)
261{ 262{
@@ -289,6 +290,7 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len,
289 MD5Init(&ctx->ctx); 290 MD5Init(&ctx->ctx);
290 MD5Update(&ctx->ctx, ctx->k_ipad, 64); 291 MD5Update(&ctx->ctx, ctx->k_ipad, 64);
291} 292}
293#endif
292 294
293/*********************************************************************** 295/***********************************************************************
294 the microsoft version of hmac_md5 initialisation. 296 the microsoft version of hmac_md5 initialisation.
@@ -350,7 +352,8 @@ hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)
350 single function to calculate an HMAC MD5 digest from data. 352 single function to calculate an HMAC MD5 digest from data.
351 use the microsoft hmacmd5 init method because the key is 16 bytes. 353 use the microsoft hmacmd5 init method because the key is 16 bytes.
352************************************************************/ 354************************************************************/
353void 355#if 0 /* currently unused */
356static void
354hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 357hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
355 unsigned char *digest) 358 unsigned char *digest)
356{ 359{
@@ -361,3 +364,4 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
361 } 364 }
362 hmac_md5_final(digest, &ctx); 365 hmac_md5_final(digest, &ctx);
363} 366}
367#endif
diff --git a/fs/cifs/md5.h b/fs/cifs/md5.h
index 00e1c5394fe1..f7d4f4197bac 100644
--- a/fs/cifs/md5.h
+++ b/fs/cifs/md5.h
@@ -27,12 +27,12 @@ void MD5Final(unsigned char digest[16], struct MD5Context *context);
27 27
28/* The following definitions come from lib/hmacmd5.c */ 28/* The following definitions come from lib/hmacmd5.c */
29 29
30void hmac_md5_init_rfc2104(unsigned char *key, int key_len, 30/* void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
31 struct HMACMD5Context *ctx); 31 struct HMACMD5Context *ctx);*/
32void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, 32void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
33 struct HMACMD5Context *ctx); 33 struct HMACMD5Context *ctx);
34void hmac_md5_update(const unsigned char *text, int text_len, 34void hmac_md5_update(const unsigned char *text, int text_len,
35 struct HMACMD5Context *ctx); 35 struct HMACMD5Context *ctx);
36void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); 36void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
37void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, 37/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
38 unsigned char *digest); 38 unsigned char *digest);*/
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 22c937e5884f..bbc9cd34b6ea 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -389,7 +389,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
389 return; 389 return;
390} 390}
391 391
392int 392static int
393checkSMBhdr(struct smb_hdr *smb, __u16 mid) 393checkSMBhdr(struct smb_hdr *smb, __u16 mid)
394{ 394{
395 /* Make sure that this really is an SMB, that it is a response, 395 /* Make sure that this really is an SMB, that it is a response,
@@ -418,26 +418,42 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
418} 418}
419 419
420int 420int
421checkSMB(struct smb_hdr *smb, __u16 mid, int length) 421checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
422{ 422{
423 __u32 len = smb->smb_buf_length; 423 __u32 len = smb->smb_buf_length;
424 __u32 clc_len; /* calculated length */ 424 __u32 clc_len; /* calculated length */
425 cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len)); 425 cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
426 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || 426
427 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { 427 if (length < 2 + sizeof (struct smb_hdr)) {
428 if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { 428 if ((length >= sizeof (struct smb_hdr) - 1)
429 if (((unsigned int)length >=
430 sizeof (struct smb_hdr) - 1)
431 && (smb->Status.CifsError != 0)) { 429 && (smb->Status.CifsError != 0)) {
432 smb->WordCount = 0; 430 smb->WordCount = 0;
433 /* some error cases do not return wct and bcc */ 431 /* some error cases do not return wct and bcc */
432 return 0;
433 } else if ((length == sizeof(struct smb_hdr) + 1) &&
434 (smb->WordCount == 0)) {
435 char * tmp = (char *)smb;
436 /* Need to work around a bug in two servers here */
437 /* First, check if the part of bcc they sent was zero */
438 if (tmp[sizeof(struct smb_hdr)] == 0) {
439 /* some servers return only half of bcc
440 * on simple responses (wct, bcc both zero)
441 * in particular have seen this on
442 * ulogoffX and FindClose. This leaves
443 * one byte of bcc potentially unitialized
444 */
445 /* zero rest of bcc */
446 tmp[sizeof(struct smb_hdr)+1] = 0;
434 return 0; 447 return 0;
435 } else {
436 cERROR(1, ("Length less than smb header size"));
437 } 448 }
449 cERROR(1,("rcvd invalid byte count (bcc)"));
450 } else {
451 cERROR(1, ("Length less than smb header size"));
438 } 452 }
439 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) 453 return 1;
440 cERROR(1, ("smb length greater than MaxBufSize, mid=%d", 454 }
455 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
456 cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
441 smb->Mid)); 457 smb->Mid));
442 return 1; 458 return 1;
443 } 459 }
@@ -446,7 +462,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
446 return 1; 462 return 1;
447 clc_len = smbCalcSize_LE(smb); 463 clc_len = smbCalcSize_LE(smb);
448 464
449 if(4 + len != (unsigned int)length) { 465 if(4 + len != length) {
450 cERROR(1, ("Length read does not match RFC1001 length %d",len)); 466 cERROR(1, ("Length read does not match RFC1001 length %d",len));
451 return 1; 467 return 1;
452 } 468 }
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index ce87550e918f..992e80edc720 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -909,3 +909,61 @@ cifs_UnixTimeToNT(struct timespec t)
909 /* Convert to 100ns intervals and then add the NTFS time offset. */ 909 /* Convert to 100ns intervals and then add the NTFS time offset. */
910 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; 910 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
911} 911}
912
913static int total_days_of_prev_months[] =
914{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
915
916
917__le64 cnvrtDosCifsTm(__u16 date, __u16 time)
918{
919 return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time)));
920}
921
922struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
923{
924 struct timespec ts;
925 int sec, min, days, month, year;
926 SMB_TIME * st = (SMB_TIME *)&time;
927 SMB_DATE * sd = (SMB_DATE *)&date;
928
929 cFYI(1,("date %d time %d",date, time));
930
931 sec = 2 * st->TwoSeconds;
932 min = st->Minutes;
933 if((sec > 59) || (min > 59))
934 cERROR(1,("illegal time min %d sec %d", min, sec));
935 sec += (min * 60);
936 sec += 60 * 60 * st->Hours;
937 if(st->Hours > 24)
938 cERROR(1,("illegal hours %d",st->Hours));
939 days = sd->Day;
940 month = sd->Month;
941 if((days > 31) || (month > 12))
942 cERROR(1,("illegal date, month %d day: %d", month, days));
943 month -= 1;
944 days += total_days_of_prev_months[month];
945 days += 3652; /* account for difference in days between 1980 and 1970 */
946 year = sd->Year;
947 days += year * 365;
948 days += (year/4); /* leap year */
949 /* generalized leap year calculation is more complex, ie no leap year
950 for years/100 except for years/400, but since the maximum number for DOS
951 year is 2**7, the last year is 1980+127, which means we need only
952 consider 2 special case years, ie the years 2000 and 2100, and only
953 adjust for the lack of leap year for the year 2100, as 2000 was a
954 leap year (divisable by 400) */
955 if(year >= 120) /* the year 2100 */
956 days = days - 1; /* do not count leap year for the year 2100 */
957
958 /* adjust for leap year where we are still before leap day */
959 if(year != 120)
960 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
961 sec += 24 * 60 * 60 * days;
962
963 ts.tv_sec = sec;
964
965 /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */
966
967 ts.tv_nsec = 0;
968 return ts;
969}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index b27b34537bf2..b5b0a2a41bef 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -106,6 +106,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
106 return rc; 106 return rc;
107} 107}
108 108
109static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
110{
111 if((tcon) && (tcon->ses) && (tcon->ses->server)) {
112 inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
113 inode->i_mtime.tv_sec += tcon->ses->server->timeAdj;
114 inode->i_atime.tv_sec += tcon->ses->server->timeAdj;
115 }
116 return;
117}
118
119
109static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 120static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
110 char * buf, int *pobject_type, int isNewInode) 121 char * buf, int *pobject_type, int isNewInode)
111{ 122{
@@ -135,16 +146,23 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
135 tmp_inode->i_ctime = 146 tmp_inode->i_ctime =
136 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 147 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
137 } else { /* legacy, OS2 and DOS style */ 148 } else { /* legacy, OS2 and DOS style */
149/* struct timespec ts;*/
138 FIND_FILE_STANDARD_INFO * pfindData = 150 FIND_FILE_STANDARD_INFO * pfindData =
139 (FIND_FILE_STANDARD_INFO *)buf; 151 (FIND_FILE_STANDARD_INFO *)buf;
140 152
153 tmp_inode->i_mtime = cnvrtDosUnixTm(
154 le16_to_cpu(pfindData->LastWriteDate),
155 le16_to_cpu(pfindData->LastWriteTime));
156 tmp_inode->i_atime = cnvrtDosUnixTm(
157 le16_to_cpu(pfindData->LastAccessDate),
158 le16_to_cpu(pfindData->LastAccessTime));
159 tmp_inode->i_ctime = cnvrtDosUnixTm(
160 le16_to_cpu(pfindData->LastWriteDate),
161 le16_to_cpu(pfindData->LastWriteTime));
162 AdjustForTZ(cifs_sb->tcon, tmp_inode);
141 attr = le16_to_cpu(pfindData->Attributes); 163 attr = le16_to_cpu(pfindData->Attributes);
142 allocation_size = le32_to_cpu(pfindData->AllocationSize); 164 allocation_size = le32_to_cpu(pfindData->AllocationSize);
143 end_of_file = le32_to_cpu(pfindData->DataSize); 165 end_of_file = le32_to_cpu(pfindData->DataSize);
144 tmp_inode->i_atime = CURRENT_TIME;
145 /* tmp_inode->i_mtime = BB FIXME - add dos time handling
146 tmp_inode->i_ctime = 0; BB FIXME */
147
148 } 166 }
149 167
150 /* Linux can not store file creation time unfortunately so ignore it */ 168 /* Linux can not store file creation time unfortunately so ignore it */
@@ -938,6 +956,7 @@ static int cifs_save_resume_key(const char *current_entry,
938 filename = &pFindData->FileName[0]; 956 filename = &pFindData->FileName[0];
939 /* one byte length, no name conversion */ 957 /* one byte length, no name conversion */
940 len = (unsigned int)pFindData->FileNameLength; 958 len = (unsigned int)pFindData->FileNameLength;
959 cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
941 } else { 960 } else {
942 cFYI(1,("Unknown findfirst level %d",level)); 961 cFYI(1,("Unknown findfirst level %d",level));
943 return -EINVAL; 962 return -EINVAL;
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 22b4c35dcfe3..a8a083543ba0 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -268,6 +268,10 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
268 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 268 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
269 if(ses->serverOS) 269 if(ses->serverOS)
270 strncpy(ses->serverOS, bcc_ptr, len); 270 strncpy(ses->serverOS, bcc_ptr, len);
271 if(strncmp(ses->serverOS, "OS/2",4) == 0) {
272 cFYI(1,("OS/2 server"));
273 ses->flags |= CIFS_SES_OS2;
274 }
271 275
272 bcc_ptr += len + 1; 276 bcc_ptr += len + 1;
273 bleft -= len + 1; 277 bleft -= len + 1;
@@ -290,16 +294,11 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
290 if(len > bleft) 294 if(len > bleft)
291 return rc; 295 return rc;
292 296
293 if(ses->serverDomain) 297 /* No domain field in LANMAN case. Domain is
294 kfree(ses->serverDomain); 298 returned by old servers in the SMB negprot response */
295 299 /* BB For newer servers which do not support Unicode,
296 ses->serverDomain = kzalloc(len + 1, GFP_KERNEL); 300 but thus do return domain here we could add parsing
297 if(ses->serverOS) 301 for it later, but it is not very important */
298 strncpy(ses->serverOS, bcc_ptr, len);
299
300 bcc_ptr += len + 1;
301 bleft -= len + 1;
302
303 cFYI(1,("ascii: bytes left %d",bleft)); 302 cFYI(1,("ascii: bytes left %d",bleft));
304 303
305 return rc; 304 return rc;
@@ -366,6 +365,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
366 str_area = kmalloc(2000, GFP_KERNEL); 365 str_area = kmalloc(2000, GFP_KERNEL);
367 bcc_ptr = str_area; 366 bcc_ptr = str_area;
368 367
368 ses->flags &= ~CIFS_SES_LANMAN;
369
369 if(type == LANMAN) { 370 if(type == LANMAN) {
370#ifdef CONFIG_CIFS_WEAK_PW_HASH 371#ifdef CONFIG_CIFS_WEAK_PW_HASH
371 char lnm_session_key[CIFS_SESS_KEY_SIZE]; 372 char lnm_session_key[CIFS_SESS_KEY_SIZE];
@@ -377,7 +378,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
377 /* and copy into bcc */ 378 /* and copy into bcc */
378 379
379 calc_lanman_hash(ses, lnm_session_key); 380 calc_lanman_hash(ses, lnm_session_key);
380 381 ses->flags |= CIFS_SES_LANMAN;
381/* #ifdef CONFIG_CIFS_DEBUG2 382/* #ifdef CONFIG_CIFS_DEBUG2
382 cifs_dump_mem("cryptkey: ",ses->server->cryptKey, 383 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
383 CIFS_SESS_KEY_SIZE); 384 CIFS_SESS_KEY_SIZE);
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
index efaa044523a7..7a1b2b961ec8 100644
--- a/fs/cifs/smbdes.c
+++ b/fs/cifs/smbdes.c
@@ -364,20 +364,20 @@ E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
364 smbhash(p24 + 16, c8, p21 + 14, 1); 364 smbhash(p24 + 16, c8, p21 + 14, 1);
365} 365}
366 366
367void 367#if 0 /* currently unsued */
368static void
368D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) 369D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
369{ 370{
370 smbhash(out, in, p14, 0); 371 smbhash(out, in, p14, 0);
371 smbhash(out + 8, in + 8, p14 + 7, 0); 372 smbhash(out + 8, in + 8, p14 + 7, 0);
372} 373}
373 374
374void 375static void
375E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out) 376E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
376{ 377{
377 smbhash(out, in, p14, 1); 378 smbhash(out, in, p14, 1);
378 smbhash(out + 8, in + 8, p14 + 7, 1); 379 smbhash(out + 8, in + 8, p14 + 7, 1);
379} 380}
380#if 0
381/* these routines are currently unneeded, but may be 381/* these routines are currently unneeded, but may be
382 needed later */ 382 needed later */
383void 383void
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index f518c5e45035..4b25ba92180d 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -51,11 +51,8 @@
51 51
52void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 52void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
53void E_md4hash(const unsigned char *passwd, unsigned char *p16); 53void E_md4hash(const unsigned char *passwd, unsigned char *p16);
54void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]);
55static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, 54static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
56 unsigned char p24[24]); 55 unsigned char p24[24]);
57void NTLMSSPOWFencrypt(unsigned char passwd[8],
58 unsigned char *ntlmchalresp, unsigned char p24[24]);
59void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); 56void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
60 57
61/* 58/*
@@ -144,8 +141,9 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
144 memset(wpwd,0,129 * 2); 141 memset(wpwd,0,129 * 2);
145} 142}
146 143
144#if 0 /* currently unused */
147/* Does both the NT and LM owfs of a user's password */ 145/* Does both the NT and LM owfs of a user's password */
148void 146static void
149nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) 147nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
150{ 148{
151 char passwd[514]; 149 char passwd[514];
@@ -171,6 +169,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
171 /* clear out local copy of user's password (just being paranoid). */ 169 /* clear out local copy of user's password (just being paranoid). */
172 memset(passwd, '\0', sizeof (passwd)); 170 memset(passwd, '\0', sizeof (passwd));
173} 171}
172#endif
174 173
175/* Does the NTLMv2 owfs of a user's password */ 174/* Does the NTLMv2 owfs of a user's password */
176#if 0 /* function not needed yet - but will be soon */ 175#if 0 /* function not needed yet - but will be soon */
@@ -223,7 +222,8 @@ SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
223} 222}
224 223
225/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ 224/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
226void 225#if 0 /* currently unused */
226static void
227NTLMSSPOWFencrypt(unsigned char passwd[8], 227NTLMSSPOWFencrypt(unsigned char passwd[8],
228 unsigned char *ntlmchalresp, unsigned char p24[24]) 228 unsigned char *ntlmchalresp, unsigned char p24[24])
229{ 229{
@@ -235,6 +235,7 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],
235 235
236 E_P24(p21, ntlmchalresp, p24); 236 E_P24(p21, ntlmchalresp, p24);
237} 237}
238#endif
238 239
239/* Does the NT MD4 hash then des encryption. */ 240/* Does the NT MD4 hash then des encryption. */
240 241
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 6dc6721d9e82..89e8da112a75 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -150,11 +150,6 @@ int ioprio_best(unsigned short aprio, unsigned short bprio)
150 unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); 150 unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
151 unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); 151 unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
152 152
153 if (!ioprio_valid(aprio))
154 return bprio;
155 if (!ioprio_valid(bprio))
156 return aprio;
157
158 if (aclass == IOPRIO_CLASS_NONE) 153 if (aclass == IOPRIO_CLASS_NONE)
159 aclass = IOPRIO_CLASS_BE; 154 aclass = IOPRIO_CLASS_BE;
160 if (bclass == IOPRIO_CLASS_NONE) 155 if (bclass == IOPRIO_CLASS_NONE)
diff --git a/fs/splice.c b/fs/splice.c
index 13e92dd19fbb..a567010b62ac 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -607,7 +607,7 @@ find_page:
607 ret = -ENOMEM; 607 ret = -ENOMEM;
608 page = page_cache_alloc_cold(mapping); 608 page = page_cache_alloc_cold(mapping);
609 if (unlikely(!page)) 609 if (unlikely(!page))
610 goto out_nomem; 610 goto out_ret;
611 611
612 /* 612 /*
613 * This will also lock the page 613 * This will also lock the page
@@ -666,7 +666,7 @@ find_page:
666 if (sd->pos + this_len > isize) 666 if (sd->pos + this_len > isize)
667 vmtruncate(mapping->host, isize); 667 vmtruncate(mapping->host, isize);
668 668
669 goto out; 669 goto out_ret;
670 } 670 }
671 671
672 if (buf->page != page) { 672 if (buf->page != page) {
@@ -698,7 +698,7 @@ find_page:
698out: 698out:
699 page_cache_release(page); 699 page_cache_release(page);
700 unlock_page(page); 700 unlock_page(page);
701out_nomem: 701out_ret:
702 return ret; 702 return ret;
703} 703}
704 704
diff --git a/include/asm-i386/vic.h b/include/asm-i386/vic.h
index 4abfcfb91eb8..53100f353612 100644
--- a/include/asm-i386/vic.h
+++ b/include/asm-i386/vic.h
@@ -58,4 +58,4 @@ static const int VIC_CPI_Registers[] =
58 58
59#define VIC_BOOT_INTERRUPT_MASK 0xfe 59#define VIC_BOOT_INTERRUPT_MASK 0xfe
60 60
61extern void smp_vic_timer_interrupt(struct pt_regs *regs); 61extern void smp_vic_timer_interrupt(void);
diff --git a/include/asm-i386/voyager.h b/include/asm-i386/voyager.h
index e74c54aa757f..5b27838905b2 100644
--- a/include/asm-i386/voyager.h
+++ b/include/asm-i386/voyager.h
@@ -118,33 +118,33 @@ typedef struct voyager_module {
118} voyager_module_t; 118} voyager_module_t;
119 119
120typedef struct voyager_eeprom_hdr { 120typedef struct voyager_eeprom_hdr {
121 __u8 module_id[4] __attribute__((packed)); 121 __u8 module_id[4];
122 __u8 version_id __attribute__((packed)); 122 __u8 version_id;
123 __u8 config_id __attribute__((packed)); 123 __u8 config_id;
124 __u16 boundry_id __attribute__((packed)); /* boundary scan id */ 124 __u16 boundry_id; /* boundary scan id */
125 __u16 ee_size __attribute__((packed)); /* size of EEPROM */ 125 __u16 ee_size; /* size of EEPROM */
126 __u8 assembly[11] __attribute__((packed)); /* assembly # */ 126 __u8 assembly[11]; /* assembly # */
127 __u8 assembly_rev __attribute__((packed)); /* assembly rev */ 127 __u8 assembly_rev; /* assembly rev */
128 __u8 tracer[4] __attribute__((packed)); /* tracer number */ 128 __u8 tracer[4]; /* tracer number */
129 __u16 assembly_cksum __attribute__((packed)); /* asm checksum */ 129 __u16 assembly_cksum; /* asm checksum */
130 __u16 power_consump __attribute__((packed)); /* pwr requirements */ 130 __u16 power_consump; /* pwr requirements */
131 __u16 num_asics __attribute__((packed)); /* number of asics */ 131 __u16 num_asics; /* number of asics */
132 __u16 bist_time __attribute__((packed)); /* min. bist time */ 132 __u16 bist_time; /* min. bist time */
133 __u16 err_log_offset __attribute__((packed)); /* error log offset */ 133 __u16 err_log_offset; /* error log offset */
134 __u16 scan_path_offset __attribute__((packed));/* scan path offset */ 134 __u16 scan_path_offset;/* scan path offset */
135 __u16 cct_offset __attribute__((packed)); 135 __u16 cct_offset;
136 __u16 log_length __attribute__((packed)); /* length of err log */ 136 __u16 log_length; /* length of err log */
137 __u16 xsum_end __attribute__((packed)); /* offset to end of 137 __u16 xsum_end; /* offset to end of
138 checksum */ 138 checksum */
139 __u8 reserved[4] __attribute__((packed)); 139 __u8 reserved[4];
140 __u8 sflag __attribute__((packed)); /* starting sentinal */ 140 __u8 sflag; /* starting sentinal */
141 __u8 part_number[13] __attribute__((packed)); /* prom part number */ 141 __u8 part_number[13]; /* prom part number */
142 __u8 version[10] __attribute__((packed)); /* version number */ 142 __u8 version[10]; /* version number */
143 __u8 signature[8] __attribute__((packed)); 143 __u8 signature[8];
144 __u16 eeprom_chksum __attribute__((packed)); 144 __u16 eeprom_chksum;
145 __u32 data_stamp_offset __attribute__((packed)); 145 __u32 data_stamp_offset;
146 __u8 eflag __attribute__((packed)); /* ending sentinal */ 146 __u8 eflag ; /* ending sentinal */
147} voyager_eprom_hdr_t; 147} __attribute__((packed)) voyager_eprom_hdr_t;
148 148
149 149
150 150
@@ -155,30 +155,30 @@ typedef struct voyager_eeprom_hdr {
155 * in the module EPROMs. We really only care about the IDs and 155 * in the module EPROMs. We really only care about the IDs and
156 * offsets */ 156 * offsets */
157typedef struct voyager_sp_table { 157typedef struct voyager_sp_table {
158 __u8 asic_id __attribute__((packed)); 158 __u8 asic_id;
159 __u8 bypass_flag __attribute__((packed)); 159 __u8 bypass_flag;
160 __u16 asic_data_offset __attribute__((packed)); 160 __u16 asic_data_offset;
161 __u16 config_data_offset __attribute__((packed)); 161 __u16 config_data_offset;
162} voyager_sp_table_t; 162} __attribute__((packed)) voyager_sp_table_t;
163 163
164typedef struct voyager_jtag_table { 164typedef struct voyager_jtag_table {
165 __u8 icode[4] __attribute__((packed)); 165 __u8 icode[4];
166 __u8 runbist[4] __attribute__((packed)); 166 __u8 runbist[4];
167 __u8 intest[4] __attribute__((packed)); 167 __u8 intest[4];
168 __u8 samp_preld[4] __attribute__((packed)); 168 __u8 samp_preld[4];
169 __u8 ireg_len __attribute__((packed)); 169 __u8 ireg_len;
170} voyager_jtt_t; 170} __attribute__((packed)) voyager_jtt_t;
171 171
172typedef struct voyager_asic_data_table { 172typedef struct voyager_asic_data_table {
173 __u8 jtag_id[4] __attribute__((packed)); 173 __u8 jtag_id[4];
174 __u16 length_bsr __attribute__((packed)); 174 __u16 length_bsr;
175 __u16 length_bist_reg __attribute__((packed)); 175 __u16 length_bist_reg;
176 __u32 bist_clk __attribute__((packed)); 176 __u32 bist_clk;
177 __u16 subaddr_bits __attribute__((packed)); 177 __u16 subaddr_bits;
178 __u16 seed_bits __attribute__((packed)); 178 __u16 seed_bits;
179 __u16 sig_bits __attribute__((packed)); 179 __u16 sig_bits;
180 __u16 jtag_offset __attribute__((packed)); 180 __u16 jtag_offset;
181} voyager_at_t; 181} __attribute__((packed)) voyager_at_t;
182 182
183/* Voyager Interrupt Controller (VIC) registers */ 183/* Voyager Interrupt Controller (VIC) registers */
184 184
@@ -328,52 +328,52 @@ struct voyager_bios_info {
328#define NUMBER_OF_POS_REGS 8 328#define NUMBER_OF_POS_REGS 8
329 329
330typedef struct { 330typedef struct {
331 __u8 MC_Slot __attribute__((packed)); 331 __u8 MC_Slot;
332 __u8 POS_Values[NUMBER_OF_POS_REGS] __attribute__((packed)); 332 __u8 POS_Values[NUMBER_OF_POS_REGS];
333} MC_SlotInformation_t; 333} __attribute__((packed)) MC_SlotInformation_t;
334 334
335struct QuadDescription { 335struct QuadDescription {
336 __u8 Type __attribute__((packed)); /* for type 0 (DYADIC or MONADIC) all fields 336 __u8 Type; /* for type 0 (DYADIC or MONADIC) all fields
337 * will be zero except for slot */ 337 * will be zero except for slot */
338 __u8 StructureVersion __attribute__((packed)); 338 __u8 StructureVersion;
339 __u32 CPI_BaseAddress __attribute__((packed)); 339 __u32 CPI_BaseAddress;
340 __u32 LARC_BankSize __attribute__((packed)); 340 __u32 LARC_BankSize;
341 __u32 LocalMemoryStateBits __attribute__((packed)); 341 __u32 LocalMemoryStateBits;
342 __u8 Slot __attribute__((packed)); /* Processor slots 1 - 4 */ 342 __u8 Slot; /* Processor slots 1 - 4 */
343}; 343} __attribute__((packed));
344 344
345struct ProcBoardInfo { 345struct ProcBoardInfo {
346 __u8 Type __attribute__((packed)); 346 __u8 Type;
347 __u8 StructureVersion __attribute__((packed)); 347 __u8 StructureVersion;
348 __u8 NumberOfBoards __attribute__((packed)); 348 __u8 NumberOfBoards;
349 struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS] __attribute__((packed)); 349 struct QuadDescription QuadData[MAX_PROCESSOR_BOARDS];
350}; 350} __attribute__((packed));
351 351
352struct CacheDescription { 352struct CacheDescription {
353 __u8 Level __attribute__((packed)); 353 __u8 Level;
354 __u32 TotalSize __attribute__((packed)); 354 __u32 TotalSize;
355 __u16 LineSize __attribute__((packed)); 355 __u16 LineSize;
356 __u8 Associativity __attribute__((packed)); 356 __u8 Associativity;
357 __u8 CacheType __attribute__((packed)); 357 __u8 CacheType;
358 __u8 WriteType __attribute__((packed)); 358 __u8 WriteType;
359 __u8 Number_CPUs_SharedBy __attribute__((packed)); 359 __u8 Number_CPUs_SharedBy;
360 __u8 Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS] __attribute__((packed)); 360 __u8 Shared_CPUs_Hardware_IDs[MAX_SHARED_CPUS];
361 361
362}; 362} __attribute__((packed));
363 363
364struct CPU_Description { 364struct CPU_Description {
365 __u8 CPU_HardwareId __attribute__((packed)); 365 __u8 CPU_HardwareId;
366 char *FRU_String __attribute__((packed)); 366 char *FRU_String;
367 __u8 NumberOfCacheLevels __attribute__((packed)); 367 __u8 NumberOfCacheLevels;
368 struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS] __attribute__((packed)); 368 struct CacheDescription CacheLevelData[MAX_CACHE_LEVELS];
369}; 369} __attribute__((packed));
370 370
371struct CPU_Info { 371struct CPU_Info {
372 __u8 Type __attribute__((packed)); 372 __u8 Type;
373 __u8 StructureVersion __attribute__((packed)); 373 __u8 StructureVersion;
374 __u8 NumberOf_CPUs __attribute__((packed)); 374 __u8 NumberOf_CPUs;
375 struct CPU_Description CPU_Data[MAX_CPUS] __attribute__((packed)); 375 struct CPU_Description CPU_Data[MAX_CPUS];
376}; 376} __attribute__((packed));
377 377
378 378
379/* 379/*
diff --git a/include/asm-sh/cpu-sh4/ubc.h b/include/asm-sh/cpu-sh4/ubc.h
index 3d0943167659..c86e17050935 100644
--- a/include/asm-sh/cpu-sh4/ubc.h
+++ b/include/asm-sh/cpu-sh4/ubc.h
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 1999 Niibe Yutaka 4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 Paul Mundt
6 * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
6 * 7 *
7 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -11,6 +12,41 @@
11#ifndef __ASM_CPU_SH4_UBC_H 12#ifndef __ASM_CPU_SH4_UBC_H
12#define __ASM_CPU_SH4_UBC_H 13#define __ASM_CPU_SH4_UBC_H
13 14
15#if defined(CONFIG_CPU_SH4A)
16#define UBC_CBR0 0xff200000
17#define UBC_CRR0 0xff200004
18#define UBC_CAR0 0xff200008
19#define UBC_CAMR0 0xff20000c
20#define UBC_CBR1 0xff200020
21#define UBC_CRR1 0xff200024
22#define UBC_CAR1 0xff200028
23#define UBC_CAMR1 0xff20002c
24#define UBC_CDR1 0xff200030
25#define UBC_CDMR1 0xff200034
26#define UBC_CETR1 0xff200038
27#define UBC_CCMFR 0xff200600
28#define UBC_CBCR 0xff200620
29
30/* CBR */
31#define UBC_CBR_AIE (0x01<<30)
32#define UBC_CBR_ID_INST (0x01<<4)
33#define UBC_CBR_RW_READ (0x01<<1)
34#define UBC_CBR_CE (0x01)
35
36#define UBC_CBR_AIV_MASK (0x00FF0000)
37#define UBC_CBR_AIV_SHIFT (16)
38#define UBC_CBR_AIV_SET(asid) (((asid)<<UBC_CBR_AIV_SHIFT) & UBC_CBR_AIV_MASK)
39
40#define UBC_CBR_INIT 0x20000000
41
42/* CRR */
43#define UBC_CRR_RES (0x01<<13)
44#define UBC_CRR_PCB (0x01<<1)
45#define UBC_CRR_BIE (0x01)
46
47#define UBC_CRR_INIT 0x00002000
48
49#else /* CONFIG_CPU_SH4 */
14#define UBC_BARA 0xff200000 50#define UBC_BARA 0xff200000
15#define UBC_BAMRA 0xff200004 51#define UBC_BAMRA 0xff200004
16#define UBC_BBRA 0xff200008 52#define UBC_BBRA 0xff200008
@@ -22,6 +58,7 @@
22#define UBC_BDRB 0xff200018 58#define UBC_BDRB 0xff200018
23#define UBC_BDMRB 0xff20001c 59#define UBC_BDMRB 0xff20001c
24#define UBC_BRCR 0xff200020 60#define UBC_BRCR 0xff200020
61#endif /* CONFIG_CPU_SH4 */
25 62
26#endif /* __ASM_CPU_SH4_UBC_H */ 63#endif /* __ASM_CPU_SH4_UBC_H */
27 64
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h
index fed26616967a..80ee1cda7498 100644
--- a/include/asm-sh/hw_irq.h
+++ b/include/asm-sh/hw_irq.h
@@ -1,4 +1,8 @@
1#ifndef __ASM_SH_HW_IRQ_H 1#ifndef __ASM_SH_HW_IRQ_H
2#define __ASM_SH_HW_IRQ_H 2#define __ASM_SH_HW_IRQ_H
3 3
4#include <asm/atomic.h>
5
6extern atomic_t irq_err_count;
7
4#endif /* __ASM_SH_HW_IRQ_H */ 8#endif /* __ASM_SH_HW_IRQ_H */
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index 0e5f365aff70..28996f9c58cc 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -697,13 +697,15 @@ extern int ipr_irq_demux(int irq);
697 697
698#define INTC2_INTPRI_OFFSET 0x00 698#define INTC2_INTPRI_OFFSET 0x00
699 699
700void make_intc2_irq(unsigned int irq, 700struct intc2_data {
701 unsigned int ipr_offset, unsigned int ipr_shift, 701 unsigned short irq;
702 unsigned int msk_offset, unsigned int msk_shift, 702 unsigned char ipr_offset, ipr_shift;
703 unsigned int priority); 703 unsigned char msk_offset, msk_shift;
704 unsigned char priority;
705};
706
707void make_intc2_irq(struct intc2_data *);
704void init_IRQ_intc2(void); 708void init_IRQ_intc2(void);
705void intc2_add_clear_irq(int irq, int (*fn)(int));
706
707#endif 709#endif
708 710
709extern int shmse_irq_demux(int irq); 711extern int shmse_irq_demux(int irq);
diff --git a/include/asm-sh/irq_regs.h b/include/asm-sh/irq_regs.h
new file mode 100644
index 000000000000..3dd9c0b70270
--- /dev/null
+++ b/include/asm-sh/irq_regs.h
@@ -0,0 +1 @@
#include <asm-generic/irq_regs.h>
diff --git a/include/asm-sh/timer.h b/include/asm-sh/timer.h
index c7ab28095ba0..5df842bcf7b6 100644
--- a/include/asm-sh/timer.h
+++ b/include/asm-sh/timer.h
@@ -8,8 +8,9 @@ struct sys_timer_ops {
8 int (*init)(void); 8 int (*init)(void);
9 int (*start)(void); 9 int (*start)(void);
10 int (*stop)(void); 10 int (*stop)(void);
11#ifndef CONFIG_GENERIC_TIME
11 unsigned long (*get_offset)(void); 12 unsigned long (*get_offset)(void);
12 unsigned long (*get_frequency)(void); 13#endif
13}; 14};
14 15
15struct sys_timer { 16struct sys_timer {
@@ -24,21 +25,17 @@ struct sys_timer {
24extern struct sys_timer tmu_timer; 25extern struct sys_timer tmu_timer;
25extern struct sys_timer *sys_timer; 26extern struct sys_timer *sys_timer;
26 27
28#ifndef CONFIG_GENERIC_TIME
27static inline unsigned long get_timer_offset(void) 29static inline unsigned long get_timer_offset(void)
28{ 30{
29 return sys_timer->ops->get_offset(); 31 return sys_timer->ops->get_offset();
30} 32}
31 33#endif
32static inline unsigned long get_timer_frequency(void)
33{
34 return sys_timer->ops->get_frequency();
35}
36 34
37/* arch/sh/kernel/timers/timer.c */ 35/* arch/sh/kernel/timers/timer.c */
38struct sys_timer *get_sys_timer(void); 36struct sys_timer *get_sys_timer(void);
39 37
40/* arch/sh/kernel/time.c */ 38/* arch/sh/kernel/time.c */
41void handle_timer_tick(struct pt_regs *); 39void handle_timer_tick(void);
42 40
43#endif /* __ASM_SH_TIMER_H */ 41#endif /* __ASM_SH_TIMER_H */
44
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 26f7856ff812..d370d2cfe138 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -157,6 +157,7 @@ enum rq_cmd_type_bits {
157 REQ_TYPE_ATA_CMD, 157 REQ_TYPE_ATA_CMD,
158 REQ_TYPE_ATA_TASK, 158 REQ_TYPE_ATA_TASK,
159 REQ_TYPE_ATA_TASKFILE, 159 REQ_TYPE_ATA_TASKFILE,
160 REQ_TYPE_ATA_PC,
160}; 161};
161 162
162/* 163/*
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index b3370ef5164d..2fa9f1144228 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -70,7 +70,6 @@ struct elevator_type
70{ 70{
71 struct list_head list; 71 struct list_head list;
72 struct elevator_ops ops; 72 struct elevator_ops ops;
73 struct elevator_type *elevator_type;
74 struct elv_fs_entry *elevator_attrs; 73 struct elv_fs_entry *elevator_attrs;
75 char elevator_name[ELV_NAME_MAX]; 74 char elevator_name[ELV_NAME_MAX];
76 struct module *elevator_owner; 75 struct module *elevator_owner;
diff --git a/include/linux/security.h b/include/linux/security.h
index 9b5fea81f55e..b200b9856f32 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -882,7 +882,8 @@ struct request_sock;
882 * Check permission when a flow selects a xfrm_policy for processing 882 * Check permission when a flow selects a xfrm_policy for processing
883 * XFRMs on a packet. The hook is called when selecting either a 883 * XFRMs on a packet. The hook is called when selecting either a
884 * per-socket policy or a generic xfrm policy. 884 * per-socket policy or a generic xfrm policy.
885 * Return 0 if permission is granted. 885 * Return 0 if permission is granted, -ESRCH otherwise, or -errno
886 * on other errors.
886 * @xfrm_state_pol_flow_match: 887 * @xfrm_state_pol_flow_match:
887 * @x contains the state to match. 888 * @x contains the state to match.
888 * @xp contains the policy to check for a match. 889 * @xp contains the policy to check for a match.
@@ -891,6 +892,7 @@ struct request_sock;
891 * @xfrm_flow_state_match: 892 * @xfrm_flow_state_match:
892 * @fl contains the flow key to match. 893 * @fl contains the flow key to match.
893 * @xfrm points to the xfrm_state to match. 894 * @xfrm points to the xfrm_state to match.
895 * @xp points to the xfrm_policy to match.
894 * Return 1 if there is a match. 896 * Return 1 if there is a match.
895 * @xfrm_decode_session: 897 * @xfrm_decode_session:
896 * @skb points to skb to decode. 898 * @skb points to skb to decode.
@@ -1388,7 +1390,8 @@ struct security_operations {
1388 int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); 1390 int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
1389 int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, 1391 int (*xfrm_state_pol_flow_match)(struct xfrm_state *x,
1390 struct xfrm_policy *xp, struct flowi *fl); 1392 struct xfrm_policy *xp, struct flowi *fl);
1391 int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm); 1393 int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm,
1394 struct xfrm_policy *xp);
1392 int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); 1395 int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall);
1393#endif /* CONFIG_SECURITY_NETWORK_XFRM */ 1396#endif /* CONFIG_SECURITY_NETWORK_XFRM */
1394 1397
@@ -3120,11 +3123,6 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm
3120 return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL); 3123 return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL);
3121} 3124}
3122 3125
3123static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
3124{
3125 return security_ops->xfrm_policy_alloc_security(xp, NULL, sk);
3126}
3127
3128static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 3126static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
3129{ 3127{
3130 return security_ops->xfrm_policy_clone_security(old, new); 3128 return security_ops->xfrm_policy_clone_security(old, new);
@@ -3175,9 +3173,10 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
3175 return security_ops->xfrm_state_pol_flow_match(x, xp, fl); 3173 return security_ops->xfrm_state_pol_flow_match(x, xp, fl);
3176} 3174}
3177 3175
3178static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) 3176static inline int security_xfrm_flow_state_match(struct flowi *fl,
3177 struct xfrm_state *xfrm, struct xfrm_policy *xp)
3179{ 3178{
3180 return security_ops->xfrm_flow_state_match(fl, xfrm); 3179 return security_ops->xfrm_flow_state_match(fl, xfrm, xp);
3181} 3180}
3182 3181
3183static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) 3182static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
@@ -3197,11 +3196,6 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm
3197 return 0; 3196 return 0;
3198} 3197}
3199 3198
3200static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
3201{
3202 return 0;
3203}
3204
3205static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 3199static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
3206{ 3200{
3207 return 0; 3201 return 0;
@@ -3249,7 +3243,7 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
3249} 3243}
3250 3244
3251static inline int security_xfrm_flow_state_match(struct flowi *fl, 3245static inline int security_xfrm_flow_state_match(struct flowi *fl,
3252 struct xfrm_state *xfrm) 3246 struct xfrm_state *xfrm, struct xfrm_policy *xp)
3253{ 3247{
3254 return 1; 3248 return 1;
3255} 3249}
diff --git a/include/net/flow.h b/include/net/flow.h
index ddf5f3ca1720..3b44d72b27d3 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -97,7 +97,7 @@ struct flowi {
97#define FLOW_DIR_FWD 2 97#define FLOW_DIR_FWD 2
98 98
99struct sock; 99struct sock;
100typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, 100typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
101 void **objp, atomic_t **obj_refp); 101 void **objp, atomic_t **obj_refp);
102 102
103extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, 103extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 6d14c22a00c5..5f48748fe017 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -196,6 +196,7 @@ static inline void inet_twsk_put(struct inet_timewait_sock *tw)
196{ 196{
197 if (atomic_dec_and_test(&tw->tw_refcnt)) { 197 if (atomic_dec_and_test(&tw->tw_refcnt)) {
198 struct module *owner = tw->tw_prot->owner; 198 struct module *owner = tw->tw_prot->owner;
199 twsk_destructor((struct sock *)tw);
199#ifdef SOCK_REFCNT_DEBUG 200#ifdef SOCK_REFCNT_DEBUG
200 printk(KERN_DEBUG "%s timewait_sock %p released\n", 201 printk(KERN_DEBUG "%s timewait_sock %p released\n",
201 tw->tw_prot->name, tw); 202 tw->tw_prot->name, tw);
diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index c63a58058e21..113337c27955 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -34,6 +34,7 @@
34#include <linux/net.h> 34#include <linux/net.h>
35#include <linux/skbuff.h> 35#include <linux/skbuff.h>
36#include <net/netlink.h> 36#include <net/netlink.h>
37#include <asm/atomic.h>
37 38
38/* 39/*
39 * NetLabel - A management interface for maintaining network packet label 40 * NetLabel - A management interface for maintaining network packet label
@@ -106,6 +107,7 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
106 107
107/* LSM security attributes */ 108/* LSM security attributes */
108struct netlbl_lsm_cache { 109struct netlbl_lsm_cache {
110 atomic_t refcount;
109 void (*free) (const void *data); 111 void (*free) (const void *data);
110 void *data; 112 void *data;
111}; 113};
@@ -117,7 +119,7 @@ struct netlbl_lsm_secattr {
117 unsigned char *mls_cat; 119 unsigned char *mls_cat;
118 size_t mls_cat_len; 120 size_t mls_cat_len;
119 121
120 struct netlbl_lsm_cache cache; 122 struct netlbl_lsm_cache *cache;
121}; 123};
122 124
123/* 125/*
@@ -126,6 +128,43 @@ struct netlbl_lsm_secattr {
126 128
127 129
128/** 130/**
131 * netlbl_secattr_cache_alloc - Allocate and initialize a secattr cache
132 * @flags: the memory allocation flags
133 *
134 * Description:
135 * Allocate and initialize a netlbl_lsm_cache structure. Returns a pointer
136 * on success, NULL on failure.
137 *
138 */
139static inline struct netlbl_lsm_cache *netlbl_secattr_cache_alloc(int flags)
140{
141 struct netlbl_lsm_cache *cache;
142
143 cache = kzalloc(sizeof(*cache), flags);
144 if (cache)
145 atomic_set(&cache->refcount, 1);
146 return cache;
147}
148
149/**
150 * netlbl_secattr_cache_free - Frees a netlbl_lsm_cache struct
151 * @cache: the struct to free
152 *
153 * Description:
154 * Frees @secattr including all of the internal buffers.
155 *
156 */
157static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
158{
159 if (!atomic_dec_and_test(&cache->refcount))
160 return;
161
162 if (cache->free)
163 cache->free(cache->data);
164 kfree(cache);
165}
166
167/**
129 * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct 168 * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct
130 * @secattr: the struct to initialize 169 * @secattr: the struct to initialize
131 * 170 *
@@ -143,20 +182,16 @@ static inline int netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
143/** 182/**
144 * netlbl_secattr_destroy - Clears a netlbl_lsm_secattr struct 183 * netlbl_secattr_destroy - Clears a netlbl_lsm_secattr struct
145 * @secattr: the struct to clear 184 * @secattr: the struct to clear
146 * @clear_cache: cache clear flag
147 * 185 *
148 * Description: 186 * Description:
149 * Destroys the @secattr struct, including freeing all of the internal buffers. 187 * Destroys the @secattr struct, including freeing all of the internal buffers.
150 * If @clear_cache is true then free the cache fields, otherwise leave them 188 * The struct must be reset with a call to netlbl_secattr_init() before reuse.
151 * intact. The struct must be reset with a call to netlbl_secattr_init()
152 * before reuse.
153 * 189 *
154 */ 190 */
155static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr, 191static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
156 u32 clear_cache)
157{ 192{
158 if (clear_cache && secattr->cache.data != NULL && secattr->cache.free) 193 if (secattr->cache)
159 secattr->cache.free(secattr->cache.data); 194 netlbl_secattr_cache_free(secattr->cache);
160 kfree(secattr->domain); 195 kfree(secattr->domain);
161 kfree(secattr->mls_cat); 196 kfree(secattr->mls_cat);
162} 197}
@@ -178,17 +213,14 @@ static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(int flags)
178/** 213/**
179 * netlbl_secattr_free - Frees a netlbl_lsm_secattr struct 214 * netlbl_secattr_free - Frees a netlbl_lsm_secattr struct
180 * @secattr: the struct to free 215 * @secattr: the struct to free
181 * @clear_cache: cache clear flag
182 * 216 *
183 * Description: 217 * Description:
184 * Frees @secattr including all of the internal buffers. If @clear_cache is 218 * Frees @secattr including all of the internal buffers.
185 * true then free the cache fields, otherwise leave them intact.
186 * 219 *
187 */ 220 */
188static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr, 221static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
189 u32 clear_cache)
190{ 222{
191 netlbl_secattr_destroy(secattr, clear_cache); 223 netlbl_secattr_destroy(secattr);
192 kfree(secattr); 224 kfree(secattr);
193} 225}
194 226
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index ee68a3124076..764e3af5be93 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -139,6 +139,7 @@ int sctp_inet_listen(struct socket *sock, int backlog);
139void sctp_write_space(struct sock *sk); 139void sctp_write_space(struct sock *sk);
140unsigned int sctp_poll(struct file *file, struct socket *sock, 140unsigned int sctp_poll(struct file *file, struct socket *sock,
141 poll_table *wait); 141 poll_table *wait);
142void sctp_sock_rfree(struct sk_buff *skb);
142 143
143/* 144/*
144 * sctp/primitive.c 145 * sctp/primitive.c
@@ -444,6 +445,19 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list)
444 return result; 445 return result;
445} 446}
446 447
448/* SCTP version of skb_set_owner_r. We need this one because
449 * of the way we have to do receive buffer accounting on bundled
450 * chunks.
451 */
452static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
453{
454 struct sctp_ulpevent *event = sctp_skb2event(skb);
455
456 skb->sk = sk;
457 skb->destructor = sctp_sock_rfree;
458 atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
459}
460
447/* Tests if the list has one and only one entry. */ 461/* Tests if the list has one and only one entry. */
448static inline int sctp_list_single_entry(struct list_head *head) 462static inline int sctp_list_single_entry(struct list_head *head)
449{ 463{
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 6c40cfc4832d..1a4ddc1ec7d2 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -63,6 +63,7 @@ struct sctp_ulpevent {
63 __u32 cumtsn; 63 __u32 cumtsn;
64 int msg_flags; 64 int msg_flags;
65 int iif; 65 int iif;
66 unsigned int rmem_len;
66}; 67};
67 68
68/* Retrieve the skb this event sits inside of. */ 69/* Retrieve the skb this event sits inside of. */
diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h
index 2544281e1d5e..be293d795e38 100644
--- a/include/net/timewait_sock.h
+++ b/include/net/timewait_sock.h
@@ -19,6 +19,7 @@ struct timewait_sock_ops {
19 unsigned int twsk_obj_size; 19 unsigned int twsk_obj_size;
20 int (*twsk_unique)(struct sock *sk, 20 int (*twsk_unique)(struct sock *sk,
21 struct sock *sktw, void *twp); 21 struct sock *sktw, void *twp);
22 void (*twsk_destructor)(struct sock *sk);
22}; 23};
23 24
24static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) 25static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
@@ -28,4 +29,10 @@ static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
28 return 0; 29 return 0;
29} 30}
30 31
32static inline void twsk_destructor(struct sock *sk)
33{
34 if (sk->sk_prot->twsk_prot->twsk_destructor != NULL)
35 sk->sk_prot->twsk_prot->twsk_destructor(sk);
36}
37
31#endif /* _TIMEWAIT_SOCK_H */ 38#endif /* _TIMEWAIT_SOCK_H */
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1e2a4ddec96e..737fdb2ee8a4 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -995,7 +995,8 @@ struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
995 int create, unsigned short family); 995 int create, unsigned short family);
996extern void xfrm_policy_flush(u8 type); 996extern void xfrm_policy_flush(u8 type);
997extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); 997extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
998extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family, int strict); 998extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
999 struct flowi *fl, int family, int strict);
999extern void xfrm_init_pmtu(struct dst_entry *dst); 1000extern void xfrm_init_pmtu(struct dst_entry *dst);
1000 1001
1001extern wait_queue_head_t km_waitq; 1002extern wait_queue_head_t km_waitq;
diff --git a/net/compat.c b/net/compat.c
index d5d69fa15d07..52d32f1bc728 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -285,8 +285,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
285 285
286 if (i > 0) { 286 if (i > 0) {
287 int cmlen = CMSG_COMPAT_LEN(i * sizeof(int)); 287 int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
288 if (!err) 288 err = put_user(SOL_SOCKET, &cm->cmsg_level);
289 err = put_user(SOL_SOCKET, &cm->cmsg_level);
290 if (!err) 289 if (!err)
291 err = put_user(SCM_RIGHTS, &cm->cmsg_type); 290 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
292 if (!err) 291 if (!err)
diff --git a/net/core/flow.c b/net/core/flow.c
index f23e7e386543..b16d31ae5e54 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -85,6 +85,14 @@ static void flow_cache_new_hashrnd(unsigned long arg)
85 add_timer(&flow_hash_rnd_timer); 85 add_timer(&flow_hash_rnd_timer);
86} 86}
87 87
88static void flow_entry_kill(int cpu, struct flow_cache_entry *fle)
89{
90 if (fle->object)
91 atomic_dec(fle->object_ref);
92 kmem_cache_free(flow_cachep, fle);
93 flow_count(cpu)--;
94}
95
88static void __flow_cache_shrink(int cpu, int shrink_to) 96static void __flow_cache_shrink(int cpu, int shrink_to)
89{ 97{
90 struct flow_cache_entry *fle, **flp; 98 struct flow_cache_entry *fle, **flp;
@@ -100,10 +108,7 @@ static void __flow_cache_shrink(int cpu, int shrink_to)
100 } 108 }
101 while ((fle = *flp) != NULL) { 109 while ((fle = *flp) != NULL) {
102 *flp = fle->next; 110 *flp = fle->next;
103 if (fle->object) 111 flow_entry_kill(cpu, fle);
104 atomic_dec(fle->object_ref);
105 kmem_cache_free(flow_cachep, fle);
106 flow_count(cpu)--;
107 } 112 }
108 } 113 }
109} 114}
@@ -220,24 +225,33 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
220 225
221nocache: 226nocache:
222 { 227 {
228 int err;
223 void *obj; 229 void *obj;
224 atomic_t *obj_ref; 230 atomic_t *obj_ref;
225 231
226 resolver(key, family, dir, &obj, &obj_ref); 232 err = resolver(key, family, dir, &obj, &obj_ref);
227 233
228 if (fle) { 234 if (fle) {
229 fle->genid = atomic_read(&flow_cache_genid); 235 if (err) {
230 236 /* Force security policy check on next lookup */
231 if (fle->object) 237 *head = fle->next;
232 atomic_dec(fle->object_ref); 238 flow_entry_kill(cpu, fle);
233 239 } else {
234 fle->object = obj; 240 fle->genid = atomic_read(&flow_cache_genid);
235 fle->object_ref = obj_ref; 241
236 if (obj) 242 if (fle->object)
237 atomic_inc(fle->object_ref); 243 atomic_dec(fle->object_ref);
244
245 fle->object = obj;
246 fle->object_ref = obj_ref;
247 if (obj)
248 atomic_inc(fle->object_ref);
249 }
238 } 250 }
239 local_bh_enable(); 251 local_bh_enable();
240 252
253 if (err)
254 obj = ERR_PTR(err);
241 return obj; 255 return obj;
242 } 256 }
243} 257}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 221e4038216b..02f3c7947898 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -602,7 +602,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
602 goto errout; 602 goto errout;
603 } 603 }
604 604
605 err = rtnl_unicast(skb, NETLINK_CB(skb).pid); 605 err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
606errout: 606errout:
607 kfree(iw_buf); 607 kfree(iw_buf);
608 dev_put(dev); 608 dev_put(dev);
diff --git a/net/core/scm.c b/net/core/scm.c
index 649d01ef35b6..271cf060ef8c 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -245,8 +245,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
245 if (i > 0) 245 if (i > 0)
246 { 246 {
247 int cmlen = CMSG_LEN(i*sizeof(int)); 247 int cmlen = CMSG_LEN(i*sizeof(int));
248 if (!err) 248 err = put_user(SOL_SOCKET, &cm->cmsg_level);
249 err = put_user(SOL_SOCKET, &cm->cmsg_level);
250 if (!err) 249 if (!err)
251 err = put_user(SCM_RIGHTS, &cm->cmsg_type); 250 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
252 if (!err) 251 if (!err)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index bf692c1c116f..7e746c4c1688 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -311,7 +311,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
311 } 311 }
312 312
313 if (sk->sk_state == DCCP_TIME_WAIT) { 313 if (sk->sk_state == DCCP_TIME_WAIT) {
314 inet_twsk_put((struct inet_timewait_sock *)sk); 314 inet_twsk_put(inet_twsk(sk));
315 return; 315 return;
316 } 316 }
317 317
@@ -614,7 +614,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
614 bh_lock_sock(nsk); 614 bh_lock_sock(nsk);
615 return nsk; 615 return nsk;
616 } 616 }
617 inet_twsk_put((struct inet_timewait_sock *)nsk); 617 inet_twsk_put(inet_twsk(nsk));
618 return NULL; 618 return NULL;
619 } 619 }
620 620
@@ -980,7 +980,7 @@ discard_and_relse:
980 goto discard_it; 980 goto discard_it;
981 981
982do_time_wait: 982do_time_wait:
983 inet_twsk_put((struct inet_timewait_sock *)sk); 983 inet_twsk_put(inet_twsk(sk));
984 goto no_dccp_socket; 984 goto no_dccp_socket;
985} 985}
986 986
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 7a47399cf31f..7171a78671aa 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -285,7 +285,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
285 } 285 }
286 286
287 if (sk->sk_state == DCCP_TIME_WAIT) { 287 if (sk->sk_state == DCCP_TIME_WAIT) {
288 inet_twsk_put((struct inet_timewait_sock *)sk); 288 inet_twsk_put(inet_twsk(sk));
289 return; 289 return;
290 } 290 }
291 291
@@ -663,7 +663,7 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
663 bh_lock_sock(nsk); 663 bh_lock_sock(nsk);
664 return nsk; 664 return nsk;
665 } 665 }
666 inet_twsk_put((struct inet_timewait_sock *)nsk); 666 inet_twsk_put(inet_twsk(nsk));
667 return NULL; 667 return NULL;
668 } 668 }
669 669
@@ -1109,7 +1109,7 @@ discard_and_relse:
1109 goto discard_it; 1109 goto discard_it;
1110 1110
1111do_time_wait: 1111do_time_wait:
1112 inet_twsk_put((struct inet_timewait_sock *)sk); 1112 inet_twsk_put(inet_twsk(sk));
1113 goto no_dccp_socket; 1113 goto no_dccp_socket;
1114} 1114}
1115 1115
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 70e027375682..3456cd331835 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -1178,8 +1178,10 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len
1178 if (peer) { 1178 if (peer) {
1179 if ((sock->state != SS_CONNECTED && 1179 if ((sock->state != SS_CONNECTED &&
1180 sock->state != SS_CONNECTING) && 1180 sock->state != SS_CONNECTING) &&
1181 scp->accept_mode == ACC_IMMED) 1181 scp->accept_mode == ACC_IMMED) {
1182 release_sock(sk);
1182 return -ENOTCONN; 1183 return -ENOTCONN;
1184 }
1183 1185
1184 memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn)); 1186 memcpy(sa, &scp->peer, sizeof(struct sockaddr_dn));
1185 } else { 1187 } else {
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index dd0761e3d280..a2a43d8d93fe 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -267,9 +267,14 @@ static void dn_dst_link_failure(struct sk_buff *skb)
267 267
268static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) 268static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
269{ 269{
270 return memcmp(&fl1->nl_u.dn_u, &fl2->nl_u.dn_u, sizeof(fl1->nl_u.dn_u)) == 0 && 270 return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) |
271 fl1->oif == fl2->oif && 271 (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) |
272 fl1->iif == fl2->iif; 272#ifdef CONFIG_IP_ROUTE_FWMARK
273 (fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) |
274#endif
275 (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) |
276 (fl1->oif ^ fl2->oif) |
277 (fl1->iif ^ fl2->iif)) == 0;
273} 278}
274 279
275static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) 280static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp)
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index a8e2e879a647..bde8ccaa1531 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -43,6 +43,7 @@
43#include <net/tcp.h> 43#include <net/tcp.h>
44#include <net/netlabel.h> 44#include <net/netlabel.h>
45#include <net/cipso_ipv4.h> 45#include <net/cipso_ipv4.h>
46#include <asm/atomic.h>
46#include <asm/bug.h> 47#include <asm/bug.h>
47 48
48struct cipso_v4_domhsh_entry { 49struct cipso_v4_domhsh_entry {
@@ -79,7 +80,7 @@ struct cipso_v4_map_cache_entry {
79 unsigned char *key; 80 unsigned char *key;
80 size_t key_len; 81 size_t key_len;
81 82
82 struct netlbl_lsm_cache lsm_data; 83 struct netlbl_lsm_cache *lsm_data;
83 84
84 u32 activity; 85 u32 activity;
85 struct list_head list; 86 struct list_head list;
@@ -188,13 +189,14 @@ static void cipso_v4_doi_domhsh_free(struct rcu_head *entry)
188 * @entry: the entry to free 189 * @entry: the entry to free
189 * 190 *
190 * Description: 191 * Description:
191 * This function frees the memory associated with a cache entry. 192 * This function frees the memory associated with a cache entry including the
193 * LSM cache data if there are no longer any users, i.e. reference count == 0.
192 * 194 *
193 */ 195 */
194static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry) 196static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry)
195{ 197{
196 if (entry->lsm_data.free) 198 if (entry->lsm_data)
197 entry->lsm_data.free(entry->lsm_data.data); 199 netlbl_secattr_cache_free(entry->lsm_data);
198 kfree(entry->key); 200 kfree(entry->key);
199 kfree(entry); 201 kfree(entry);
200} 202}
@@ -315,8 +317,8 @@ static int cipso_v4_cache_check(const unsigned char *key,
315 entry->key_len == key_len && 317 entry->key_len == key_len &&
316 memcmp(entry->key, key, key_len) == 0) { 318 memcmp(entry->key, key, key_len) == 0) {
317 entry->activity += 1; 319 entry->activity += 1;
318 secattr->cache.free = entry->lsm_data.free; 320 atomic_inc(&entry->lsm_data->refcount);
319 secattr->cache.data = entry->lsm_data.data; 321 secattr->cache = entry->lsm_data;
320 if (prev_entry == NULL) { 322 if (prev_entry == NULL) {
321 spin_unlock_bh(&cipso_v4_cache[bkt].lock); 323 spin_unlock_bh(&cipso_v4_cache[bkt].lock);
322 return 0; 324 return 0;
@@ -383,8 +385,8 @@ int cipso_v4_cache_add(const struct sk_buff *skb,
383 memcpy(entry->key, cipso_ptr, cipso_ptr_len); 385 memcpy(entry->key, cipso_ptr, cipso_ptr_len);
384 entry->key_len = cipso_ptr_len; 386 entry->key_len = cipso_ptr_len;
385 entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len); 387 entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
386 entry->lsm_data.free = secattr->cache.free; 388 atomic_inc(&secattr->cache->refcount);
387 entry->lsm_data.data = secattr->cache.data; 389 entry->lsm_data = secattr->cache;
388 390
389 bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1); 391 bkt = entry->hash & (CIPSO_V4_CACHE_BUCKETBITS - 1);
390 spin_lock_bh(&cipso_v4_cache[bkt].lock); 392 spin_lock_bh(&cipso_v4_cache[bkt].lock);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index f5fba051df3d..d5b5dec075b8 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -611,8 +611,8 @@ static int ipgre_rcv(struct sk_buff *skb)
611 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header 611 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
612 */ 612 */
613 if (flags == 0 && 613 if (flags == 0 &&
614 skb->protocol == __constant_htons(ETH_P_WCCP)) { 614 skb->protocol == htons(ETH_P_WCCP)) {
615 skb->protocol = __constant_htons(ETH_P_IP); 615 skb->protocol = htons(ETH_P_IP);
616 if ((*(h + offset) & 0xF0) != 0x40) 616 if ((*(h + offset) & 0xF0) != 0x40)
617 offset += 4; 617 offset += 4;
618 } 618 }
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index c41ddba02e9d..925ee4dfc32c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -566,9 +566,15 @@ static inline u32 rt_score(struct rtable *rt)
566 566
567static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) 567static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
568{ 568{
569 return memcmp(&fl1->nl_u.ip4_u, &fl2->nl_u.ip4_u, sizeof(fl1->nl_u.ip4_u)) == 0 && 569 return ((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
570 fl1->oif == fl2->oif && 570 (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) |
571 fl1->iif == fl2->iif; 571#ifdef CONFIG_IP_ROUTE_FWMARK
572 (fl1->nl_u.ip4_u.fwmark ^ fl2->nl_u.ip4_u.fwmark) |
573#endif
574 (*(u16 *)&fl1->nl_u.ip4_u.tos ^
575 *(u16 *)&fl2->nl_u.ip4_u.tos) |
576 (fl1->oif ^ fl2->oif) |
577 (fl1->iif ^ fl2->iif)) == 0;
572} 578}
573 579
574#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 580#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c83938b8fcb1..6bbd98575172 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -355,7 +355,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
355 return; 355 return;
356 } 356 }
357 if (sk->sk_state == TCP_TIME_WAIT) { 357 if (sk->sk_state == TCP_TIME_WAIT) {
358 inet_twsk_put((struct inet_timewait_sock *)sk); 358 inet_twsk_put(inet_twsk(sk));
359 return; 359 return;
360 } 360 }
361 361
@@ -578,7 +578,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
578 struct tcphdr *th = skb->h.th; 578 struct tcphdr *th = skb->h.th;
579 struct { 579 struct {
580 struct tcphdr th; 580 struct tcphdr th;
581 u32 tsopt[3]; 581 u32 tsopt[TCPOLEN_TSTAMP_ALIGNED >> 2];
582 } rep; 582 } rep;
583 struct ip_reply_arg arg; 583 struct ip_reply_arg arg;
584 584
@@ -960,7 +960,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
960 bh_lock_sock(nsk); 960 bh_lock_sock(nsk);
961 return nsk; 961 return nsk;
962 } 962 }
963 inet_twsk_put((struct inet_timewait_sock *)nsk); 963 inet_twsk_put(inet_twsk(nsk));
964 return NULL; 964 return NULL;
965 } 965 }
966 966
@@ -1154,26 +1154,24 @@ discard_and_relse:
1154 1154
1155do_time_wait: 1155do_time_wait:
1156 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { 1156 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
1157 inet_twsk_put((struct inet_timewait_sock *) sk); 1157 inet_twsk_put(inet_twsk(sk));
1158 goto discard_it; 1158 goto discard_it;
1159 } 1159 }
1160 1160
1161 if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) { 1161 if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
1162 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1162 TCP_INC_STATS_BH(TCP_MIB_INERRS);
1163 inet_twsk_put((struct inet_timewait_sock *) sk); 1163 inet_twsk_put(inet_twsk(sk));
1164 goto discard_it; 1164 goto discard_it;
1165 } 1165 }
1166 switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk, 1166 switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
1167 skb, th)) {
1168 case TCP_TW_SYN: { 1167 case TCP_TW_SYN: {
1169 struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo, 1168 struct sock *sk2 = inet_lookup_listener(&tcp_hashinfo,
1170 skb->nh.iph->daddr, 1169 skb->nh.iph->daddr,
1171 th->dest, 1170 th->dest,
1172 inet_iif(skb)); 1171 inet_iif(skb));
1173 if (sk2) { 1172 if (sk2) {
1174 inet_twsk_deschedule((struct inet_timewait_sock *)sk, 1173 inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row);
1175 &tcp_death_row); 1174 inet_twsk_put(inet_twsk(sk));
1176 inet_twsk_put((struct inet_timewait_sock *)sk);
1177 sk = sk2; 1175 sk = sk2;
1178 goto process; 1176 goto process;
1179 } 1177 }
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 9a253faefc81..f22536e32cb1 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -273,10 +273,10 @@ static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
273 __u32 tstamp) 273 __u32 tstamp)
274{ 274{
275 if (tp->rx_opt.tstamp_ok) { 275 if (tp->rx_opt.tstamp_ok) {
276 *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | 276 *ptr++ = htonl((TCPOPT_NOP << 24) |
277 (TCPOPT_NOP << 16) | 277 (TCPOPT_NOP << 16) |
278 (TCPOPT_TIMESTAMP << 8) | 278 (TCPOPT_TIMESTAMP << 8) |
279 TCPOLEN_TIMESTAMP); 279 TCPOLEN_TIMESTAMP);
280 *ptr++ = htonl(tstamp); 280 *ptr++ = htonl(tstamp);
281 *ptr++ = htonl(tp->rx_opt.ts_recent); 281 *ptr++ = htonl(tp->rx_opt.ts_recent);
282 } 282 }
@@ -325,18 +325,27 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
325 *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss); 325 *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
326 if (ts) { 326 if (ts) {
327 if(sack) 327 if(sack)
328 *ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) | 328 *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
329 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); 329 (TCPOLEN_SACK_PERM << 16) |
330 (TCPOPT_TIMESTAMP << 8) |
331 TCPOLEN_TIMESTAMP);
330 else 332 else
331 *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 333 *ptr++ = htonl((TCPOPT_NOP << 24) |
332 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); 334 (TCPOPT_NOP << 16) |
335 (TCPOPT_TIMESTAMP << 8) |
336 TCPOLEN_TIMESTAMP);
333 *ptr++ = htonl(tstamp); /* TSVAL */ 337 *ptr++ = htonl(tstamp); /* TSVAL */
334 *ptr++ = htonl(ts_recent); /* TSECR */ 338 *ptr++ = htonl(ts_recent); /* TSECR */
335 } else if(sack) 339 } else if(sack)
336 *ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 340 *ptr++ = htonl((TCPOPT_NOP << 24) |
337 (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM); 341 (TCPOPT_NOP << 16) |
342 (TCPOPT_SACK_PERM << 8) |
343 TCPOLEN_SACK_PERM);
338 if (offer_wscale) 344 if (offer_wscale)
339 *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale)); 345 *ptr++ = htonl((TCPOPT_NOP << 24) |
346 (TCPOPT_WINDOW << 16) |
347 (TCPOLEN_WINDOW << 8) |
348 (wscale));
340} 349}
341 350
342/* This routine actually transmits TCP packets queued in by 351/* This routine actually transmits TCP packets queued in by
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 7a7a00147e55..1bed0cdf53e3 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -52,7 +52,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
52 xdst->u.rt.fl.fl4_dst == fl->fl4_dst && 52 xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
53 xdst->u.rt.fl.fl4_src == fl->fl4_src && 53 xdst->u.rt.fl.fl4_src == fl->fl4_src &&
54 xdst->u.rt.fl.fl4_tos == fl->fl4_tos && 54 xdst->u.rt.fl.fl4_tos == fl->fl4_tos &&
55 xfrm_bundle_ok(xdst, fl, AF_INET, 0)) { 55 xfrm_bundle_ok(policy, xdst, fl, AF_INET, 0)) {
56 dst_clone(dst); 56 dst_clone(dst);
57 break; 57 break;
58 } 58 }
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index a460e8132b4d..ef5eaad44851 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -153,6 +153,19 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION
153 ---help--- 153 ---help---
154 Support for MIPv6 route optimization mode. 154 Support for MIPv6 route optimization mode.
155 155
156config IPV6_SIT
157 tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
158 depends on IPV6
159 default y
160 ---help---
161 Tunneling means encapsulating data of one protocol type within
162 another protocol and sending it over a channel that understands the
163 encapsulating protocol. This driver implements encapsulation of IPv6
164 into IPv4 packets. This is useful if you want to connect two IPv6
165 networks over an IPv4-only path.
166
167 Saying M here will produce a module called sit.ko. If unsure, say Y.
168
156config IPV6_TUNNEL 169config IPV6_TUNNEL
157 tristate "IPv6: IPv6-in-IPv6 tunnel" 170 tristate "IPv6: IPv6-in-IPv6 tunnel"
158 select INET6_TUNNEL 171 select INET6_TUNNEL
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 87274e47fe32..addcc011bc01 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-$(CONFIG_IPV6) += ipv6.o 5obj-$(CONFIG_IPV6) += ipv6.o
6 6
7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \ 7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ 8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
9 protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ 9 protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ 10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
@@ -29,6 +29,7 @@ obj-$(CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION) += xfrm6_mode_ro.o
29obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o 29obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o
30obj-$(CONFIG_NETFILTER) += netfilter/ 30obj-$(CONFIG_NETFILTER) += netfilter/
31 31
32obj-$(CONFIG_IPV6_SIT) += sit.o
32obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o 33obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
33 34
34obj-y += exthdrs_core.o 35obj-y += exthdrs_core.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e03c33b2465b..b312a5f7a759 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -396,8 +396,10 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
396 ndev->regen_timer.data = (unsigned long) ndev; 396 ndev->regen_timer.data = (unsigned long) ndev;
397 if ((dev->flags&IFF_LOOPBACK) || 397 if ((dev->flags&IFF_LOOPBACK) ||
398 dev->type == ARPHRD_TUNNEL || 398 dev->type == ARPHRD_TUNNEL ||
399 dev->type == ARPHRD_NONE || 399#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
400 dev->type == ARPHRD_SIT) { 400 dev->type == ARPHRD_SIT ||
401#endif
402 dev->type == ARPHRD_NONE) {
401 printk(KERN_INFO 403 printk(KERN_INFO
402 "%s: Disabled Privacy Extensions\n", 404 "%s: Disabled Privacy Extensions\n",
403 dev->name); 405 dev->name);
@@ -1546,8 +1548,10 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
1546 This thing is done here expecting that the whole 1548 This thing is done here expecting that the whole
1547 class of non-broadcast devices need not cloning. 1549 class of non-broadcast devices need not cloning.
1548 */ 1550 */
1551#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
1549 if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT)) 1552 if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
1550 cfg.fc_flags |= RTF_NONEXTHOP; 1553 cfg.fc_flags |= RTF_NONEXTHOP;
1554#endif
1551 1555
1552 ip6_route_add(&cfg); 1556 ip6_route_add(&cfg);
1553} 1557}
@@ -1569,6 +1573,7 @@ static void addrconf_add_mroute(struct net_device *dev)
1569 ip6_route_add(&cfg); 1573 ip6_route_add(&cfg);
1570} 1574}
1571 1575
1576#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
1572static void sit_route_add(struct net_device *dev) 1577static void sit_route_add(struct net_device *dev)
1573{ 1578{
1574 struct fib6_config cfg = { 1579 struct fib6_config cfg = {
@@ -1582,6 +1587,7 @@ static void sit_route_add(struct net_device *dev)
1582 /* prefix length - 96 bits "::d.d.d.d" */ 1587 /* prefix length - 96 bits "::d.d.d.d" */
1583 ip6_route_add(&cfg); 1588 ip6_route_add(&cfg);
1584} 1589}
1590#endif
1585 1591
1586static void addrconf_add_lroute(struct net_device *dev) 1592static void addrconf_add_lroute(struct net_device *dev)
1587{ 1593{
@@ -1852,6 +1858,7 @@ int addrconf_set_dstaddr(void __user *arg)
1852 if (dev == NULL) 1858 if (dev == NULL)
1853 goto err_exit; 1859 goto err_exit;
1854 1860
1861#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
1855 if (dev->type == ARPHRD_SIT) { 1862 if (dev->type == ARPHRD_SIT) {
1856 struct ifreq ifr; 1863 struct ifreq ifr;
1857 mm_segment_t oldfs; 1864 mm_segment_t oldfs;
@@ -1881,6 +1888,7 @@ int addrconf_set_dstaddr(void __user *arg)
1881 err = dev_open(dev); 1888 err = dev_open(dev);
1882 } 1889 }
1883 } 1890 }
1891#endif
1884 1892
1885err_exit: 1893err_exit:
1886 rtnl_unlock(); 1894 rtnl_unlock();
@@ -2010,6 +2018,7 @@ int addrconf_del_ifaddr(void __user *arg)
2010 return err; 2018 return err;
2011} 2019}
2012 2020
2021#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2013static void sit_add_v4_addrs(struct inet6_dev *idev) 2022static void sit_add_v4_addrs(struct inet6_dev *idev)
2014{ 2023{
2015 struct inet6_ifaddr * ifp; 2024 struct inet6_ifaddr * ifp;
@@ -2078,6 +2087,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
2078 } 2087 }
2079 } 2088 }
2080} 2089}
2090#endif
2081 2091
2082static void init_loopback(struct net_device *dev) 2092static void init_loopback(struct net_device *dev)
2083{ 2093{
@@ -2141,6 +2151,7 @@ static void addrconf_dev_config(struct net_device *dev)
2141 addrconf_add_linklocal(idev, &addr); 2151 addrconf_add_linklocal(idev, &addr);
2142} 2152}
2143 2153
2154#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2144static void addrconf_sit_config(struct net_device *dev) 2155static void addrconf_sit_config(struct net_device *dev)
2145{ 2156{
2146 struct inet6_dev *idev; 2157 struct inet6_dev *idev;
@@ -2166,6 +2177,7 @@ static void addrconf_sit_config(struct net_device *dev)
2166 } else 2177 } else
2167 sit_route_add(dev); 2178 sit_route_add(dev);
2168} 2179}
2180#endif
2169 2181
2170static inline int 2182static inline int
2171ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) 2183ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev)
@@ -2260,9 +2272,11 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
2260 } 2272 }
2261 2273
2262 switch(dev->type) { 2274 switch(dev->type) {
2275#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2263 case ARPHRD_SIT: 2276 case ARPHRD_SIT:
2264 addrconf_sit_config(dev); 2277 addrconf_sit_config(dev);
2265 break; 2278 break;
2279#endif
2266 case ARPHRD_TUNNEL6: 2280 case ARPHRD_TUNNEL6:
2267 addrconf_ip6_tnl_config(dev); 2281 addrconf_ip6_tnl_config(dev);
2268 break; 2282 break;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e94eccb99707..858cae29581c 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -850,7 +850,6 @@ static int __init inet6_init(void)
850 err = addrconf_init(); 850 err = addrconf_init();
851 if (err) 851 if (err)
852 goto addrconf_fail; 852 goto addrconf_fail;
853 sit_init();
854 853
855 /* Init v6 extension headers. */ 854 /* Init v6 extension headers. */
856 ipv6_rthdr_init(); 855 ipv6_rthdr_init();
@@ -927,7 +926,6 @@ static void __exit inet6_exit(void)
927 mip6_fini(); 926 mip6_fini();
928#endif 927#endif
929 /* Cleanup code parts. */ 928 /* Cleanup code parts. */
930 sit_cleanup();
931 ip6_flowlabel_cleanup(); 929 ip6_flowlabel_cleanup();
932 addrconf_cleanup(); 930 addrconf_cleanup();
933 ip6_route_cleanup(); 931 ip6_route_cleanup();
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 836eecd7e62b..dc5765b62b87 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -850,3 +850,6 @@ int __init sit_init(void)
850 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 850 inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
851 goto out; 851 goto out;
852} 852}
853
854module_init(sit_init);
855module_exit(sit_cleanup);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 3b6575478fcc..4c2a7c0cafef 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -329,7 +329,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
329 } 329 }
330 330
331 if (sk->sk_state == TCP_TIME_WAIT) { 331 if (sk->sk_state == TCP_TIME_WAIT) {
332 inet_twsk_put((struct inet_timewait_sock *)sk); 332 inet_twsk_put(inet_twsk(sk));
333 return; 333 return;
334 } 334 }
335 335
@@ -653,7 +653,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
653 int tot_len = sizeof(struct tcphdr); 653 int tot_len = sizeof(struct tcphdr);
654 654
655 if (ts) 655 if (ts)
656 tot_len += 3*4; 656 tot_len += TCPOLEN_TSTAMP_ALIGNED;
657 657
658 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, 658 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
659 GFP_ATOMIC); 659 GFP_ATOMIC);
@@ -749,7 +749,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
749 bh_lock_sock(nsk); 749 bh_lock_sock(nsk);
750 return nsk; 750 return nsk;
751 } 751 }
752 inet_twsk_put((struct inet_timewait_sock *)nsk); 752 inet_twsk_put(inet_twsk(nsk));
753 return NULL; 753 return NULL;
754 } 754 }
755 755
@@ -1283,18 +1283,17 @@ discard_and_relse:
1283 1283
1284do_time_wait: 1284do_time_wait:
1285 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 1285 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
1286 inet_twsk_put((struct inet_timewait_sock *)sk); 1286 inet_twsk_put(inet_twsk(sk));
1287 goto discard_it; 1287 goto discard_it;
1288 } 1288 }
1289 1289
1290 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { 1290 if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
1291 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1291 TCP_INC_STATS_BH(TCP_MIB_INERRS);
1292 inet_twsk_put((struct inet_timewait_sock *)sk); 1292 inet_twsk_put(inet_twsk(sk));
1293 goto discard_it; 1293 goto discard_it;
1294 } 1294 }
1295 1295
1296 switch (tcp_timewait_state_process((struct inet_timewait_sock *)sk, 1296 switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
1297 skb, th)) {
1298 case TCP_TW_SYN: 1297 case TCP_TW_SYN:
1299 { 1298 {
1300 struct sock *sk2; 1299 struct sock *sk2;
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 6a252e2134d1..73cee2ec07e8 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -73,7 +73,7 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
73 xdst->u.rt6.rt6i_src.plen); 73 xdst->u.rt6.rt6i_src.plen);
74 if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) && 74 if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) &&
75 ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) && 75 ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) &&
76 xfrm_bundle_ok(xdst, fl, AF_INET6, 76 xfrm_bundle_ok(policy, xdst, fl, AF_INET6,
77 (xdst->u.rt6.rt6i_dst.plen != 128 || 77 (xdst->u.rt6.rt6i_dst.plen != 128 ||
78 xdst->u.rt6.rt6i_src.plen != 128))) { 78 xdst->u.rt6.rt6i_src.plen != 128))) {
79 dst_clone(dst); 79 dst_clone(dst);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index ff98e70b0931..20ff7cca1d07 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -2928,11 +2928,6 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
2928 if (*dir) 2928 if (*dir)
2929 goto out; 2929 goto out;
2930 } 2930 }
2931 else {
2932 *dir = security_xfrm_sock_policy_alloc(xp, sk);
2933 if (*dir)
2934 goto out;
2935 }
2936 2931
2937 *dir = pol->sadb_x_policy_dir-1; 2932 *dir = pol->sadb_x_policy_dir-1;
2938 return xp; 2933 return xp;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 54fb7de3c2b1..ff971103fd0c 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -200,7 +200,7 @@ void netlbl_cache_invalidate(void)
200int netlbl_cache_add(const struct sk_buff *skb, 200int netlbl_cache_add(const struct sk_buff *skb,
201 const struct netlbl_lsm_secattr *secattr) 201 const struct netlbl_lsm_secattr *secattr)
202{ 202{
203 if (secattr->cache.data == NULL) 203 if (secattr->cache == NULL)
204 return -ENOMSG; 204 return -ENOMSG;
205 205
206 if (CIPSO_V4_OPTEXIST(skb)) 206 if (CIPSO_V4_OPTEXIST(skb))
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index bb3ddd4784b1..9b9c555c713f 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -786,11 +786,10 @@ static long htb_do_events(struct htb_sched *q, int level)
786 for (i = 0; i < 500; i++) { 786 for (i = 0; i < 500; i++) {
787 struct htb_class *cl; 787 struct htb_class *cl;
788 long diff; 788 long diff;
789 struct rb_node *p = q->wait_pq[level].rb_node; 789 struct rb_node *p = rb_first(&q->wait_pq[level]);
790
790 if (!p) 791 if (!p)
791 return 0; 792 return 0;
792 while (p->rb_left)
793 p = p->rb_left;
794 793
795 cl = rb_entry(p, struct htb_class, pq_node); 794 cl = rb_entry(p, struct htb_class, pq_node);
796 if (time_after(cl->pq_key, q->jiffies)) { 795 if (time_after(cl->pq_key, q->jiffies)) {
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index a356d8d310a9..7f49e769080e 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -344,7 +344,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
344 assoc, sk, sctp_sk(sk)->type, sk->sk_state, 344 assoc, sk, sctp_sk(sk)->type, sk->sk_state,
345 assoc->state, hash, assoc->assoc_id, 345 assoc->state, hash, assoc->assoc_id,
346 assoc->sndbuf_used, 346 assoc->sndbuf_used,
347 (sk->sk_rcvbuf - assoc->rwnd), 347 atomic_read(&assoc->rmem_alloc),
348 sock_i_uid(sk), sock_i_ino(sk), 348 sock_i_uid(sk), sock_i_ino(sk),
349 epb->bind_addr.port, 349 epb->bind_addr.port,
350 assoc->peer.port); 350 assoc->peer.port);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3fe906d65069..9deec4391187 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5362,6 +5362,20 @@ static void sctp_wfree(struct sk_buff *skb)
5362 sctp_association_put(asoc); 5362 sctp_association_put(asoc);
5363} 5363}
5364 5364
5365/* Do accounting for the receive space on the socket.
5366 * Accounting for the association is done in ulpevent.c
5367 * We set this as a destructor for the cloned data skbs so that
5368 * accounting is done at the correct time.
5369 */
5370void sctp_sock_rfree(struct sk_buff *skb)
5371{
5372 struct sock *sk = skb->sk;
5373 struct sctp_ulpevent *event = sctp_skb2event(skb);
5374
5375 atomic_sub(event->rmem_len, &sk->sk_rmem_alloc);
5376}
5377
5378
5365/* Helper function to wait for space in the sndbuf. */ 5379/* Helper function to wait for space in the sndbuf. */
5366static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, 5380static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p,
5367 size_t msg_len) 5381 size_t msg_len)
@@ -5634,10 +5648,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
5634 sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { 5648 sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) {
5635 event = sctp_skb2event(skb); 5649 event = sctp_skb2event(skb);
5636 if (event->asoc == assoc) { 5650 if (event->asoc == assoc) {
5637 sock_rfree(skb); 5651 sctp_sock_rfree(skb);
5638 __skb_unlink(skb, &oldsk->sk_receive_queue); 5652 __skb_unlink(skb, &oldsk->sk_receive_queue);
5639 __skb_queue_tail(&newsk->sk_receive_queue, skb); 5653 __skb_queue_tail(&newsk->sk_receive_queue, skb);
5640 skb_set_owner_r(skb, newsk); 5654 sctp_skb_set_owner_r(skb, newsk);
5641 } 5655 }
5642 } 5656 }
5643 5657
@@ -5665,10 +5679,10 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
5665 sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { 5679 sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) {
5666 event = sctp_skb2event(skb); 5680 event = sctp_skb2event(skb);
5667 if (event->asoc == assoc) { 5681 if (event->asoc == assoc) {
5668 sock_rfree(skb); 5682 sctp_sock_rfree(skb);
5669 __skb_unlink(skb, &oldsp->pd_lobby); 5683 __skb_unlink(skb, &oldsp->pd_lobby);
5670 __skb_queue_tail(queue, skb); 5684 __skb_queue_tail(queue, skb);
5671 skb_set_owner_r(skb, newsk); 5685 sctp_skb_set_owner_r(skb, newsk);
5672 } 5686 }
5673 } 5687 }
5674 5688
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index ee236784a6bb..a015283a9087 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -55,10 +55,13 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event);
55 55
56 56
57/* Initialize an ULP event from an given skb. */ 57/* Initialize an ULP event from an given skb. */
58SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) 58SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event,
59 int msg_flags,
60 unsigned int len)
59{ 61{
60 memset(event, 0, sizeof(struct sctp_ulpevent)); 62 memset(event, 0, sizeof(struct sctp_ulpevent));
61 event->msg_flags = msg_flags; 63 event->msg_flags = msg_flags;
64 event->rmem_len = len;
62} 65}
63 66
64/* Create a new sctp_ulpevent. */ 67/* Create a new sctp_ulpevent. */
@@ -73,7 +76,7 @@ SCTP_STATIC struct sctp_ulpevent *sctp_ulpevent_new(int size, int msg_flags,
73 goto fail; 76 goto fail;
74 77
75 event = sctp_skb2event(skb); 78 event = sctp_skb2event(skb);
76 sctp_ulpevent_init(event, msg_flags); 79 sctp_ulpevent_init(event, msg_flags, skb->truesize);
77 80
78 return event; 81 return event;
79 82
@@ -101,17 +104,16 @@ static inline void sctp_ulpevent_set_owner(struct sctp_ulpevent *event,
101 sctp_association_hold((struct sctp_association *)asoc); 104 sctp_association_hold((struct sctp_association *)asoc);
102 skb = sctp_event2skb(event); 105 skb = sctp_event2skb(event);
103 event->asoc = (struct sctp_association *)asoc; 106 event->asoc = (struct sctp_association *)asoc;
104 atomic_add(skb->truesize, &event->asoc->rmem_alloc); 107 atomic_add(event->rmem_len, &event->asoc->rmem_alloc);
105 skb_set_owner_r(skb, asoc->base.sk); 108 sctp_skb_set_owner_r(skb, asoc->base.sk);
106} 109}
107 110
108/* A simple destructor to give up the reference to the association. */ 111/* A simple destructor to give up the reference to the association. */
109static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) 112static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event)
110{ 113{
111 struct sctp_association *asoc = event->asoc; 114 struct sctp_association *asoc = event->asoc;
112 struct sk_buff *skb = sctp_event2skb(event);
113 115
114 atomic_sub(skb->truesize, &asoc->rmem_alloc); 116 atomic_sub(event->rmem_len, &asoc->rmem_alloc);
115 sctp_association_put(asoc); 117 sctp_association_put(asoc);
116} 118}
117 119
@@ -372,7 +374,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
372 374
373 /* Embed the event fields inside the cloned skb. */ 375 /* Embed the event fields inside the cloned skb. */
374 event = sctp_skb2event(skb); 376 event = sctp_skb2event(skb);
375 sctp_ulpevent_init(event, MSG_NOTIFICATION); 377 sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
376 378
377 sre = (struct sctp_remote_error *) 379 sre = (struct sctp_remote_error *)
378 skb_push(skb, sizeof(struct sctp_remote_error)); 380 skb_push(skb, sizeof(struct sctp_remote_error));
@@ -464,7 +466,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
464 466
465 /* Embed the event fields inside the cloned skb. */ 467 /* Embed the event fields inside the cloned skb. */
466 event = sctp_skb2event(skb); 468 event = sctp_skb2event(skb);
467 sctp_ulpevent_init(event, MSG_NOTIFICATION); 469 sctp_ulpevent_init(event, MSG_NOTIFICATION, skb->truesize);
468 470
469 ssf = (struct sctp_send_failed *) 471 ssf = (struct sctp_send_failed *)
470 skb_push(skb, sizeof(struct sctp_send_failed)); 472 skb_push(skb, sizeof(struct sctp_send_failed));
@@ -682,8 +684,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
682 /* Embed the event fields inside the cloned skb. */ 684 /* Embed the event fields inside the cloned skb. */
683 event = sctp_skb2event(skb); 685 event = sctp_skb2event(skb);
684 686
685 /* Initialize event with flags 0. */ 687 /* Initialize event with flags 0 and correct length
686 sctp_ulpevent_init(event, 0); 688 * Since this is a clone of the original skb, only account for
689 * the data of this chunk as other chunks will be accounted separately.
690 */
691 sctp_ulpevent_init(event, 0, skb->len + sizeof(struct sk_buff));
687 692
688 sctp_ulpevent_receive_data(event, asoc); 693 sctp_ulpevent_receive_data(event, asoc);
689 694
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 575e556aeb3e..e1d144275f97 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -309,7 +309,7 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *qu
309 if (!new) 309 if (!new)
310 return NULL; /* try again later */ 310 return NULL; /* try again later */
311 311
312 new->sk = f_frag->sk; 312 sctp_skb_set_owner_r(new, f_frag->sk);
313 313
314 skb_shinfo(new)->frag_list = pos; 314 skb_shinfo(new)->frag_list = pos;
315 } else 315 } else
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 2a7861661f14..7736b23c3f03 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -883,30 +883,32 @@ out:
883} 883}
884EXPORT_SYMBOL(xfrm_policy_walk); 884EXPORT_SYMBOL(xfrm_policy_walk);
885 885
886/* Find policy to apply to this flow. */ 886/*
887 887 * Find policy to apply to this flow.
888 *
889 * Returns 0 if policy found, else an -errno.
890 */
888static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, 891static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl,
889 u8 type, u16 family, int dir) 892 u8 type, u16 family, int dir)
890{ 893{
891 struct xfrm_selector *sel = &pol->selector; 894 struct xfrm_selector *sel = &pol->selector;
892 int match; 895 int match, ret = -ESRCH;
893 896
894 if (pol->family != family || 897 if (pol->family != family ||
895 pol->type != type) 898 pol->type != type)
896 return 0; 899 return ret;
897 900
898 match = xfrm_selector_match(sel, fl, family); 901 match = xfrm_selector_match(sel, fl, family);
899 if (match) { 902 if (match)
900 if (!security_xfrm_policy_lookup(pol, fl->secid, dir)) 903 ret = security_xfrm_policy_lookup(pol, fl->secid, dir);
901 return 1;
902 }
903 904
904 return 0; 905 return ret;
905} 906}
906 907
907static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, 908static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
908 u16 family, u8 dir) 909 u16 family, u8 dir)
909{ 910{
911 int err;
910 struct xfrm_policy *pol, *ret; 912 struct xfrm_policy *pol, *ret;
911 xfrm_address_t *daddr, *saddr; 913 xfrm_address_t *daddr, *saddr;
912 struct hlist_node *entry; 914 struct hlist_node *entry;
@@ -922,7 +924,15 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
922 chain = policy_hash_direct(daddr, saddr, family, dir); 924 chain = policy_hash_direct(daddr, saddr, family, dir);
923 ret = NULL; 925 ret = NULL;
924 hlist_for_each_entry(pol, entry, chain, bydst) { 926 hlist_for_each_entry(pol, entry, chain, bydst) {
925 if (xfrm_policy_match(pol, fl, type, family, dir)) { 927 err = xfrm_policy_match(pol, fl, type, family, dir);
928 if (err) {
929 if (err == -ESRCH)
930 continue;
931 else {
932 ret = ERR_PTR(err);
933 goto fail;
934 }
935 } else {
926 ret = pol; 936 ret = pol;
927 priority = ret->priority; 937 priority = ret->priority;
928 break; 938 break;
@@ -930,36 +940,53 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl,
930 } 940 }
931 chain = &xfrm_policy_inexact[dir]; 941 chain = &xfrm_policy_inexact[dir];
932 hlist_for_each_entry(pol, entry, chain, bydst) { 942 hlist_for_each_entry(pol, entry, chain, bydst) {
933 if (xfrm_policy_match(pol, fl, type, family, dir) && 943 err = xfrm_policy_match(pol, fl, type, family, dir);
934 pol->priority < priority) { 944 if (err) {
945 if (err == -ESRCH)
946 continue;
947 else {
948 ret = ERR_PTR(err);
949 goto fail;
950 }
951 } else if (pol->priority < priority) {
935 ret = pol; 952 ret = pol;
936 break; 953 break;
937 } 954 }
938 } 955 }
939 if (ret) 956 if (ret)
940 xfrm_pol_hold(ret); 957 xfrm_pol_hold(ret);
958fail:
941 read_unlock_bh(&xfrm_policy_lock); 959 read_unlock_bh(&xfrm_policy_lock);
942 960
943 return ret; 961 return ret;
944} 962}
945 963
946static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, 964static int xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
947 void **objp, atomic_t **obj_refp) 965 void **objp, atomic_t **obj_refp)
948{ 966{
949 struct xfrm_policy *pol; 967 struct xfrm_policy *pol;
968 int err = 0;
950 969
951#ifdef CONFIG_XFRM_SUB_POLICY 970#ifdef CONFIG_XFRM_SUB_POLICY
952 pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir); 971 pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_SUB, fl, family, dir);
953 if (pol) 972 if (IS_ERR(pol)) {
973 err = PTR_ERR(pol);
974 pol = NULL;
975 }
976 if (pol || err)
954 goto end; 977 goto end;
955#endif 978#endif
956 pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir); 979 pol = xfrm_policy_lookup_bytype(XFRM_POLICY_TYPE_MAIN, fl, family, dir);
957 980 if (IS_ERR(pol)) {
981 err = PTR_ERR(pol);
982 pol = NULL;
983 }
958#ifdef CONFIG_XFRM_SUB_POLICY 984#ifdef CONFIG_XFRM_SUB_POLICY
959end: 985end:
960#endif 986#endif
961 if ((*objp = (void *) pol) != NULL) 987 if ((*objp = (void *) pol) != NULL)
962 *obj_refp = &pol->refcnt; 988 *obj_refp = &pol->refcnt;
989 return err;
963} 990}
964 991
965static inline int policy_to_flow_dir(int dir) 992static inline int policy_to_flow_dir(int dir)
@@ -989,12 +1016,16 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
989 sk->sk_family); 1016 sk->sk_family);
990 int err = 0; 1017 int err = 0;
991 1018
992 if (match) 1019 if (match) {
993 err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir)); 1020 err = security_xfrm_policy_lookup(pol, fl->secid,
994 1021 policy_to_flow_dir(dir));
995 if (match && !err) 1022 if (!err)
996 xfrm_pol_hold(pol); 1023 xfrm_pol_hold(pol);
997 else 1024 else if (err == -ESRCH)
1025 pol = NULL;
1026 else
1027 pol = ERR_PTR(err);
1028 } else
998 pol = NULL; 1029 pol = NULL;
999 } 1030 }
1000 read_unlock_bh(&xfrm_policy_lock); 1031 read_unlock_bh(&xfrm_policy_lock);
@@ -1286,8 +1317,11 @@ restart:
1286 pol_dead = 0; 1317 pol_dead = 0;
1287 xfrm_nr = 0; 1318 xfrm_nr = 0;
1288 1319
1289 if (sk && sk->sk_policy[1]) 1320 if (sk && sk->sk_policy[1]) {
1290 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl); 1321 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
1322 if (IS_ERR(policy))
1323 return PTR_ERR(policy);
1324 }
1291 1325
1292 if (!policy) { 1326 if (!policy) {
1293 /* To accelerate a bit... */ 1327 /* To accelerate a bit... */
@@ -1297,6 +1331,8 @@ restart:
1297 1331
1298 policy = flow_cache_lookup(fl, dst_orig->ops->family, 1332 policy = flow_cache_lookup(fl, dst_orig->ops->family,
1299 dir, xfrm_policy_lookup); 1333 dir, xfrm_policy_lookup);
1334 if (IS_ERR(policy))
1335 return PTR_ERR(policy);
1300 } 1336 }
1301 1337
1302 if (!policy) 1338 if (!policy)
@@ -1343,6 +1379,10 @@ restart:
1343 fl, family, 1379 fl, family,
1344 XFRM_POLICY_OUT); 1380 XFRM_POLICY_OUT);
1345 if (pols[1]) { 1381 if (pols[1]) {
1382 if (IS_ERR(pols[1])) {
1383 err = PTR_ERR(pols[1]);
1384 goto error;
1385 }
1346 if (pols[1]->action == XFRM_POLICY_BLOCK) { 1386 if (pols[1]->action == XFRM_POLICY_BLOCK) {
1347 err = -EPERM; 1387 err = -EPERM;
1348 goto error; 1388 goto error;
@@ -1574,13 +1614,19 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1574 } 1614 }
1575 1615
1576 pol = NULL; 1616 pol = NULL;
1577 if (sk && sk->sk_policy[dir]) 1617 if (sk && sk->sk_policy[dir]) {
1578 pol = xfrm_sk_policy_lookup(sk, dir, &fl); 1618 pol = xfrm_sk_policy_lookup(sk, dir, &fl);
1619 if (IS_ERR(pol))
1620 return 0;
1621 }
1579 1622
1580 if (!pol) 1623 if (!pol)
1581 pol = flow_cache_lookup(&fl, family, fl_dir, 1624 pol = flow_cache_lookup(&fl, family, fl_dir,
1582 xfrm_policy_lookup); 1625 xfrm_policy_lookup);
1583 1626
1627 if (IS_ERR(pol))
1628 return 0;
1629
1584 if (!pol) { 1630 if (!pol) {
1585 if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) { 1631 if (skb->sp && secpath_has_nontransport(skb->sp, 0, &xerr_idx)) {
1586 xfrm_secpath_reject(xerr_idx, skb, &fl); 1632 xfrm_secpath_reject(xerr_idx, skb, &fl);
@@ -1599,6 +1645,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1599 &fl, family, 1645 &fl, family,
1600 XFRM_POLICY_IN); 1646 XFRM_POLICY_IN);
1601 if (pols[1]) { 1647 if (pols[1]) {
1648 if (IS_ERR(pols[1]))
1649 return 0;
1602 pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec; 1650 pols[1]->curlft.use_time = (unsigned long)xtime.tv_sec;
1603 npols ++; 1651 npols ++;
1604 } 1652 }
@@ -1706,7 +1754,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
1706 1754
1707static int stale_bundle(struct dst_entry *dst) 1755static int stale_bundle(struct dst_entry *dst)
1708{ 1756{
1709 return !xfrm_bundle_ok((struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0); 1757 return !xfrm_bundle_ok(NULL, (struct xfrm_dst *)dst, NULL, AF_UNSPEC, 0);
1710} 1758}
1711 1759
1712void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) 1760void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev)
@@ -1828,7 +1876,8 @@ EXPORT_SYMBOL(xfrm_init_pmtu);
1828 * still valid. 1876 * still valid.
1829 */ 1877 */
1830 1878
1831int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int strict) 1879int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
1880 struct flowi *fl, int family, int strict)
1832{ 1881{
1833 struct dst_entry *dst = &first->u.dst; 1882 struct dst_entry *dst = &first->u.dst;
1834 struct xfrm_dst *last; 1883 struct xfrm_dst *last;
@@ -1845,7 +1894,7 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int str
1845 1894
1846 if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) 1895 if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family))
1847 return 0; 1896 return 0;
1848 if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm)) 1897 if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol))
1849 return 0; 1898 return 0;
1850 if (dst->xfrm->km.state != XFRM_STATE_VALID) 1899 if (dst->xfrm->km.state != XFRM_STATE_VALID)
1851 return 0; 1900 return 0;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index d54b3a70d5df..2b2e59d8ffbc 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1992,15 +1992,6 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
1992 xp->type = XFRM_POLICY_TYPE_MAIN; 1992 xp->type = XFRM_POLICY_TYPE_MAIN;
1993 copy_templates(xp, ut, nr); 1993 copy_templates(xp, ut, nr);
1994 1994
1995 if (!xp->security) {
1996 int err = security_xfrm_sock_policy_alloc(xp, sk);
1997 if (err) {
1998 kfree(xp);
1999 *dir = err;
2000 return NULL;
2001 }
2002 }
2003
2004 *dir = p->dir; 1995 *dir = p->dir;
2005 1996
2006 return xp; 1997 return xp;
diff --git a/security/dummy.c b/security/dummy.c
index aeee70565509..43874c1e6e23 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -881,7 +881,8 @@ static int dummy_xfrm_state_pol_flow_match(struct xfrm_state *x,
881 return 1; 881 return 1;
882} 882}
883 883
884static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) 884static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
885 struct xfrm_policy *xp)
885{ 886{
886 return 1; 887 return 1;
887} 888}
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 81eb59890162..526b28019aca 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -19,7 +19,8 @@ int selinux_xfrm_state_delete(struct xfrm_state *x);
19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); 19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
20int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, 20int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
21 struct xfrm_policy *xp, struct flowi *fl); 21 struct xfrm_policy *xp, struct flowi *fl);
22int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); 22int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
23 struct xfrm_policy *xp);
23 24
24 25
25/* 26/*
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index b18895302555..ba48961f9d05 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -618,6 +618,7 @@ void policydb_destroy(struct policydb *p)
618 c = c->next; 618 c = c->next;
619 ocontext_destroy(ctmp,i); 619 ocontext_destroy(ctmp,i);
620 } 620 }
621 p->ocontexts[i] = NULL;
621 } 622 }
622 623
623 g = p->genfs; 624 g = p->genfs;
@@ -633,6 +634,7 @@ void policydb_destroy(struct policydb *p)
633 g = g->next; 634 g = g->next;
634 kfree(gtmp); 635 kfree(gtmp);
635 } 636 }
637 p->genfs = NULL;
636 638
637 cond_policydb_destroy(p); 639 cond_policydb_destroy(p);
638 640
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 0c219a1b3243..18274b005090 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2172,7 +2172,12 @@ struct netlbl_cache {
2172 */ 2172 */
2173static void selinux_netlbl_cache_free(const void *data) 2173static void selinux_netlbl_cache_free(const void *data)
2174{ 2174{
2175 struct netlbl_cache *cache = NETLBL_CACHE(data); 2175 struct netlbl_cache *cache;
2176
2177 if (data == NULL)
2178 return;
2179
2180 cache = NETLBL_CACHE(data);
2176 switch (cache->type) { 2181 switch (cache->type) {
2177 case NETLBL_CACHE_T_MLS: 2182 case NETLBL_CACHE_T_MLS:
2178 ebitmap_destroy(&cache->data.mls_label.level[0].cat); 2183 ebitmap_destroy(&cache->data.mls_label.level[0].cat);
@@ -2197,17 +2202,20 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx)
2197 struct netlbl_lsm_secattr secattr; 2202 struct netlbl_lsm_secattr secattr;
2198 2203
2199 netlbl_secattr_init(&secattr); 2204 netlbl_secattr_init(&secattr);
2205 secattr.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC);
2206 if (secattr.cache == NULL)
2207 goto netlbl_cache_add_return;
2200 2208
2201 cache = kzalloc(sizeof(*cache), GFP_ATOMIC); 2209 cache = kzalloc(sizeof(*cache), GFP_ATOMIC);
2202 if (cache == NULL) 2210 if (cache == NULL)
2203 goto netlbl_cache_add_failure; 2211 goto netlbl_cache_add_return;
2204 secattr.cache.free = selinux_netlbl_cache_free; 2212 secattr.cache->free = selinux_netlbl_cache_free;
2205 secattr.cache.data = (void *)cache; 2213 secattr.cache->data = (void *)cache;
2206 2214
2207 cache->type = NETLBL_CACHE_T_MLS; 2215 cache->type = NETLBL_CACHE_T_MLS;
2208 if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, 2216 if (ebitmap_cpy(&cache->data.mls_label.level[0].cat,
2209 &ctx->range.level[0].cat) != 0) 2217 &ctx->range.level[0].cat) != 0)
2210 goto netlbl_cache_add_failure; 2218 goto netlbl_cache_add_return;
2211 cache->data.mls_label.level[1].cat.highbit = 2219 cache->data.mls_label.level[1].cat.highbit =
2212 cache->data.mls_label.level[0].cat.highbit; 2220 cache->data.mls_label.level[0].cat.highbit;
2213 cache->data.mls_label.level[1].cat.node = 2221 cache->data.mls_label.level[1].cat.node =
@@ -2215,13 +2223,10 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx)
2215 cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; 2223 cache->data.mls_label.level[0].sens = ctx->range.level[0].sens;
2216 cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; 2224 cache->data.mls_label.level[1].sens = ctx->range.level[0].sens;
2217 2225
2218 if (netlbl_cache_add(skb, &secattr) != 0) 2226 netlbl_cache_add(skb, &secattr);
2219 goto netlbl_cache_add_failure;
2220 2227
2221 return; 2228netlbl_cache_add_return:
2222 2229 netlbl_secattr_destroy(&secattr);
2223netlbl_cache_add_failure:
2224 netlbl_secattr_destroy(&secattr, 1);
2225} 2230}
2226 2231
2227/** 2232/**
@@ -2263,8 +2268,8 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb,
2263 2268
2264 POLICY_RDLOCK; 2269 POLICY_RDLOCK;
2265 2270
2266 if (secattr->cache.data) { 2271 if (secattr->cache) {
2267 cache = NETLBL_CACHE(secattr->cache.data); 2272 cache = NETLBL_CACHE(secattr->cache->data);
2268 switch (cache->type) { 2273 switch (cache->type) {
2269 case NETLBL_CACHE_T_SID: 2274 case NETLBL_CACHE_T_SID:
2270 *sid = cache->data.sid; 2275 *sid = cache->data.sid;
@@ -2331,7 +2336,7 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb,
2331 selinux_netlbl_cache_add(skb, &ctx_new); 2336 selinux_netlbl_cache_add(skb, &ctx_new);
2332 ebitmap_destroy(&ctx_new.range.level[0].cat); 2337 ebitmap_destroy(&ctx_new.range.level[0].cat);
2333 } else { 2338 } else {
2334 *sid = SECINITSID_UNLABELED; 2339 *sid = SECSID_NULL;
2335 rc = 0; 2340 rc = 0;
2336 } 2341 }
2337 2342
@@ -2369,7 +2374,7 @@ static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
2369 &secattr, 2374 &secattr,
2370 base_sid, 2375 base_sid,
2371 sid); 2376 sid);
2372 netlbl_secattr_destroy(&secattr, 0); 2377 netlbl_secattr_destroy(&secattr);
2373 2378
2374 return rc; 2379 return rc;
2375} 2380}
@@ -2415,7 +2420,7 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid)
2415 if (rc == 0) 2420 if (rc == 0)
2416 sksec->nlbl_state = NLBL_LABELED; 2421 sksec->nlbl_state = NLBL_LABELED;
2417 2422
2418 netlbl_secattr_destroy(&secattr, 0); 2423 netlbl_secattr_destroy(&secattr);
2419 2424
2420netlbl_socket_setsid_return: 2425netlbl_socket_setsid_return:
2421 POLICY_RDUNLOCK; 2426 POLICY_RDUNLOCK;
@@ -2514,10 +2519,10 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
2514 if (netlbl_sock_getattr(sk, &secattr) == 0 && 2519 if (netlbl_sock_getattr(sk, &secattr) == 0 &&
2515 selinux_netlbl_secattr_to_sid(NULL, 2520 selinux_netlbl_secattr_to_sid(NULL,
2516 &secattr, 2521 &secattr,
2517 sksec->sid, 2522 SECINITSID_UNLABELED,
2518 &nlbl_peer_sid) == 0) 2523 &nlbl_peer_sid) == 0)
2519 sksec->peer_sid = nlbl_peer_sid; 2524 sksec->peer_sid = nlbl_peer_sid;
2520 netlbl_secattr_destroy(&secattr, 0); 2525 netlbl_secattr_destroy(&secattr);
2521 2526
2522 sksec->nlbl_state = NLBL_REQUIRE; 2527 sksec->nlbl_state = NLBL_REQUIRE;
2523 2528
@@ -2547,9 +2552,6 @@ u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid)
2547 if (rc != 0) 2552 if (rc != 0)
2548 return SECSID_NULL; 2553 return SECSID_NULL;
2549 2554
2550 if (peer_sid == SECINITSID_UNLABELED)
2551 return SECSID_NULL;
2552
2553 return peer_sid; 2555 return peer_sid;
2554} 2556}
2555 2557
@@ -2611,11 +2613,13 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
2611 u32 netlbl_sid; 2613 u32 netlbl_sid;
2612 u32 recv_perm; 2614 u32 recv_perm;
2613 2615
2614 rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &netlbl_sid); 2616 rc = selinux_netlbl_skbuff_getsid(skb,
2617 SECINITSID_UNLABELED,
2618 &netlbl_sid);
2615 if (rc != 0) 2619 if (rc != 0)
2616 return rc; 2620 return rc;
2617 2621
2618 if (netlbl_sid == SECINITSID_UNLABELED) 2622 if (netlbl_sid == SECSID_NULL)
2619 return 0; 2623 return 0;
2620 2624
2621 switch (sksec->sclass) { 2625 switch (sksec->sclass) {
@@ -2653,10 +2657,6 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
2653u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) 2657u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
2654{ 2658{
2655 struct sk_security_struct *sksec = sock->sk->sk_security; 2659 struct sk_security_struct *sksec = sock->sk->sk_security;
2656
2657 if (sksec->peer_sid == SECINITSID_UNLABELED)
2658 return SECSID_NULL;
2659
2660 return sksec->peer_sid; 2660 return sksec->peer_sid;
2661} 2661}
2662 2662
@@ -2672,16 +2672,10 @@ u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock)
2672u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb) 2672u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
2673{ 2673{
2674 int peer_sid; 2674 int peer_sid;
2675 struct sock *sk = skb->sk;
2676 struct inode_security_struct *isec;
2677 2675
2678 if (sk == NULL || sk->sk_socket == NULL) 2676 if (selinux_netlbl_skbuff_getsid(skb,
2679 return SECSID_NULL; 2677 SECINITSID_UNLABELED,
2680 2678 &peer_sid) != 0)
2681 isec = SOCK_INODE(sk->sk_socket)->i_security;
2682 if (selinux_netlbl_skbuff_getsid(skb, isec->sid, &peer_sid) != 0)
2683 return SECSID_NULL;
2684 if (peer_sid == SECINITSID_UNLABELED)
2685 return SECSID_NULL; 2679 return SECSID_NULL;
2686 2680
2687 return peer_sid; 2681 return peer_sid;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 3e742b850af6..675b995a67c3 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -77,8 +77,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
77 */ 77 */
78int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) 78int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
79{ 79{
80 int rc = 0; 80 int rc;
81 u32 sel_sid = SECINITSID_UNLABELED; 81 u32 sel_sid;
82 struct xfrm_sec_ctx *ctx; 82 struct xfrm_sec_ctx *ctx;
83 83
84 /* Context sid is either set to label or ANY_ASSOC */ 84 /* Context sid is either set to label or ANY_ASSOC */
@@ -88,11 +88,21 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
88 88
89 sel_sid = ctx->ctx_sid; 89 sel_sid = ctx->ctx_sid;
90 } 90 }
91 else
92 /*
93 * All flows should be treated as polmatch'ing an
94 * otherwise applicable "non-labeled" policy. This
95 * would prevent inadvertent "leaks".
96 */
97 return 0;
91 98
92 rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, 99 rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION,
93 ASSOCIATION__POLMATCH, 100 ASSOCIATION__POLMATCH,
94 NULL); 101 NULL);
95 102
103 if (rc == -EACCES)
104 rc = -ESRCH;
105
96 return rc; 106 return rc;
97} 107}
98 108
@@ -108,15 +118,20 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
108 u32 pol_sid; 118 u32 pol_sid;
109 int err; 119 int err;
110 120
111 if (x->security) 121 if (xp->security) {
112 state_sid = x->security->ctx_sid; 122 if (!x->security)
113 else 123 /* unlabeled SA and labeled policy can't match */
114 state_sid = SECINITSID_UNLABELED; 124 return 0;
115 125 else
116 if (xp->security) 126 state_sid = x->security->ctx_sid;
117 pol_sid = xp->security->ctx_sid; 127 pol_sid = xp->security->ctx_sid;
118 else 128 } else
119 pol_sid = SECINITSID_UNLABELED; 129 if (x->security)
130 /* unlabeled policy and labeled SA can't match */
131 return 0;
132 else
133 /* unlabeled policy and unlabeled SA match all flows */
134 return 1;
120 135
121 err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION, 136 err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION,
122 ASSOCIATION__POLMATCH, 137 ASSOCIATION__POLMATCH,
@@ -125,7 +140,11 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
125 if (err) 140 if (err)
126 return 0; 141 return 0;
127 142
128 return selinux_xfrm_flow_state_match(fl, x); 143 err = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION,
144 ASSOCIATION__SENDTO,
145 NULL)? 0:1;
146
147 return err;
129} 148}
130 149
131/* 150/*
@@ -133,12 +152,22 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
133 * can use a given security association. 152 * can use a given security association.
134 */ 153 */
135 154
136int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) 155int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
156 struct xfrm_policy *xp)
137{ 157{
138 int rc = 0; 158 int rc = 0;
139 u32 sel_sid = SECINITSID_UNLABELED; 159 u32 sel_sid = SECINITSID_UNLABELED;
140 struct xfrm_sec_ctx *ctx; 160 struct xfrm_sec_ctx *ctx;
141 161
162 if (!xp->security)
163 if (!xfrm->security)
164 return 1;
165 else
166 return 0;
167 else
168 if (!xfrm->security)
169 return 0;
170
142 /* Context sid is either set to label or ANY_ASSOC */ 171 /* Context sid is either set to label or ANY_ASSOC */
143 if ((ctx = xfrm->security)) { 172 if ((ctx = xfrm->security)) {
144 if (!selinux_authorizable_ctx(ctx)) 173 if (!selinux_authorizable_ctx(ctx))