diff options
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: */ |
18 | extern void __divl (void); | 18 | extern 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 |
46 | static void | 46 | static void |
47 | voyager_dump(int dummy1, struct pt_regs *dummy2, struct tty_struct *dummy3) | 47 | voyager_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). */ |
168 | void | 168 | void |
169 | voyager_timer_interrupt(struct pt_regs *regs) | 169 | voyager_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); | |||
85 | static void ack_special_QIC_CPI(__u8 cpi); | 85 | static void ack_special_QIC_CPI(__u8 cpi); |
86 | static void ack_VIC_CPI(__u8 cpi); | 86 | static void ack_VIC_CPI(__u8 cpi); |
87 | static void send_CPI_allbutself(__u8 cpi); | 87 | static void send_CPI_allbutself(__u8 cpi); |
88 | static void enable_vic_irq(unsigned int irq); | 88 | static void mask_vic_irq(unsigned int irq); |
89 | static void disable_vic_irq(unsigned int irq); | 89 | static void unmask_vic_irq(unsigned int irq); |
90 | static unsigned int startup_vic_irq(unsigned int irq); | 90 | static unsigned int startup_vic_irq(unsigned int irq); |
91 | static void enable_local_vic_irq(unsigned int irq); | 91 | static void enable_local_vic_irq(unsigned int irq); |
92 | static void disable_local_vic_irq(unsigned int irq); | 92 | static 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 | */ |
208 | static struct hw_interrupt_type vic_irq_type = { | 208 | static 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) | |||
1144 | fastcall void | 1141 | fastcall void |
1145 | smp_qic_timer_interrupt(struct pt_regs *regs) | 1142 | smp_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 */ |
1272 | void | 1269 | void |
1273 | smp_vic_timer_interrupt(struct pt_regs *regs) | 1270 | smp_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 */ | ||
1398 | static void fastcall | ||
1399 | handle_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) | |||
1531 | static unsigned int | 1537 | static unsigned int |
1532 | startup_vic_irq(unsigned int irq) | 1538 | startup_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 | ||
1560 | static void | 1566 | static void |
1561 | enable_vic_irq(unsigned int irq) | 1567 | unmask_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 | ||
1593 | static void | 1599 | static void |
1594 | disable_vic_irq(unsigned int irq) | 1600 | mask_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 | ||
1825 | static void | 1831 | static 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 | |||
45 | config GENERIC_IOMAP | 45 | config GENERIC_IOMAP |
46 | bool | 46 | bool |
47 | 47 | ||
48 | config GENERIC_TIME | ||
49 | def_bool n | ||
50 | |||
48 | config ARCH_MAY_HAVE_PC_FDC | 51 | config ARCH_MAY_HAVE_PC_FDC |
49 | bool | 52 | bool |
50 | 53 | ||
@@ -357,6 +360,7 @@ config CPU_HAS_SR_RB | |||
357 | endmenu | 360 | endmenu |
358 | 361 | ||
359 | menu "Timer support" | 362 | menu "Timer support" |
363 | depends on !GENERIC_TIME | ||
360 | 364 | ||
361 | config SH_TMU | 365 | config 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 | ||
86 | static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs) | 86 | static 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 | ||
138 | static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 138 | static 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 | ||
70 | static unsigned char m_irq_mask = 0xfb; | 70 | static unsigned char m_irq_mask = 0xfb; |
71 | static unsigned char s_irq_mask = 0xff; | 71 | static unsigned char s_irq_mask = 0xff; |
72 | volatile unsigned long irq_err_count; | ||
73 | 72 | ||
74 | static void disable_mpc1211_irq(unsigned int irq) | 73 | static 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 |
18 | static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; | 16 | static 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}; | |||
20 | static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; | 18 | static 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 | ||
23 | static void enable_r7780rp_irq(unsigned int irq); | ||
24 | static void disable_r7780rp_irq(unsigned int irq); | ||
25 | |||
26 | /* shutdown is same as "disable" */ | ||
27 | #define shutdown_r7780rp_irq disable_r7780rp_irq | ||
28 | |||
29 | static void ack_r7780rp_irq(unsigned int irq); | ||
30 | static void end_r7780rp_irq(unsigned int irq); | ||
31 | |||
32 | static unsigned int startup_r7780rp_irq(unsigned int irq) | ||
33 | { | ||
34 | enable_r7780rp_irq(irq); | ||
35 | return 0; /* never anything pending */ | ||
36 | } | ||
37 | |||
38 | static 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 | |||
49 | static void enable_r7780rp_irq(unsigned int irq) | 21 | static 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 | |||
60 | static void ack_r7780rp_irq(unsigned int irq) | ||
61 | { | ||
62 | disable_r7780rp_irq(irq); | ||
63 | } | 25 | } |
64 | 26 | ||
65 | static void end_r7780rp_irq(unsigned int irq) | 27 | static 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 | ||
71 | static struct hw_interrupt_type r7780rp_irq_type = { | 34 | static 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 | ||
81 | static 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 | ||
36 | static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 36 | static 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 | ||
74 | static irqreturn_t hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 74 | static 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 | ||
88 | static irqreturn_t hd64465_gpio_interrupt(int irq, void *dev, struct pt_regs *regs) | 88 | static 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 | ||
87 | static irqreturn_t hd64465_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 87 | static 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 | ||
91 | static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, | 91 | static 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 | ||
54 | static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 54 | static 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 @@ | |||
21 | static unsigned int xfer_complete; | 21 | static unsigned int xfer_complete; |
22 | static int count; | 22 | static int count; |
23 | 23 | ||
24 | static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 24 | static 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 | */ |
63 | static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) | 63 | static 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) |
231 | static irqreturn_t dma_err(int irq, void *dev_id, struct pt_regs *regs) | 231 | static 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 | ||
164 | static irqreturn_t st40_pci_irq(int irq, void *dev_instance, struct pt_regs *regs) | 164 | static 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 | |||
21 | struct intc2_data { | ||
22 | unsigned char msk_offset; | ||
23 | unsigned char msk_shift; | ||
24 | |||
25 | int (*clear_irq) (int); | ||
26 | }; | ||
27 | |||
28 | static struct intc2_data intc2_data[NR_INTC2_IRQS]; | ||
29 | |||
30 | static void enable_intc2_irq(unsigned int irq); | ||
31 | static void disable_intc2_irq(unsigned int irq); | ||
32 | |||
33 | /* shutdown is same as "disable" */ | ||
34 | #define shutdown_intc2_irq disable_intc2_irq | ||
35 | |||
36 | static void mask_and_ack_intc2(unsigned int); | ||
37 | static void end_intc2_irq(unsigned int irq); | ||
38 | |||
39 | static unsigned int startup_intc2_irq(unsigned int irq) | ||
40 | { | ||
41 | enable_intc2_irq(irq); | ||
42 | return 0; /* never anything pending */ | ||
43 | } | ||
44 | |||
45 | static 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 | ||
55 | static void disable_intc2_irq(unsigned int irq) | 19 | static 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 | ||
71 | static void enable_intc2_irq(unsigned int irq) | 26 | static 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 | |||
87 | static void mask_and_ack_intc2(unsigned int irq) | ||
88 | { | ||
89 | disable_intc2_irq(irq); | ||
90 | } | 31 | } |
91 | 32 | ||
92 | static void end_intc2_irq(unsigned int irq) | 33 | static 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 | */ |
111 | void make_intc2_irq(unsigned int irq, | 50 | void 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 | ||
145 | static struct intc2_init { | 73 | static 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 */ | ||
277 | void 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 | }; |
31 | static struct ipr_data ipr_data[NR_IRQS]; | ||
32 | |||
33 | static void enable_ipr_irq(unsigned int irq); | ||
34 | static void disable_ipr_irq(unsigned int irq); | ||
35 | |||
36 | /* shutdown is same as "disable" */ | ||
37 | #define shutdown_ipr_irq disable_ipr_irq | ||
38 | |||
39 | static void mask_and_ack_ipr(unsigned int); | ||
40 | static void end_ipr_irq(unsigned int irq); | ||
41 | |||
42 | static unsigned int startup_ipr_irq(unsigned int irq) | ||
43 | { | ||
44 | enable_ipr_irq(irq); | ||
45 | return 0; /* never anything pending */ | ||
46 | } | ||
47 | |||
48 | static 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 | ||
58 | static void disable_ipr_irq(unsigned int irq) | 32 | static 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 | ||
70 | static void enable_ipr_irq(unsigned int irq) | 39 | static 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 | ||
83 | static void mask_and_ack_ipr(unsigned int irq) | 46 | static 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 | |||
101 | static 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 | ||
107 | void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) | 53 | void 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.. */ | ||
118 | void __init init_IRQ(void) | 70 | void __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 |
50 | ENTRY(user_break_point_trap) | 50 | ENTRY(user_break_point_trap) |
51 | .long break_point_trap /* 1E0 */ | 51 | .long break_point_trap /* 1E0 */ |
52 | ENTRY(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 |
54 | ENTRY(user_break_point_trap) | 54 | ENTRY(user_break_point_trap) |
55 | .long break_point_trap /* 1E0 */ | 55 | .long break_point_trap /* 1E0 */ |
56 | ENTRY(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: | |||
691 | 0: | 689 | 0: |
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 |
697 | 1: .long EXPEVT | 695 | 1: .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 | ! |
720 | 1: mov #-1, k4 | 718 | 1: 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 |
811 | 1: .long 0x00001000 ! DSP=1 | 825 | 1: .long 0x00001000 ! DSP=1 |
@@ -813,8 +827,17 @@ skip_save: | |||
813 | 3: .long 0xcfffffff ! RB=0, BL=0 | 827 | 3: .long 0xcfffffff ! RB=0, BL=0 |
814 | 4: .long exception_handling_table | 828 | 4: .long exception_handling_table |
815 | 829 | ||
830 | interrupt_exception: | ||
831 | mov.l 1f, r9 | ||
832 | jmp @r9 | ||
833 | nop | ||
834 | rts | ||
835 | nop | ||
836 | |||
837 | .align 2 | ||
838 | 1: .long do_IRQ | ||
839 | |||
816 | .align 2 | 840 | .align 2 |
817 | ENTRY(exception_none) | 841 | ENTRY(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 | ||
21 | atomic_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 | */ |
25 | void ack_bad_irq(unsigned int irq) | 28 | void 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'); |
57 | unlock: | 63 | unlock: |
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(®s); |
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" (®s), "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, ®s); | 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, | |||
290 | static void | 291 | static void |
291 | ubc_set_tracing(int asid, unsigned long pc) | 292 | ubc_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 | ||
50 | void do_gettimeofday(struct timeval *tv) | 51 | void 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 | } |
101 | EXPORT_SYMBOL(do_settimeofday); | 102 | EXPORT_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 */ |
104 | static long last_rtc_update; | 106 | static 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 | */ |
110 | void handle_timer_tick(struct pt_regs *regs) | 112 | void 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 | ||
83 | static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id, | 83 | static 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 | */ | ||
117 | static 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 | |||
168 | static void tmu_clk_init(struct clk *clk) | 113 | static 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 | ||
239 | struct sys_timer tmu_timer = { | 185 | struct 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 | ||
39 | unsigned int pcic_pin_to_irq(unsigned int pin, char *name); | 40 | unsigned 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 | ||
124 | int 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 | ||
405 | void srmmu_nocache_init(void) | 405 | void __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 | ||
94 | int 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 | ||
18 | static int __init vsmp_init(void) | 19 | static 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 | ||
94 | static struct elevator_type *elevator_find(const char *name) | 94 | static 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 | ||
113 | static void elevator_put(struct elevator_type *e) | 110 | static 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 | ||
1185 | static struct console sunzilog_console = { | 1185 | static 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 | |||
1986 | config CIFS_UPCALL | 1986 | config 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) | |||
1152 | static int dump_seek(struct file *file, loff_t off) | 1152 | static 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 */ |
34 | extern const struct cifs_sid sid_everyone; | 34 | /* extern const struct cifs_sid sid_everyone;*/ |
35 | /* group users */ | 35 | /* group users */ |
36 | extern 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 */ |
28 | extern void E_P16(unsigned char *p14, unsigned char *p16); | 28 | extern void E_P16(unsigned char *p14, unsigned char *p16); |
29 | extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); | 29 | extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); |
30 | extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); | ||
31 | extern 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 */ | |||
63 | struct task_struct * oplockThread = NULL; | 63 | struct task_struct * oplockThread = NULL; |
64 | extern struct task_struct * dnotifyThread; /* remove sparse warning */ | 64 | extern struct task_struct * dnotifyThread; /* remove sparse warning */ |
65 | struct task_struct * dnotifyThread = NULL; | 65 | struct task_struct * dnotifyThread = NULL; |
66 | static struct super_operations cifs_super_ops; | ||
66 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; | 67 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; |
67 | module_param(CIFSMaxBufSize, int, 0); | 68 | module_param(CIFSMaxBufSize, int, 0); |
68 | MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); | 69 | MODULE_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 | ||
442 | static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt) | ||
443 | { | ||
444 | /* BB FIXME */ | ||
445 | return 0; | ||
446 | } | ||
447 | #endif | ||
448 | |||
438 | static int cifs_remount(struct super_block *sb, int *flags, char *data) | 449 | static 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 | ||
444 | struct super_operations cifs_super_ops = { | 455 | static 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 | ||
459 | static int | 473 | static int |
@@ -495,7 +509,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
495 | static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) | 509 | static 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; | |||
36 | extern const struct address_space_operations cifs_addr_ops_smallbuf; | 36 | extern 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 */ |
39 | extern struct super_operations cifs_super_ops; | 39 | /* extern struct super_operations cifs_super_ops;*/ |
40 | extern void cifs_read_inode(struct inode *); | 40 | extern void cifs_read_inode(struct inode *); |
41 | extern void cifs_delete_inode(struct inode *); | 41 | extern 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 | */ |
515 | GLOBAL_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; | |||
568 | GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent | 574 | GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent |
569 | with more secure ntlmssp2 challenge/resp */ | 575 | with more secure ntlmssp2 challenge/resp */ |
570 | GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ | 576 | GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ |
571 | GLOBAL_EXTERN unsigned int secFlags; | ||
572 | GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ | 577 | GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ |
573 | GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ | 578 | GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */ |
574 | GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ | 579 | GLOBAL_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 | |||
411 | typedef struct lanman_neg_rsp { | 414 | typedef 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 | |||
674 | typedef struct smb_com_close_req { | 680 | typedef 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 *, | |||
50 | extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, | 50 | extern 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); |
53 | extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *, | 53 | extern 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 */); |
57 | extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); | 58 | extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); |
58 | extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); | ||
59 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); | 59 | extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); |
60 | extern int is_size_safe_to_change(struct cifsInodeInfo *); | 60 | extern int is_size_safe_to_change(struct cifsInodeInfo *); |
61 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); | 61 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *); |
@@ -80,6 +80,9 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, | |||
80 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 80 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
81 | extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); | 81 | extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); |
82 | extern u64 cifs_UnixTimeToNT(struct timespec); | 82 | extern u64 cifs_UnixTimeToNT(struct timespec); |
83 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); | ||
84 | extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); | ||
85 | |||
83 | extern int cifs_get_inode_info(struct inode **pinode, | 86 | extern 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, | |||
116 | extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, | 119 | extern 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); |
120 | extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, | 124 | extern 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 *); | |||
279 | extern struct cifsTconInfo *tconInfoAlloc(void); | 283 | extern struct cifsTconInfo *tconInfoAlloc(void); |
280 | extern void tconInfoFree(struct cifsTconInfo *); | 284 | extern void tconInfoFree(struct cifsTconInfo *); |
281 | 285 | ||
282 | extern int cifs_reconnect(struct TCP_Server_Info *server); | ||
283 | |||
284 | extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); | 286 | extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); |
285 | extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, | 287 | extern 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 */ |
2776 | const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; | 2813 | const 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 */ |
2778 | const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | 2816 | const 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 */ |
2781 | static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len) | 2820 | static 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 */ |
2862 | int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, | 2900 | int 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 | |||
2922 | CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, | 2969 | CIFSSMBQPathInfo(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 | ||
112 | int | 112 | static int |
113 | cifs_reconnect(struct TCP_Server_Info *server) | 113 | cifs_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 | ***********************************************************************/ |
258 | void | 259 | static void |
259 | hmac_md5_init_rfc2104(unsigned char *key, int key_len, | 260 | hmac_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 | ************************************************************/ |
353 | void | 355 | #if 0 /* currently unused */ |
356 | static void | ||
354 | hmac_md5(unsigned char key[16], unsigned char *data, int data_len, | 357 | hmac_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 | ||
30 | void 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);*/ |
32 | void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, | 32 | void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, |
33 | struct HMACMD5Context *ctx); | 33 | struct HMACMD5Context *ctx); |
34 | void hmac_md5_update(const unsigned char *text, int text_len, | 34 | void hmac_md5_update(const unsigned char *text, int text_len, |
35 | struct HMACMD5Context *ctx); | 35 | struct HMACMD5Context *ctx); |
36 | void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); | 36 | void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); |
37 | void 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 | ||
392 | int | 392 | static int |
393 | checkSMBhdr(struct smb_hdr *smb, __u16 mid) | 393 | checkSMBhdr(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 | ||
420 | int | 420 | int |
421 | checkSMB(struct smb_hdr *smb, __u16 mid, int length) | 421 | checkSMB(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 | |||
913 | static 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 | |||
922 | struct 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 | ||
109 | static 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 | |||
109 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | 120 | static 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 | ||
367 | void | 367 | #if 0 /* currently unsued */ |
368 | static void | ||
368 | D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) | 369 | D_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 | ||
374 | void | 375 | static void |
375 | E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out) | 376 | E_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 */ |
383 | void | 383 | void |
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 | ||
52 | void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); | 52 | void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); |
53 | void E_md4hash(const unsigned char *passwd, unsigned char *p16); | 53 | void E_md4hash(const unsigned char *passwd, unsigned char *p16); |
54 | void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]); | ||
55 | static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, | 54 | static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, |
56 | unsigned char p24[24]); | 55 | unsigned char p24[24]); |
57 | void NTLMSSPOWFencrypt(unsigned char passwd[8], | ||
58 | unsigned char *ntlmchalresp, unsigned char p24[24]); | ||
59 | void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); | 56 | void 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 */ |
148 | void | 146 | static void |
149 | nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) | 147 | nt_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. */ |
226 | void | 225 | #if 0 /* currently unused */ |
226 | static void | ||
227 | NTLMSSPOWFencrypt(unsigned char passwd[8], | 227 | NTLMSSPOWFencrypt(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: | |||
698 | out: | 698 | out: |
699 | page_cache_release(page); | 699 | page_cache_release(page); |
700 | unlock_page(page); | 700 | unlock_page(page); |
701 | out_nomem: | 701 | out_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 | ||
61 | extern void smp_vic_timer_interrupt(struct pt_regs *regs); | 61 | extern 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 | ||
120 | typedef struct voyager_eeprom_hdr { | 120 | typedef 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 */ |
157 | typedef struct voyager_sp_table { | 157 | typedef 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 | ||
164 | typedef struct voyager_jtag_table { | 164 | typedef 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 | ||
172 | typedef struct voyager_asic_data_table { | 172 | typedef 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 | ||
330 | typedef struct { | 330 | typedef 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 | ||
335 | struct QuadDescription { | 335 | struct 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 | ||
345 | struct ProcBoardInfo { | 345 | struct 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 | ||
352 | struct CacheDescription { | 352 | struct 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 | ||
364 | struct CPU_Description { | 364 | struct 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 | ||
371 | struct CPU_Info { | 371 | struct 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 | |||
6 | extern 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 | ||
700 | void make_intc2_irq(unsigned int irq, | 700 | struct 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 | |||
707 | void make_intc2_irq(struct intc2_data *); | ||
704 | void init_IRQ_intc2(void); | 708 | void init_IRQ_intc2(void); |
705 | void intc2_add_clear_irq(int irq, int (*fn)(int)); | ||
706 | |||
707 | #endif | 709 | #endif |
708 | 710 | ||
709 | extern int shmse_irq_demux(int irq); | 711 | extern 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 | ||
15 | struct sys_timer { | 16 | struct sys_timer { |
@@ -24,21 +25,17 @@ struct sys_timer { | |||
24 | extern struct sys_timer tmu_timer; | 25 | extern struct sys_timer tmu_timer; |
25 | extern struct sys_timer *sys_timer; | 26 | extern struct sys_timer *sys_timer; |
26 | 27 | ||
28 | #ifndef CONFIG_GENERIC_TIME | ||
27 | static inline unsigned long get_timer_offset(void) | 29 | static 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 | |
32 | static 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 */ |
38 | struct sys_timer *get_sys_timer(void); | 36 | struct sys_timer *get_sys_timer(void); |
39 | 37 | ||
40 | /* arch/sh/kernel/time.c */ | 38 | /* arch/sh/kernel/time.c */ |
41 | void handle_timer_tick(struct pt_regs *); | 39 | void 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 | ||
3123 | static 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 | |||
3128 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 3126 | static 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 | ||
3178 | static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | 3176 | static 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 | ||
3183 | static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid) | 3182 | static 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 | ||
3200 | static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk) | ||
3201 | { | ||
3202 | return 0; | ||
3203 | } | ||
3204 | |||
3205 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 3199 | static 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 | ||
3251 | static inline int security_xfrm_flow_state_match(struct flowi *fl, | 3245 | static 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 | ||
99 | struct sock; | 99 | struct sock; |
100 | typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir, | 100 | typedef 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 | ||
103 | extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir, | 103 | extern 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 */ |
108 | struct netlbl_lsm_cache { | 109 | struct 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 | */ | ||
139 | static 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 | */ | ||
157 | static 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 | */ |
155 | static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr, | 191 | static 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 | */ |
188 | static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr, | 221 | static 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); | |||
139 | void sctp_write_space(struct sock *sk); | 139 | void sctp_write_space(struct sock *sk); |
140 | unsigned int sctp_poll(struct file *file, struct socket *sock, | 140 | unsigned int sctp_poll(struct file *file, struct socket *sock, |
141 | poll_table *wait); | 141 | poll_table *wait); |
142 | void 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 | */ | ||
452 | static 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. */ |
448 | static inline int sctp_list_single_entry(struct list_head *head) | 462 | static 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 | ||
24 | static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) | 25 | static 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 | ||
32 | static 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); |
996 | extern void xfrm_policy_flush(u8 type); | 996 | extern void xfrm_policy_flush(u8 type); |
997 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 997 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
998 | extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family, int strict); | 998 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, |
999 | struct flowi *fl, int family, int strict); | ||
999 | extern void xfrm_init_pmtu(struct dst_entry *dst); | 1000 | extern void xfrm_init_pmtu(struct dst_entry *dst); |
1000 | 1001 | ||
1001 | extern wait_queue_head_t km_waitq; | 1002 | extern 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 | ||
88 | static 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 | |||
88 | static void __flow_cache_shrink(int cpu, int shrink_to) | 96 | static 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 | ||
221 | nocache: | 226 | nocache: |
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); |
606 | errout: | 606 | errout: |
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 | ||
982 | do_time_wait: | 982 | do_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 | ||
1111 | do_time_wait: | 1111 | do_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 | ||
268 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | 268 | static 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 | ||
275 | static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route **rp) | 280 | static 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 | ||
48 | struct cipso_v4_domhsh_entry { | 49 | struct 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 | */ |
194 | static void cipso_v4_cache_entry_free(struct cipso_v4_map_cache_entry *entry) | 196 | static 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 | ||
567 | static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | 567 | static 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 | ||
1155 | do_time_wait: | 1155 | do_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 | ||
156 | config 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 | |||
156 | config IPV6_TUNNEL | 169 | config 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 | ||
5 | obj-$(CONFIG_IPV6) += ipv6.o | 5 | obj-$(CONFIG_IPV6) += ipv6.o |
6 | 6 | ||
7 | ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \ | 7 | ipv6-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 | |||
29 | obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o | 29 | obj-$(CONFIG_INET6_XFRM_MODE_BEET) += xfrm6_mode_beet.o |
30 | obj-$(CONFIG_NETFILTER) += netfilter/ | 30 | obj-$(CONFIG_NETFILTER) += netfilter/ |
31 | 31 | ||
32 | obj-$(CONFIG_IPV6_SIT) += sit.o | ||
32 | obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o | 33 | obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o |
33 | 34 | ||
34 | obj-y += exthdrs_core.o | 35 | obj-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) | ||
1572 | static void sit_route_add(struct net_device *dev) | 1577 | static 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 | ||
1586 | static void addrconf_add_lroute(struct net_device *dev) | 1592 | static 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 | ||
1885 | err_exit: | 1893 | err_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) | ||
2013 | static void sit_add_v4_addrs(struct inet6_dev *idev) | 2022 | static 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 | ||
2082 | static void init_loopback(struct net_device *dev) | 2092 | static 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) | ||
2144 | static void addrconf_sit_config(struct net_device *dev) | 2155 | static 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 | ||
2170 | static inline int | 2182 | static inline int |
2171 | ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | 2183 | ipv6_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 | |||
854 | module_init(sit_init); | ||
855 | module_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 | ||
1284 | do_time_wait: | 1284 | do_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) | |||
200 | int netlbl_cache_add(const struct sk_buff *skb, | 200 | int 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 | */ | ||
5370 | void 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. */ |
5366 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | 5380 | static 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. */ |
58 | SCTP_STATIC void sctp_ulpevent_init(struct sctp_ulpevent *event, int msg_flags) | 58 | SCTP_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. */ |
109 | static inline void sctp_ulpevent_release_owner(struct sctp_ulpevent *event) | 112 | static 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 | } |
884 | EXPORT_SYMBOL(xfrm_policy_walk); | 884 | EXPORT_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 | */ | ||
888 | static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, | 891 | static 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 | ||
907 | static struct xfrm_policy *xfrm_policy_lookup_bytype(u8 type, struct flowi *fl, | 908 | static 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); |
958 | fail: | ||
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 | ||
946 | static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir, | 964 | static 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 |
959 | end: | 985 | end: |
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 | ||
965 | static inline int policy_to_flow_dir(int dir) | 992 | static 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 | ||
1707 | static int stale_bundle(struct dst_entry *dst) | 1755 | static 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 | ||
1712 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) | 1760 | void 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 | ||
1831 | int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family, int strict) | 1879 | int 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 | ||
884 | static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | 884 | static 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); | |||
19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | 19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); |
20 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, | 20 | int 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); |
22 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); | 22 | int 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 | */ |
2173 | static void selinux_netlbl_cache_free(const void *data) | 2173 | static 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; | 2228 | netlbl_cache_add_return: |
2222 | 2229 | netlbl_secattr_destroy(&secattr); | |
2223 | netlbl_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 | ||
2420 | netlbl_socket_setsid_return: | 2425 | netlbl_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, | |||
2653 | u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) | 2657 | u32 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) | |||
2672 | u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb) | 2672 | u32 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 | */ |
78 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 78 | int 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 | ||
136 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | 155 | int 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)) |