diff options
author | Steve French <sfrench@hera.kernel.org> | 2005-06-09 17:44:56 -0400 |
---|---|---|
committer | Steve French <sfrench@hera.kernel.org> | 2005-06-09 17:44:56 -0400 |
commit | f5d9b97ee0d6d00a29bf881263510d74291fb862 (patch) | |
tree | 90b22e6038da0ad40e54c3f52e8da67189730ae8 | |
parent | 3079ca621e9e09f4593c20a9a2f24237c355f683 (diff) | |
parent | cf380ee7308db0f067ceb2ae8b852838788bf453 (diff) |
Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
104 files changed, 1357 insertions, 637 deletions
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index 665bd2c20743..d3fe2533907e 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S | |||
@@ -47,3 +47,10 @@ __XScale_start: | |||
47 | orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) | 47 | orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #ifdef CONFIG_ARCH_IXP2000 | ||
51 | mov r1, #-1 | ||
52 | mov r0, #0xd6000000 | ||
53 | str r1, [r0, #0x14] | ||
54 | str r1, [r0, #0x18] | ||
55 | #endif | ||
56 | |||
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 4eb36155dc93..e14278d59882 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -269,7 +269,7 @@ __pabt_svc: | |||
269 | add r5, sp, #S_PC | 269 | add r5, sp, #S_PC |
270 | ldmia r7, {r2 - r4} @ Get USR pc, cpsr | 270 | ldmia r7, {r2 - r4} @ Get USR pc, cpsr |
271 | 271 | ||
272 | #if __LINUX_ARM_ARCH__ < 6 | 272 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) |
273 | @ make sure our user space atomic helper is aborted | 273 | @ make sure our user space atomic helper is aborted |
274 | cmp r2, #VIRT_OFFSET | 274 | cmp r2, #VIRT_OFFSET |
275 | bichs r3, r3, #PSR_Z_BIT | 275 | bichs r3, r3, #PSR_Z_BIT |
@@ -616,11 +616,17 @@ __kuser_helper_start: | |||
616 | 616 | ||
617 | __kuser_cmpxchg: @ 0xffff0fc0 | 617 | __kuser_cmpxchg: @ 0xffff0fc0 |
618 | 618 | ||
619 | #if __LINUX_ARM_ARCH__ < 6 | 619 | #if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) |
620 | 620 | ||
621 | #ifdef CONFIG_SMP /* sanity check */ | 621 | /* |
622 | #error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?" | 622 | * Poor you. No fast solution possible... |
623 | #endif | 623 | * The kernel itself must perform the operation. |
624 | * A special ghost syscall is used for that (see traps.c). | ||
625 | */ | ||
626 | swi #0x9ffff0 | ||
627 | mov pc, lr | ||
628 | |||
629 | #elif __LINUX_ARM_ARCH__ < 6 | ||
624 | 630 | ||
625 | /* | 631 | /* |
626 | * Theory of operation: | 632 | * Theory of operation: |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 14df16b983f4..45d2a032d890 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -464,6 +464,55 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
464 | #endif | 464 | #endif |
465 | return 0; | 465 | return 0; |
466 | 466 | ||
467 | #ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG | ||
468 | /* | ||
469 | * Atomically store r1 in *r2 if *r2 is equal to r0 for user space. | ||
470 | * Return zero in r0 if *MEM was changed or non-zero if no exchange | ||
471 | * happened. Also set the user C flag accordingly. | ||
472 | * If access permissions have to be fixed up then non-zero is | ||
473 | * returned and the operation has to be re-attempted. | ||
474 | * | ||
475 | * *NOTE*: This is a ghost syscall private to the kernel. Only the | ||
476 | * __kuser_cmpxchg code in entry-armv.S should be aware of its | ||
477 | * existence. Don't ever use this from user code. | ||
478 | */ | ||
479 | case 0xfff0: | ||
480 | { | ||
481 | extern void do_DataAbort(unsigned long addr, unsigned int fsr, | ||
482 | struct pt_regs *regs); | ||
483 | unsigned long val; | ||
484 | unsigned long addr = regs->ARM_r2; | ||
485 | struct mm_struct *mm = current->mm; | ||
486 | pgd_t *pgd; pmd_t *pmd; pte_t *pte; | ||
487 | |||
488 | regs->ARM_cpsr &= ~PSR_C_BIT; | ||
489 | spin_lock(&mm->page_table_lock); | ||
490 | pgd = pgd_offset(mm, addr); | ||
491 | if (!pgd_present(*pgd)) | ||
492 | goto bad_access; | ||
493 | pmd = pmd_offset(pgd, addr); | ||
494 | if (!pmd_present(*pmd)) | ||
495 | goto bad_access; | ||
496 | pte = pte_offset_map(pmd, addr); | ||
497 | if (!pte_present(*pte) || !pte_write(*pte)) | ||
498 | goto bad_access; | ||
499 | val = *(unsigned long *)addr; | ||
500 | val -= regs->ARM_r0; | ||
501 | if (val == 0) { | ||
502 | *(unsigned long *)addr = regs->ARM_r1; | ||
503 | regs->ARM_cpsr |= PSR_C_BIT; | ||
504 | } | ||
505 | spin_unlock(&mm->page_table_lock); | ||
506 | return val; | ||
507 | |||
508 | bad_access: | ||
509 | spin_unlock(&mm->page_table_lock); | ||
510 | /* simulate a read access fault */ | ||
511 | do_DataAbort(addr, 15 + (1 << 11), regs); | ||
512 | return -1; | ||
513 | } | ||
514 | #endif | ||
515 | |||
467 | default: | 516 | default: |
468 | /* Calls 9f00xx..9f07ff are defined to return -ENOSYS | 517 | /* Calls 9f00xx..9f07ff are defined to return -ENOSYS |
469 | if not implemented, rather than raising SIGILL. This | 518 | if not implemented, rather than raising SIGILL. This |
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S index 6d1d7c27806e..5e240e452af6 100644 --- a/arch/arm/lib/io-writesw-armv4.S +++ b/arch/arm/lib/io-writesw-armv4.S | |||
@@ -87,9 +87,9 @@ ENTRY(__raw_writesw) | |||
87 | subs r2, r2, #2 | 87 | subs r2, r2, #2 |
88 | orr ip, ip, r3, push_hbyte1 | 88 | orr ip, ip, r3, push_hbyte1 |
89 | strh ip, [r0] | 89 | strh ip, [r0] |
90 | bpl 2b | 90 | bpl 1b |
91 | 91 | ||
92 | 3: tst r2, #1 | 92 | tst r2, #1 |
93 | 2: movne ip, r3, lsr #8 | 93 | 3: movne ip, r3, lsr #8 |
94 | strneh ip, [r0] | 94 | strneh ip, [r0] |
95 | mov pc, lr | 95 | mov pc, lr |
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 3f952237ae3d..6823ae28ae6a 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c | |||
@@ -304,6 +304,15 @@ static void __init mainstone_map_io(void) | |||
304 | PWER = 0xC0000002; | 304 | PWER = 0xC0000002; |
305 | PRER = 0x00000002; | 305 | PRER = 0x00000002; |
306 | PFER = 0x00000002; | 306 | PFER = 0x00000002; |
307 | /* for use I SRAM as framebuffer. */ | ||
308 | PSLR |= 0xF04; | ||
309 | PCFR = 0x66; | ||
310 | /* For Keypad wakeup. */ | ||
311 | KPC &=~KPC_ASACT; | ||
312 | KPC |=KPC_AS; | ||
313 | PKWR = 0x000FD000; | ||
314 | /* Need read PKWR back after set it. */ | ||
315 | PKWR; | ||
307 | } | 316 | } |
308 | 317 | ||
309 | MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") | 318 | MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") |
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 82a4bf34c251..9799fe80df23 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
@@ -29,9 +29,6 @@ | |||
29 | */ | 29 | */ |
30 | #undef DEBUG | 30 | #undef DEBUG |
31 | 31 | ||
32 | extern void pxa_cpu_suspend(void); | ||
33 | extern void pxa_cpu_resume(void); | ||
34 | |||
35 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 32 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
36 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 33 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
37 | 34 | ||
@@ -63,6 +60,12 @@ enum { SLEEP_SAVE_START = 0, | |||
63 | SLEEP_SAVE_ICMR, | 60 | SLEEP_SAVE_ICMR, |
64 | SLEEP_SAVE_CKEN, | 61 | SLEEP_SAVE_CKEN, |
65 | 62 | ||
63 | #ifdef CONFIG_PXA27x | ||
64 | SLEEP_SAVE_MDREFR, | ||
65 | SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, | ||
66 | SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, | ||
67 | #endif | ||
68 | |||
66 | SLEEP_SAVE_CKSUM, | 69 | SLEEP_SAVE_CKSUM, |
67 | 70 | ||
68 | SLEEP_SAVE_SIZE | 71 | SLEEP_SAVE_SIZE |
@@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state) | |||
75 | unsigned long checksum = 0; | 78 | unsigned long checksum = 0; |
76 | struct timespec delta, rtc; | 79 | struct timespec delta, rtc; |
77 | int i; | 80 | int i; |
78 | 81 | extern void pxa_cpu_pm_enter(suspend_state_t state); | |
79 | if (state != PM_SUSPEND_MEM) | ||
80 | return -EINVAL; | ||
81 | 82 | ||
82 | #ifdef CONFIG_IWMMXT | 83 | #ifdef CONFIG_IWMMXT |
83 | /* force any iWMMXt context to ram **/ | 84 | /* force any iWMMXt context to ram **/ |
@@ -100,16 +101,17 @@ static int pxa_pm_enter(suspend_state_t state) | |||
100 | SAVE(GAFR2_L); SAVE(GAFR2_U); | 101 | SAVE(GAFR2_L); SAVE(GAFR2_U); |
101 | 102 | ||
102 | #ifdef CONFIG_PXA27x | 103 | #ifdef CONFIG_PXA27x |
104 | SAVE(MDREFR); | ||
103 | SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); | 105 | SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); |
104 | SAVE(GAFR3_L); SAVE(GAFR3_U); | 106 | SAVE(GAFR3_L); SAVE(GAFR3_U); |
107 | SAVE(PWER); SAVE(PCFR); SAVE(PRER); | ||
108 | SAVE(PFER); SAVE(PKWR); | ||
105 | #endif | 109 | #endif |
106 | 110 | ||
107 | SAVE(ICMR); | 111 | SAVE(ICMR); |
108 | ICMR = 0; | 112 | ICMR = 0; |
109 | 113 | ||
110 | SAVE(CKEN); | 114 | SAVE(CKEN); |
111 | CKEN = 0; | ||
112 | |||
113 | SAVE(PSTR); | 115 | SAVE(PSTR); |
114 | 116 | ||
115 | /* Note: wake up source are set up in each machine specific files */ | 117 | /* Note: wake up source are set up in each machine specific files */ |
@@ -123,16 +125,13 @@ static int pxa_pm_enter(suspend_state_t state) | |||
123 | /* Clear sleep reset status */ | 125 | /* Clear sleep reset status */ |
124 | RCSR = RCSR_SMR; | 126 | RCSR = RCSR_SMR; |
125 | 127 | ||
126 | /* set resume return address */ | ||
127 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
128 | |||
129 | /* before sleeping, calculate and save a checksum */ | 128 | /* before sleeping, calculate and save a checksum */ |
130 | for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) | 129 | for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) |
131 | checksum += sleep_save[i]; | 130 | checksum += sleep_save[i]; |
132 | sleep_save[SLEEP_SAVE_CKSUM] = checksum; | 131 | sleep_save[SLEEP_SAVE_CKSUM] = checksum; |
133 | 132 | ||
134 | /* *** go zzz *** */ | 133 | /* *** go zzz *** */ |
135 | pxa_cpu_suspend(); | 134 | pxa_cpu_pm_enter(state); |
136 | 135 | ||
137 | /* after sleeping, validate the checksum */ | 136 | /* after sleeping, validate the checksum */ |
138 | checksum = 0; | 137 | checksum = 0; |
@@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state) | |||
145 | LUB_HEXLED = 0xbadbadc5; | 144 | LUB_HEXLED = 0xbadbadc5; |
146 | #endif | 145 | #endif |
147 | while (1) | 146 | while (1) |
148 | pxa_cpu_suspend(); | 147 | pxa_cpu_pm_enter(state); |
149 | } | 148 | } |
150 | 149 | ||
151 | /* ensure not to come back here if it wasn't intended */ | 150 | /* ensure not to come back here if it wasn't intended */ |
@@ -162,8 +161,11 @@ static int pxa_pm_enter(suspend_state_t state) | |||
162 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); | 161 | RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); |
163 | 162 | ||
164 | #ifdef CONFIG_PXA27x | 163 | #ifdef CONFIG_PXA27x |
164 | RESTORE(MDREFR); | ||
165 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); | 165 | RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); |
166 | RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); | 166 | RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); |
167 | RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); | ||
168 | RESTORE(PFER); RESTORE(PKWR); | ||
167 | #endif | 169 | #endif |
168 | 170 | ||
169 | PSSR = PSSR_RDH | PSSR_PH; | 171 | PSSR = PSSR_RDH | PSSR_PH; |
@@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp) | |||
197 | */ | 199 | */ |
198 | static int pxa_pm_prepare(suspend_state_t state) | 200 | static int pxa_pm_prepare(suspend_state_t state) |
199 | { | 201 | { |
200 | return 0; | 202 | extern int pxa_cpu_pm_prepare(suspend_state_t state); |
203 | |||
204 | return pxa_cpu_pm_prepare(state); | ||
201 | } | 205 | } |
202 | 206 | ||
203 | /* | 207 | /* |
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e887b7175ef3..b6d945a6e774 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -102,3 +102,32 @@ unsigned int get_lcdclk_frequency_10khz(void) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | 104 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); |
105 | |||
106 | |||
107 | int pxa_cpu_pm_prepare(suspend_state_t state) | ||
108 | { | ||
109 | switch (state) { | ||
110 | case PM_SUSPEND_MEM: | ||
111 | break; | ||
112 | default: | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | void pxa_cpu_pm_enter(suspend_state_t state) | ||
120 | { | ||
121 | extern void pxa_cpu_suspend(unsigned int); | ||
122 | extern void pxa_cpu_resume(void); | ||
123 | |||
124 | CKEN = 0; | ||
125 | |||
126 | switch (state) { | ||
127 | case PM_SUSPEND_MEM: | ||
128 | /* set resume return address */ | ||
129 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
130 | pxa_cpu_suspend(3); | ||
131 | break; | ||
132 | } | ||
133 | } | ||
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e863afefb53..aa3c3b2ab75e 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -120,6 +120,38 @@ EXPORT_SYMBOL(get_clk_frequency_khz); | |||
120 | EXPORT_SYMBOL(get_memclk_frequency_10khz); | 120 | EXPORT_SYMBOL(get_memclk_frequency_10khz); |
121 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); | 121 | EXPORT_SYMBOL(get_lcdclk_frequency_10khz); |
122 | 122 | ||
123 | int pxa_cpu_pm_prepare(suspend_state_t state) | ||
124 | { | ||
125 | switch (state) { | ||
126 | case PM_SUSPEND_MEM: | ||
127 | return 0; | ||
128 | default: | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | void pxa_cpu_pm_enter(suspend_state_t state) | ||
134 | { | ||
135 | extern void pxa_cpu_standby(void); | ||
136 | extern void pxa_cpu_suspend(unsigned int); | ||
137 | extern void pxa_cpu_resume(void); | ||
138 | |||
139 | CKEN = CKEN22_MEMC | CKEN9_OSTIMER; | ||
140 | |||
141 | /* ensure voltage-change sequencer not initiated, which hangs */ | ||
142 | PCFR &= ~PCFR_FVC; | ||
143 | |||
144 | /* Clear edge-detect status register. */ | ||
145 | PEDR = 0xDF12FE1B; | ||
146 | |||
147 | switch (state) { | ||
148 | case PM_SUSPEND_MEM: | ||
149 | /* set resume return address */ | ||
150 | PSPR = virt_to_phys(pxa_cpu_resume); | ||
151 | pxa_cpu_suspend(3); | ||
152 | break; | ||
153 | } | ||
154 | } | ||
123 | 155 | ||
124 | /* | 156 | /* |
125 | * device registration specific to PXA27x. | 157 | * device registration specific to PXA27x. |
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index bc229fab86d4..c7c28890d406 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c | |||
@@ -785,6 +785,10 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) | |||
785 | chan->client = NULL; | 785 | chan->client = NULL; |
786 | chan->in_use = 0; | 786 | chan->in_use = 0; |
787 | 787 | ||
788 | if (chan->irq_claimed) | ||
789 | free_irq(chan->irq, (void *)chan); | ||
790 | chan->irq_claimed = 0; | ||
791 | |||
788 | local_irq_restore(flags); | 792 | local_irq_restore(flags); |
789 | 793 | ||
790 | return 0; | 794 | return 0; |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 48bac7da8c70..3fefb43c67f7 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -228,7 +228,6 @@ config CPU_SA1100 | |||
228 | select CPU_CACHE_V4WB | 228 | select CPU_CACHE_V4WB |
229 | select CPU_CACHE_VIVT | 229 | select CPU_CACHE_VIVT |
230 | select CPU_TLB_V4WB | 230 | select CPU_TLB_V4WB |
231 | select CPU_MINICACHE | ||
232 | 231 | ||
233 | # XScale | 232 | # XScale |
234 | config CPU_XSCALE | 233 | config CPU_XSCALE |
@@ -239,7 +238,6 @@ config CPU_XSCALE | |||
239 | select CPU_ABRT_EV5T | 238 | select CPU_ABRT_EV5T |
240 | select CPU_CACHE_VIVT | 239 | select CPU_CACHE_VIVT |
241 | select CPU_TLB_V4WBI | 240 | select CPU_TLB_V4WBI |
242 | select CPU_MINICACHE | ||
243 | 241 | ||
244 | # ARMv6 | 242 | # ARMv6 |
245 | config CPU_V6 | 243 | config CPU_V6 |
@@ -345,11 +343,6 @@ config CPU_TLB_V4WBI | |||
345 | config CPU_TLB_V6 | 343 | config CPU_TLB_V6 |
346 | bool | 344 | bool |
347 | 345 | ||
348 | config CPU_MINICACHE | ||
349 | bool | ||
350 | help | ||
351 | Processor has a minicache. | ||
352 | |||
353 | comment "Processor Features" | 346 | comment "Processor Features" |
354 | 347 | ||
355 | config ARM_THUMB | 348 | config ARM_THUMB |
@@ -429,3 +422,11 @@ config HAS_TLS_REG | |||
429 | assume directly accessing that register and always obtain the | 422 | assume directly accessing that register and always obtain the |
430 | expected value only on ARMv7 and above. | 423 | expected value only on ARMv7 and above. |
431 | 424 | ||
425 | config NEEDS_SYSCALL_FOR_CMPXCHG | ||
426 | bool | ||
427 | default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) | ||
428 | help | ||
429 | SMP on a pre-ARMv6 processor? Well OK then. | ||
430 | Forget about fast user space cmpxchg support. | ||
431 | It is just not possible. | ||
432 | |||
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index ccf316c11e02..59f47d4c2dfe 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
@@ -31,8 +31,6 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o | |||
31 | obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o | 31 | obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o |
32 | obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o | 32 | obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o |
33 | 33 | ||
34 | obj-$(CONFIG_CPU_MINICACHE) += minicache.o | ||
35 | |||
36 | obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o | 34 | obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o |
37 | obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o | 35 | obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o |
38 | obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o | 36 | obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o |
diff --git a/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S deleted file mode 100644 index bb277316ef52..000000000000 --- a/arch/arm/mm/copypage-xscale.S +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copypage-xscale.S | ||
3 | * | ||
4 | * Copyright (C) 2001 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <asm/constants.h> | ||
13 | |||
14 | /* | ||
15 | * General note: | ||
16 | * We don't really want write-allocate cache behaviour for these functions | ||
17 | * since that will just eat through 8K of the cache. | ||
18 | */ | ||
19 | |||
20 | .text | ||
21 | .align 5 | ||
22 | /* | ||
23 | * XScale optimised copy_user_page | ||
24 | * r0 = destination | ||
25 | * r1 = source | ||
26 | * r2 = virtual user address of ultimate destination page | ||
27 | * | ||
28 | * The source page may have some clean entries in the cache already, but we | ||
29 | * can safely ignore them - break_cow() will flush them out of the cache | ||
30 | * if we eventually end up using our copied page. | ||
31 | * | ||
32 | * What we could do is use the mini-cache to buffer reads from the source | ||
33 | * page. We rely on the mini-cache being smaller than one page, so we'll | ||
34 | * cycle through the complete cache anyway. | ||
35 | */ | ||
36 | ENTRY(xscale_mc_copy_user_page) | ||
37 | stmfd sp!, {r4, r5, lr} | ||
38 | mov r5, r0 | ||
39 | mov r0, r1 | ||
40 | bl map_page_minicache | ||
41 | mov r1, r5 | ||
42 | mov lr, #PAGE_SZ/64-1 | ||
43 | |||
44 | /* | ||
45 | * Strangely enough, best performance is achieved | ||
46 | * when prefetching destination as well. (NP) | ||
47 | */ | ||
48 | pld [r0, #0] | ||
49 | pld [r0, #32] | ||
50 | pld [r1, #0] | ||
51 | pld [r1, #32] | ||
52 | |||
53 | 1: pld [r0, #64] | ||
54 | pld [r0, #96] | ||
55 | pld [r1, #64] | ||
56 | pld [r1, #96] | ||
57 | |||
58 | 2: ldrd r2, [r0], #8 | ||
59 | ldrd r4, [r0], #8 | ||
60 | mov ip, r1 | ||
61 | strd r2, [r1], #8 | ||
62 | ldrd r2, [r0], #8 | ||
63 | strd r4, [r1], #8 | ||
64 | ldrd r4, [r0], #8 | ||
65 | strd r2, [r1], #8 | ||
66 | strd r4, [r1], #8 | ||
67 | mcr p15, 0, ip, c7, c10, 1 @ clean D line | ||
68 | ldrd r2, [r0], #8 | ||
69 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line | ||
70 | ldrd r4, [r0], #8 | ||
71 | mov ip, r1 | ||
72 | strd r2, [r1], #8 | ||
73 | ldrd r2, [r0], #8 | ||
74 | strd r4, [r1], #8 | ||
75 | ldrd r4, [r0], #8 | ||
76 | strd r2, [r1], #8 | ||
77 | strd r4, [r1], #8 | ||
78 | mcr p15, 0, ip, c7, c10, 1 @ clean D line | ||
79 | subs lr, lr, #1 | ||
80 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line | ||
81 | bgt 1b | ||
82 | beq 2b | ||
83 | |||
84 | ldmfd sp!, {r4, r5, pc} | ||
85 | |||
86 | .align 5 | ||
87 | /* | ||
88 | * XScale optimised clear_user_page | ||
89 | * r0 = destination | ||
90 | * r1 = virtual user address of ultimate destination page | ||
91 | */ | ||
92 | ENTRY(xscale_mc_clear_user_page) | ||
93 | mov r1, #PAGE_SZ/32 | ||
94 | mov r2, #0 | ||
95 | mov r3, #0 | ||
96 | 1: mov ip, r0 | ||
97 | strd r2, [r0], #8 | ||
98 | strd r2, [r0], #8 | ||
99 | strd r2, [r0], #8 | ||
100 | strd r2, [r0], #8 | ||
101 | mcr p15, 0, ip, c7, c10, 1 @ clean D line | ||
102 | subs r1, r1, #1 | ||
103 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line | ||
104 | bne 1b | ||
105 | mov pc, lr | ||
106 | |||
107 | __INITDATA | ||
108 | |||
109 | .type xscale_mc_user_fns, #object | ||
110 | ENTRY(xscale_mc_user_fns) | ||
111 | .long xscale_mc_clear_user_page | ||
112 | .long xscale_mc_copy_user_page | ||
113 | .size xscale_mc_user_fns, . - xscale_mc_user_fns | ||
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c new file mode 100644 index 000000000000..42a6ee255ce0 --- /dev/null +++ b/arch/arm/mm/copypage-xscale.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copypage-xscale.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2005 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This handles the mini data cache, as found on SA11x0 and XScale | ||
11 | * processors. When we copy a user page page, we map it in such a way | ||
12 | * that accesses to this page will not touch the main data cache, but | ||
13 | * will be cached in the mini data cache. This prevents us thrashing | ||
14 | * the main data cache on page faults. | ||
15 | */ | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/pgtable.h> | ||
21 | #include <asm/tlbflush.h> | ||
22 | |||
23 | /* | ||
24 | * 0xffff8000 to 0xffffffff is reserved for any ARM architecture | ||
25 | * specific hacks for copying pages efficiently. | ||
26 | */ | ||
27 | #define COPYPAGE_MINICACHE 0xffff8000 | ||
28 | |||
29 | #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ | ||
30 | L_PTE_CACHEABLE) | ||
31 | |||
32 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) | ||
33 | |||
34 | static DEFINE_SPINLOCK(minicache_lock); | ||
35 | |||
36 | /* | ||
37 | * XScale mini-dcache optimised copy_user_page | ||
38 | * | ||
39 | * We flush the destination cache lines just before we write the data into the | ||
40 | * corresponding address. Since the Dcache is read-allocate, this removes the | ||
41 | * Dcache aliasing issue. The writes will be forwarded to the write buffer, | ||
42 | * and merged as appropriate. | ||
43 | */ | ||
44 | static void __attribute__((naked)) | ||
45 | mc_copy_user_page(void *from, void *to) | ||
46 | { | ||
47 | /* | ||
48 | * Strangely enough, best performance is achieved | ||
49 | * when prefetching destination as well. (NP) | ||
50 | */ | ||
51 | asm volatile( | ||
52 | "stmfd sp!, {r4, r5, lr} \n\ | ||
53 | mov lr, %2 \n\ | ||
54 | pld [r0, #0] \n\ | ||
55 | pld [r0, #32] \n\ | ||
56 | pld [r1, #0] \n\ | ||
57 | pld [r1, #32] \n\ | ||
58 | 1: pld [r0, #64] \n\ | ||
59 | pld [r0, #96] \n\ | ||
60 | pld [r1, #64] \n\ | ||
61 | pld [r1, #96] \n\ | ||
62 | 2: ldrd r2, [r0], #8 \n\ | ||
63 | ldrd r4, [r0], #8 \n\ | ||
64 | mov ip, r1 \n\ | ||
65 | strd r2, [r1], #8 \n\ | ||
66 | ldrd r2, [r0], #8 \n\ | ||
67 | strd r4, [r1], #8 \n\ | ||
68 | ldrd r4, [r0], #8 \n\ | ||
69 | strd r2, [r1], #8 \n\ | ||
70 | strd r4, [r1], #8 \n\ | ||
71 | mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ | ||
72 | ldrd r2, [r0], #8 \n\ | ||
73 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ | ||
74 | ldrd r4, [r0], #8 \n\ | ||
75 | mov ip, r1 \n\ | ||
76 | strd r2, [r1], #8 \n\ | ||
77 | ldrd r2, [r0], #8 \n\ | ||
78 | strd r4, [r1], #8 \n\ | ||
79 | ldrd r4, [r0], #8 \n\ | ||
80 | strd r2, [r1], #8 \n\ | ||
81 | strd r4, [r1], #8 \n\ | ||
82 | mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ | ||
83 | subs lr, lr, #1 \n\ | ||
84 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ | ||
85 | bgt 1b \n\ | ||
86 | beq 2b \n\ | ||
87 | ldmfd sp!, {r4, r5, pc} " | ||
88 | : | ||
89 | : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1)); | ||
90 | } | ||
91 | |||
92 | void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) | ||
93 | { | ||
94 | spin_lock(&minicache_lock); | ||
95 | |||
96 | set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot)); | ||
97 | flush_tlb_kernel_page(COPYPAGE_MINICACHE); | ||
98 | |||
99 | mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); | ||
100 | |||
101 | spin_unlock(&minicache_lock); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * XScale optimised clear_user_page | ||
106 | */ | ||
107 | void __attribute__((naked)) | ||
108 | xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr) | ||
109 | { | ||
110 | asm volatile( | ||
111 | "mov r1, %0 \n\ | ||
112 | mov r2, #0 \n\ | ||
113 | mov r3, #0 \n\ | ||
114 | 1: mov ip, r0 \n\ | ||
115 | strd r2, [r0], #8 \n\ | ||
116 | strd r2, [r0], #8 \n\ | ||
117 | strd r2, [r0], #8 \n\ | ||
118 | strd r2, [r0], #8 \n\ | ||
119 | mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ | ||
120 | subs r1, r1, #1 \n\ | ||
121 | mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ | ||
122 | bne 1b \n\ | ||
123 | mov pc, lr" | ||
124 | : | ||
125 | : "I" (PAGE_SIZE / 32)); | ||
126 | } | ||
127 | |||
128 | struct cpu_user_fns xscale_mc_user_fns __initdata = { | ||
129 | .cpu_clear_user_page = xscale_mc_clear_user_page, | ||
130 | .cpu_copy_user_page = xscale_mc_copy_user_page, | ||
131 | }; | ||
diff --git a/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c deleted file mode 100644 index dedf2ab01b2a..000000000000 --- a/arch/arm/mm/minicache.c +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mm/minicache.c | ||
3 | * | ||
4 | * Copyright (C) 2001 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This handles the mini data cache, as found on SA11x0 and XScale | ||
11 | * processors. When we copy a user page page, we map it in such a way | ||
12 | * that accesses to this page will not touch the main data cache, but | ||
13 | * will be cached in the mini data cache. This prevents us thrashing | ||
14 | * the main data cache on page faults. | ||
15 | */ | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/pgtable.h> | ||
21 | #include <asm/tlbflush.h> | ||
22 | |||
23 | /* | ||
24 | * 0xffff8000 to 0xffffffff is reserved for any ARM architecture | ||
25 | * specific hacks for copying pages efficiently. | ||
26 | */ | ||
27 | #define minicache_address (0xffff8000) | ||
28 | #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ | ||
29 | L_PTE_CACHEABLE) | ||
30 | |||
31 | static pte_t *minicache_pte; | ||
32 | |||
33 | /* | ||
34 | * Note that this is intended to be called only from the copy_user_page | ||
35 | * asm code; anything else will require special locking to prevent the | ||
36 | * mini-cache space being re-used. (Note: probably preempt unsafe). | ||
37 | * | ||
38 | * We rely on the fact that the minicache is 2K, and we'll be pushing | ||
39 | * 4K of data through it, so we don't actually have to specifically | ||
40 | * flush the minicache when we change the mapping. | ||
41 | * | ||
42 | * Note also: assert(PAGE_OFFSET <= virt < high_memory). | ||
43 | * Unsafe: preempt, kmap. | ||
44 | */ | ||
45 | unsigned long map_page_minicache(unsigned long virt) | ||
46 | { | ||
47 | set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot)); | ||
48 | flush_tlb_kernel_page(minicache_address); | ||
49 | |||
50 | return minicache_address; | ||
51 | } | ||
52 | |||
53 | static int __init minicache_init(void) | ||
54 | { | ||
55 | pgd_t *pgd; | ||
56 | pmd_t *pmd; | ||
57 | |||
58 | spin_lock(&init_mm.page_table_lock); | ||
59 | |||
60 | pgd = pgd_offset_k(minicache_address); | ||
61 | pmd = pmd_alloc(&init_mm, pgd, minicache_address); | ||
62 | if (!pmd) | ||
63 | BUG(); | ||
64 | minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address); | ||
65 | if (!minicache_pte) | ||
66 | BUG(); | ||
67 | |||
68 | spin_unlock(&init_mm.page_table_lock); | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | core_initcall(minicache_init); | ||
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 0fbcfe00dd8d..51ecd512603d 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile | |||
@@ -43,7 +43,7 @@ obj-$(CONFIG_SCx200) += scx200.o | |||
43 | # Note: kbuild does not track this dependency due to usage of .incbin | 43 | # Note: kbuild does not track this dependency due to usage of .incbin |
44 | $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so | 44 | $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so |
45 | targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) | 45 | targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) |
46 | targets += vsyscall.lds | 46 | targets += vsyscall-note.o vsyscall.lds |
47 | 47 | ||
48 | # The DSO images are built using a special linker script. | 48 | # The DSO images are built using a special linker script. |
49 | quiet_cmd_syscall = SYSCALL $@ | 49 | quiet_cmd_syscall = SYSCALL $@ |
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index febc091c2f02..f1aca7cffd12 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c | |||
@@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind | |||
825 | * XXX Should have an arch-hook for running this after final section | 825 | * XXX Should have an arch-hook for running this after final section |
826 | * addresses have been selected... | 826 | * addresses have been selected... |
827 | */ | 827 | */ |
828 | /* See if gp can cover the entire core module: */ | 828 | uint64_t gp; |
829 | uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2; | 829 | if (mod->core_size > MAX_LTOFF) |
830 | if (mod->core_size >= MAX_LTOFF) | ||
831 | /* | 830 | /* |
832 | * This takes advantage of fact that SHF_ARCH_SMALL gets allocated | 831 | * This takes advantage of fact that SHF_ARCH_SMALL gets allocated |
833 | * at the end of the module. | 832 | * at the end of the module. |
834 | */ | 833 | */ |
835 | gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2; | 834 | gp = mod->core_size - MAX_LTOFF / 2; |
835 | else | ||
836 | gp = mod->core_size / 2; | ||
837 | gp = (uint64_t) mod->module_core + ((gp + 7) & -8); | ||
836 | mod->arch.gp = gp; | 838 | mod->arch.gp = gp; |
837 | DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); | 839 | DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); |
838 | } | 840 | } |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 08c8a5eb25ab..575a8f657b31 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task) | |||
635 | { | 635 | { |
636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); | 636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); |
637 | 637 | ||
638 | /* | ||
639 | * Prevent migrating this task while | ||
640 | * we're fiddling with the FPU state | ||
641 | */ | ||
642 | preempt_disable(); | ||
638 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { | 643 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { |
639 | psr->mfh = 0; | 644 | psr->mfh = 0; |
640 | task->thread.flags |= IA64_THREAD_FPH_VALID; | 645 | task->thread.flags |= IA64_THREAD_FPH_VALID; |
641 | ia64_save_fpu(&task->thread.fph[0]); | 646 | ia64_save_fpu(&task->thread.fph[0]); |
642 | } | 647 | } |
648 | preempt_enable(); | ||
643 | } | 649 | } |
644 | 650 | ||
645 | /* | 651 | /* |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index b7e6b4cb374b..d14692e0920a 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
@@ -720,7 +720,8 @@ cpu_init (void) | |||
720 | ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); | 720 | ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); |
721 | 721 | ||
722 | /* | 722 | /* |
723 | * Initialize default control register to defer all speculative faults. The | 723 | * Initialize default control register to defer speculative faults except |
724 | * for those arising from TLB misses, which are not deferred. The | ||
724 | * kernel MUST NOT depend on a particular setting of these bits (in other words, | 725 | * kernel MUST NOT depend on a particular setting of these bits (in other words, |
725 | * the kernel must have recovery code for all speculative accesses). Turn on | 726 | * the kernel must have recovery code for all speculative accesses). Turn on |
726 | * dcr.lc as per recommendation by the architecture team. Most IA-32 apps | 727 | * dcr.lc as per recommendation by the architecture team. Most IA-32 apps |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index e82ad78081b3..1861173bd4f6 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
111 | siginfo_t siginfo; | 111 | siginfo_t siginfo; |
112 | int sig, code; | 112 | int sig, code; |
113 | 113 | ||
114 | /* break.b always sets cr.iim to 0, which causes problems for | ||
115 | * debuggers. Get the real break number from the original instruction, | ||
116 | * but only for kernel code. User space break.b is left alone, to | ||
117 | * preserve the existing behaviour. All break codings have the same | ||
118 | * format, so there is no need to check the slot type. | ||
119 | */ | ||
120 | if (break_num == 0 && !user_mode(regs)) { | ||
121 | struct ia64_psr *ipsr = ia64_psr(regs); | ||
122 | unsigned long *bundle = (unsigned long *)regs->cr_iip; | ||
123 | unsigned long slot; | ||
124 | switch (ipsr->ri) { | ||
125 | case 0: slot = (bundle[0] >> 5); break; | ||
126 | case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break; | ||
127 | default: slot = (bundle[1] >> 23); break; | ||
128 | } | ||
129 | break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff); | ||
130 | } | ||
131 | |||
114 | /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ | 132 | /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ |
115 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); | 133 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); |
116 | siginfo.si_imm = break_num; | 134 | siginfo.si_imm = break_num; |
@@ -202,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs) | |||
202 | 220 | ||
203 | /* first, grant user-level access to fph partition: */ | 221 | /* first, grant user-level access to fph partition: */ |
204 | psr->dfh = 0; | 222 | psr->dfh = 0; |
223 | |||
224 | /* | ||
225 | * Make sure that no other task gets in on this processor | ||
226 | * while we're claiming the FPU | ||
227 | */ | ||
228 | preempt_disable(); | ||
205 | #ifndef CONFIG_SMP | 229 | #ifndef CONFIG_SMP |
206 | { | 230 | { |
207 | struct task_struct *fpu_owner | 231 | struct task_struct *fpu_owner |
208 | = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); | 232 | = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); |
209 | 233 | ||
210 | if (ia64_is_local_fpu_owner(current)) | 234 | if (ia64_is_local_fpu_owner(current)) { |
235 | preempt_enable_no_resched(); | ||
211 | return; | 236 | return; |
237 | } | ||
212 | 238 | ||
213 | if (fpu_owner) | 239 | if (fpu_owner) |
214 | ia64_flush_fph(fpu_owner); | 240 | ia64_flush_fph(fpu_owner); |
@@ -226,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs) | |||
226 | */ | 252 | */ |
227 | psr->mfh = 1; | 253 | psr->mfh = 1; |
228 | } | 254 | } |
255 | preempt_enable_no_resched(); | ||
229 | } | 256 | } |
230 | 257 | ||
231 | static inline int | 258 | static inline int |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 547785e3cba2..4eb2f52b87a1 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -305,8 +305,9 @@ setup_gate (void) | |||
305 | struct page *page; | 305 | struct page *page; |
306 | 306 | ||
307 | /* | 307 | /* |
308 | * Map the gate page twice: once read-only to export the ELF headers etc. and once | 308 | * Map the gate page twice: once read-only to export the ELF |
309 | * execute-only page to enable privilege-promotion via "epc": | 309 | * headers etc. and once execute-only page to enable |
310 | * privilege-promotion via "epc": | ||
310 | */ | 311 | */ |
311 | page = virt_to_page(ia64_imva(__start_gate_section)); | 312 | page = virt_to_page(ia64_imva(__start_gate_section)); |
312 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); | 313 | put_kernel_page(page, GATE_ADDR, PAGE_READONLY); |
@@ -315,6 +316,20 @@ setup_gate (void) | |||
315 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); | 316 | put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); |
316 | #else | 317 | #else |
317 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); | 318 | put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); |
319 | /* Fill in the holes (if any) with read-only zero pages: */ | ||
320 | { | ||
321 | unsigned long addr; | ||
322 | |||
323 | for (addr = GATE_ADDR + PAGE_SIZE; | ||
324 | addr < GATE_ADDR + PERCPU_PAGE_SIZE; | ||
325 | addr += PAGE_SIZE) | ||
326 | { | ||
327 | put_kernel_page(ZERO_PAGE(0), addr, | ||
328 | PAGE_READONLY); | ||
329 | put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE, | ||
330 | PAGE_READONLY); | ||
331 | } | ||
332 | } | ||
318 | #endif | 333 | #endif |
319 | ia64_patch_gate(); | 334 | ia64_patch_gate(); |
320 | } | 335 | } |
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index e64cb8175f7a..44bfc7f318cb 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
@@ -222,7 +222,7 @@ void __init early_sn_setup(void) | |||
222 | 222 | ||
223 | extern int platform_intr_list[]; | 223 | extern int platform_intr_list[]; |
224 | extern nasid_t master_nasid; | 224 | extern nasid_t master_nasid; |
225 | static int shub_1_1_found __initdata; | 225 | static int __initdata shub_1_1_found = 0; |
226 | 226 | ||
227 | /* | 227 | /* |
228 | * sn_check_for_wars | 228 | * sn_check_for_wars |
@@ -251,7 +251,7 @@ static void __init sn_check_for_wars(void) | |||
251 | } else { | 251 | } else { |
252 | for_each_online_node(cnode) { | 252 | for_each_online_node(cnode) { |
253 | if (is_shub_1_1(cnodeid_to_nasid(cnode))) | 253 | if (is_shub_1_1(cnodeid_to_nasid(cnode))) |
254 | sn_hub_info->shub_1_1_found = 1; | 254 | shub_1_1_found = 1; |
255 | } | 255 | } |
256 | } | 256 | } |
257 | } | 257 | } |
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 8aa5e8c69009..17abf6cd0d90 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c | |||
@@ -838,6 +838,28 @@ struct cpu_spec cpu_specs[] = { | |||
838 | .icache_bsize = 32, | 838 | .icache_bsize = 32, |
839 | .dcache_bsize = 32, | 839 | .dcache_bsize = 32, |
840 | }, | 840 | }, |
841 | { /* 405EP */ | ||
842 | .pvr_mask = 0xffff0000, | ||
843 | .pvr_value = 0x51210000, | ||
844 | .cpu_name = "405EP", | ||
845 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | | ||
846 | CPU_FTR_USE_TB, | ||
847 | .cpu_user_features = PPC_FEATURE_32 | | ||
848 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
849 | .icache_bsize = 32, | ||
850 | .dcache_bsize = 32, | ||
851 | }, | ||
852 | { /* 405EP */ | ||
853 | .pvr_mask = 0xffff0000, | ||
854 | .pvr_value = 0x51210000, | ||
855 | .cpu_name = "405EP", | ||
856 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | | ||
857 | CPU_FTR_USE_TB, | ||
858 | .cpu_user_features = PPC_FEATURE_32 | | ||
859 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | ||
860 | .icache_bsize = 32, | ||
861 | .dcache_bsize = 32, | ||
862 | }, | ||
841 | 863 | ||
842 | #endif /* CONFIG_40x */ | 864 | #endif /* CONFIG_40x */ |
843 | #ifdef CONFIG_44x | 865 | #ifdef CONFIG_44x |
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index e4f1615ec13f..7329ef177a18 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache) | |||
619 | _GLOBAL(flush_icache_range) | 619 | _GLOBAL(flush_icache_range) |
620 | BEGIN_FTR_SECTION | 620 | BEGIN_FTR_SECTION |
621 | blr /* for 601, do nothing */ | 621 | blr /* for 601, do nothing */ |
622 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 622 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
623 | li r5,L1_CACHE_LINE_SIZE-1 | 623 | li r5,L1_CACHE_LINE_SIZE-1 |
624 | andc r3,r3,r5 | 624 | andc r3,r3,r5 |
625 | subf r4,r3,r4 | 625 | subf r4,r3,r4 |
@@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all) | |||
736 | _GLOBAL(__flush_dcache_icache) | 736 | _GLOBAL(__flush_dcache_icache) |
737 | BEGIN_FTR_SECTION | 737 | BEGIN_FTR_SECTION |
738 | blr /* for 601, do nothing */ | 738 | blr /* for 601, do nothing */ |
739 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 739 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
740 | rlwinm r3,r3,0,0,19 /* Get page base address */ | 740 | rlwinm r3,r3,0,0,19 /* Get page base address */ |
741 | li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ | 741 | li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ |
742 | mtctr r4 | 742 | mtctr r4 |
@@ -764,7 +764,7 @@ END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | |||
764 | _GLOBAL(__flush_dcache_icache_phys) | 764 | _GLOBAL(__flush_dcache_icache_phys) |
765 | BEGIN_FTR_SECTION | 765 | BEGIN_FTR_SECTION |
766 | blr /* for 601, do nothing */ | 766 | blr /* for 601, do nothing */ |
767 | END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) | 767 | END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) |
768 | mfmsr r10 | 768 | mfmsr r10 |
769 | rlwinm r0,r10,0,28,26 /* clear DR */ | 769 | rlwinm r0,r10,0,28,26 /* clear DR */ |
770 | mtmsr r0 | 770 | mtmsr r0 |
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index 7b607d1862cb..d5218b15824e 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c | |||
@@ -11,6 +11,23 @@ | |||
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/ctype.h> | 12 | #include <linux/ctype.h> |
13 | 13 | ||
14 | extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor); | ||
15 | |||
16 | /* The unnecessary pointer compare is there | ||
17 | * to check for type safety (n must be 64bit) | ||
18 | */ | ||
19 | # define do_div(n,base) ({ \ | ||
20 | __u32 __base = (base); \ | ||
21 | __u32 __rem; \ | ||
22 | (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ | ||
23 | if (((n) >> 32) == 0) { \ | ||
24 | __rem = (__u32)(n) % __base; \ | ||
25 | (n) = (__u32)(n) / __base; \ | ||
26 | } else \ | ||
27 | __rem = __div64_32(&(n), __base); \ | ||
28 | __rem; \ | ||
29 | }) | ||
30 | |||
14 | int (*prom)(void *); | 31 | int (*prom)(void *); |
15 | 32 | ||
16 | void *chosen_handle; | 33 | void *chosen_handle; |
@@ -352,7 +369,7 @@ static int skip_atoi(const char **s) | |||
352 | #define SPECIAL 32 /* 0x */ | 369 | #define SPECIAL 32 /* 0x */ |
353 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | 370 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ |
354 | 371 | ||
355 | static char * number(char * str, long num, int base, int size, int precision, int type) | 372 | static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) |
356 | { | 373 | { |
357 | char c,sign,tmp[66]; | 374 | char c,sign,tmp[66]; |
358 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | 375 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; |
@@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in | |||
367 | c = (type & ZEROPAD) ? '0' : ' '; | 384 | c = (type & ZEROPAD) ? '0' : ' '; |
368 | sign = 0; | 385 | sign = 0; |
369 | if (type & SIGN) { | 386 | if (type & SIGN) { |
370 | if (num < 0) { | 387 | if ((signed long long)num < 0) { |
371 | sign = '-'; | 388 | sign = '-'; |
372 | num = -num; | 389 | num = - (signed long long)num; |
373 | size--; | 390 | size--; |
374 | } else if (type & PLUS) { | 391 | } else if (type & PLUS) { |
375 | sign = '+'; | 392 | sign = '+'; |
@@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in | |||
389 | if (num == 0) | 406 | if (num == 0) |
390 | tmp[i++]='0'; | 407 | tmp[i++]='0'; |
391 | else while (num != 0) { | 408 | else while (num != 0) { |
392 | tmp[i++] = digits[num % base]; | 409 | tmp[i++] = digits[do_div(num, base)]; |
393 | num /= base; | ||
394 | } | 410 | } |
395 | if (i > precision) | 411 | if (i > precision) |
396 | precision = i; | 412 | precision = i; |
@@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...); | |||
426 | int vsprintf(char *buf, const char *fmt, va_list args) | 442 | int vsprintf(char *buf, const char *fmt, va_list args) |
427 | { | 443 | { |
428 | int len; | 444 | int len; |
429 | unsigned long num; | 445 | unsigned long long num; |
430 | int i, base; | 446 | int i, base; |
431 | char * str; | 447 | char * str; |
432 | const char *s; | 448 | const char *s; |
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 103daaf73573..e950a2058a19 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c | |||
@@ -45,12 +45,17 @@ static struct pt_regs jprobe_saved_regs; | |||
45 | 45 | ||
46 | int arch_prepare_kprobe(struct kprobe *p) | 46 | int arch_prepare_kprobe(struct kprobe *p) |
47 | { | 47 | { |
48 | int ret = 0; | ||
48 | kprobe_opcode_t insn = *p->addr; | 49 | kprobe_opcode_t insn = *p->addr; |
49 | 50 | ||
50 | if (IS_MTMSRD(insn) || IS_RFID(insn)) | 51 | if ((unsigned long)p->addr & 0x03) { |
51 | /* cannot put bp on RFID/MTMSRD */ | 52 | printk("Attempt to register kprobe at an unaligned address\n"); |
52 | return 1; | 53 | ret = -EINVAL; |
53 | return 0; | 54 | } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { |
55 | printk("Cannot register a kprobe on rfid or mtmsrd\n"); | ||
56 | ret = -EINVAL; | ||
57 | } | ||
58 | return ret; | ||
54 | } | 59 | } |
55 | 60 | ||
56 | void arch_copy_kprobe(struct kprobe *p) | 61 | void arch_copy_kprobe(struct kprobe *p) |
@@ -172,8 +177,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
172 | ret = emulate_step(regs, p->ainsn.insn[0]); | 177 | ret = emulate_step(regs, p->ainsn.insn[0]); |
173 | if (ret == 0) | 178 | if (ret == 0) |
174 | regs->nip = (unsigned long)p->addr + 4; | 179 | regs->nip = (unsigned long)p->addr + 4; |
175 | |||
176 | regs->msr &= ~MSR_SE; | ||
177 | } | 180 | } |
178 | 181 | ||
179 | static inline int post_kprobe_handler(struct pt_regs *regs) | 182 | static inline int post_kprobe_handler(struct pt_regs *regs) |
@@ -210,6 +213,7 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | |||
210 | 213 | ||
211 | if (kprobe_status & KPROBE_HIT_SS) { | 214 | if (kprobe_status & KPROBE_HIT_SS) { |
212 | resume_execution(current_kprobe, regs); | 215 | resume_execution(current_kprobe, regs); |
216 | regs->msr &= ~MSR_SE; | ||
213 | regs->msr |= kprobe_saved_msr; | 217 | regs->msr |= kprobe_saved_msr; |
214 | 218 | ||
215 | unlock_kprobes(); | 219 | unlock_kprobes(); |
@@ -233,8 +237,6 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, | |||
233 | */ | 237 | */ |
234 | preempt_disable(); | 238 | preempt_disable(); |
235 | switch (val) { | 239 | switch (val) { |
236 | case DIE_IABR_MATCH: | ||
237 | case DIE_DABR_MATCH: | ||
238 | case DIE_BPT: | 240 | case DIE_BPT: |
239 | if (kprobe_handler(args->regs)) | 241 | if (kprobe_handler(args->regs)) |
240 | ret = NOTIFY_STOP; | 242 | ret = NOTIFY_STOP; |
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index b944717c1dbd..e3c73b3425dc 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -792,7 +792,7 @@ _GLOBAL(sys_call_table32) | |||
792 | .llong .compat_sys_newstat | 792 | .llong .compat_sys_newstat |
793 | .llong .compat_sys_newlstat | 793 | .llong .compat_sys_newlstat |
794 | .llong .compat_sys_newfstat | 794 | .llong .compat_sys_newfstat |
795 | .llong .sys_uname | 795 | .llong .sys32_uname |
796 | .llong .sys_ni_syscall /* 110 old iopl syscall */ | 796 | .llong .sys_ni_syscall /* 110 old iopl syscall */ |
797 | .llong .sys_vhangup | 797 | .llong .sys_vhangup |
798 | .llong .sys_ni_syscall /* old idle syscall */ | 798 | .llong .sys_ni_syscall /* old idle syscall */ |
diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 7cf7a9600025..9c8e317c598d 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c | |||
@@ -791,31 +791,6 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) | |||
791 | } | 791 | } |
792 | 792 | ||
793 | 793 | ||
794 | asmlinkage int ppc64_newuname(struct new_utsname __user * name) | ||
795 | { | ||
796 | int errno = sys_newuname(name); | ||
797 | |||
798 | if (current->personality == PER_LINUX32 && !errno) { | ||
799 | if(copy_to_user(name->machine, "ppc\0\0", 8)) { | ||
800 | errno = -EFAULT; | ||
801 | } | ||
802 | } | ||
803 | return errno; | ||
804 | } | ||
805 | |||
806 | asmlinkage int ppc64_personality(unsigned long personality) | ||
807 | { | ||
808 | int ret; | ||
809 | if (current->personality == PER_LINUX32 && personality == PER_LINUX) | ||
810 | personality = PER_LINUX32; | ||
811 | ret = sys_personality(personality); | ||
812 | if (ret == PER_LINUX32) | ||
813 | ret = PER_LINUX; | ||
814 | return ret; | ||
815 | } | ||
816 | |||
817 | |||
818 | |||
819 | /* Note: it is necessary to treat mode as an unsigned int, | 794 | /* Note: it is necessary to treat mode as an unsigned int, |
820 | * with the corresponding cast to a signed int to insure that the | 795 | * with the corresponding cast to a signed int to insure that the |
821 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) | 796 | * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) |
@@ -1158,26 +1133,47 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) | |||
1158 | } | 1133 | } |
1159 | #endif | 1134 | #endif |
1160 | 1135 | ||
1136 | asmlinkage int sys32_uname(struct old_utsname __user * name) | ||
1137 | { | ||
1138 | int err = 0; | ||
1139 | |||
1140 | down_read(&uts_sem); | ||
1141 | if (copy_to_user(name, &system_utsname, sizeof(*name))) | ||
1142 | err = -EFAULT; | ||
1143 | up_read(&uts_sem); | ||
1144 | if (!err && personality(current->personality) == PER_LINUX32) { | ||
1145 | /* change "ppc64" to "ppc" */ | ||
1146 | if (__put_user(0, name->machine + 3) | ||
1147 | || __put_user(0, name->machine + 4)) | ||
1148 | err = -EFAULT; | ||
1149 | } | ||
1150 | return err; | ||
1151 | } | ||
1152 | |||
1161 | asmlinkage int sys32_olduname(struct oldold_utsname __user * name) | 1153 | asmlinkage int sys32_olduname(struct oldold_utsname __user * name) |
1162 | { | 1154 | { |
1163 | int error; | 1155 | int error; |
1164 | 1156 | ||
1165 | if (!name) | ||
1166 | return -EFAULT; | ||
1167 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) | 1157 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) |
1168 | return -EFAULT; | 1158 | return -EFAULT; |
1169 | 1159 | ||
1170 | down_read(&uts_sem); | 1160 | down_read(&uts_sem); |
1171 | error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); | 1161 | error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); |
1172 | error -= __put_user(0,name->sysname+__OLD_UTS_LEN); | 1162 | error |= __put_user(0,name->sysname+__OLD_UTS_LEN); |
1173 | error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); | 1163 | error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); |
1174 | error -= __put_user(0,name->nodename+__OLD_UTS_LEN); | 1164 | error |= __put_user(0,name->nodename+__OLD_UTS_LEN); |
1175 | error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); | 1165 | error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); |
1176 | error -= __put_user(0,name->release+__OLD_UTS_LEN); | 1166 | error |= __put_user(0,name->release+__OLD_UTS_LEN); |
1177 | error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); | 1167 | error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); |
1178 | error -= __put_user(0,name->version+__OLD_UTS_LEN); | 1168 | error |= __put_user(0,name->version+__OLD_UTS_LEN); |
1179 | error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); | 1169 | error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); |
1180 | error = __put_user(0,name->machine+__OLD_UTS_LEN); | 1170 | error |= __put_user(0,name->machine+__OLD_UTS_LEN); |
1171 | if (personality(current->personality) == PER_LINUX32) { | ||
1172 | /* change "ppc64" to "ppc" */ | ||
1173 | error |= __put_user(0, name->machine + 3); | ||
1174 | error |= __put_user(0, name->machine + 4); | ||
1175 | } | ||
1176 | |||
1181 | up_read(&uts_sem); | 1177 | up_read(&uts_sem); |
1182 | 1178 | ||
1183 | error = error ? -EFAULT : 0; | 1179 | error = error ? -EFAULT : 0; |
diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index f2865ff8d2f9..a8cbb202b8cd 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c | |||
@@ -199,24 +199,33 @@ out: | |||
199 | return ret; | 199 | return ret; |
200 | } | 200 | } |
201 | 201 | ||
202 | static int __init set_fakeppc(char *str) | 202 | long ppc64_personality(unsigned long personality) |
203 | { | 203 | { |
204 | if (*str) | 204 | long ret; |
205 | return 0; | 205 | |
206 | init_task.personality = PER_LINUX32; | 206 | if (personality(current->personality) == PER_LINUX32 |
207 | return 1; | 207 | && personality == PER_LINUX) |
208 | personality = PER_LINUX32; | ||
209 | ret = sys_personality(personality); | ||
210 | if (ret == PER_LINUX32) | ||
211 | ret = PER_LINUX; | ||
212 | return ret; | ||
208 | } | 213 | } |
209 | __setup("fakeppc", set_fakeppc); | ||
210 | 214 | ||
211 | asmlinkage int sys_uname(struct old_utsname __user * name) | 215 | long ppc64_newuname(struct new_utsname __user * name) |
212 | { | 216 | { |
213 | int err = -EFAULT; | 217 | int err = 0; |
214 | 218 | ||
215 | down_read(&uts_sem); | 219 | down_read(&uts_sem); |
216 | if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) | 220 | if (copy_to_user(name, &system_utsname, sizeof(*name))) |
217 | err = 0; | 221 | err = -EFAULT; |
218 | up_read(&uts_sem); | 222 | up_read(&uts_sem); |
219 | 223 | if (!err && personality(current->personality) == PER_LINUX32) { | |
224 | /* change ppc64 to ppc */ | ||
225 | if (__put_user(0, name->machine + 3) | ||
226 | || __put_user(0, name->machine + 4)) | ||
227 | err = -EFAULT; | ||
228 | } | ||
220 | return err; | 229 | return err; |
221 | } | 230 | } |
222 | 231 | ||
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char index 3e50fdb67626..62d87b71179b 100644 --- a/arch/um/Kconfig_char +++ b/arch/um/Kconfig_char | |||
@@ -204,5 +204,11 @@ config UML_RANDOM | |||
204 | http://sourceforge.net/projects/gkernel/). rngd periodically reads | 204 | http://sourceforge.net/projects/gkernel/). rngd periodically reads |
205 | /dev/hwrng and injects the entropy into /dev/random. | 205 | /dev/hwrng and injects the entropy into /dev/random. |
206 | 206 | ||
207 | config MMAPPER | ||
208 | tristate "iomem emulation driver" | ||
209 | help | ||
210 | This driver allows a host file to be used as emulated IO memory inside | ||
211 | UML. | ||
212 | |||
207 | endmenu | 213 | endmenu |
208 | 214 | ||
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 583b8e137c33..5d3768156c92 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c | |||
@@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) | |||
143 | { | 143 | { |
144 | struct winch_data data; | 144 | struct winch_data data; |
145 | unsigned long stack; | 145 | unsigned long stack; |
146 | int fds[2], pid, n, err; | 146 | int fds[2], n, err; |
147 | char c; | 147 | char c; |
148 | 148 | ||
149 | err = os_pipe(fds, 1, 1); | 149 | err = os_pipe(fds, 1, 1); |
150 | if(err < 0){ | 150 | if(err < 0){ |
151 | printk("winch_tramp : os_pipe failed, err = %d\n", -err); | 151 | printk("winch_tramp : os_pipe failed, err = %d\n", -err); |
152 | return(err); | 152 | goto out; |
153 | } | 153 | } |
154 | 154 | ||
155 | data = ((struct winch_data) { .pty_fd = fd, | 155 | data = ((struct winch_data) { .pty_fd = fd, |
156 | .pipe_fd = fds[1], | 156 | .pipe_fd = fds[1], |
157 | .close_me = fds[0] } ); | 157 | .close_me = fds[0] } ); |
158 | pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); | 158 | err = run_helper_thread(winch_thread, &data, 0, &stack, 0); |
159 | if(pid < 0){ | 159 | if(err < 0){ |
160 | printk("fork of winch_thread failed - errno = %d\n", errno); | 160 | printk("fork of winch_thread failed - errno = %d\n", errno); |
161 | return(pid); | 161 | goto out_close; |
162 | } | 162 | } |
163 | 163 | ||
164 | os_close_file(fds[1]); | 164 | os_close_file(fds[1]); |
@@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) | |||
168 | printk("winch_tramp : failed to read synchronization byte\n"); | 168 | printk("winch_tramp : failed to read synchronization byte\n"); |
169 | printk("read failed, err = %d\n", -n); | 169 | printk("read failed, err = %d\n", -n); |
170 | printk("fd %d will not support SIGWINCH\n", fd); | 170 | printk("fd %d will not support SIGWINCH\n", fd); |
171 | *fd_out = -1; | 171 | err = -EINVAL; |
172 | goto out_close1; | ||
172 | } | 173 | } |
173 | return(pid); | 174 | return err ; |
175 | |||
176 | out_close: | ||
177 | os_close_file(fds[1]); | ||
178 | out_close1: | ||
179 | os_close_file(fds[0]); | ||
180 | out: | ||
181 | return err; | ||
174 | } | 182 | } |
175 | 183 | ||
176 | void register_winch(int fd, struct tty_struct *tty) | 184 | void register_winch(int fd, struct tty_struct *tty) |
177 | { | 185 | { |
178 | int pid, thread, thread_fd; | 186 | int pid, thread, thread_fd = -1; |
179 | int count; | 187 | int count; |
180 | char c = 1; | 188 | char c = 1; |
181 | 189 | ||
@@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty) | |||
186 | if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, | 194 | if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, |
187 | tty) && (pid == -1)){ | 195 | tty) && (pid == -1)){ |
188 | thread = winch_tramp(fd, tty, &thread_fd); | 196 | thread = winch_tramp(fd, tty, &thread_fd); |
189 | if(fd != -1){ | 197 | if(thread > 0){ |
190 | register_winch_irq(thread_fd, fd, thread, tty); | 198 | register_winch_irq(thread_fd, fd, thread, tty); |
191 | 199 | ||
192 | count = os_write_file(thread_fd, &c, sizeof(c)); | 200 | count = os_write_file(thread_fd, &c, sizeof(c)); |
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index a63231dffe05..a37a5ac13c22 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/smp_lock.h> | 20 | #include <linux/smp_lock.h> |
21 | #include <linux/miscdevice.h> | ||
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
22 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
23 | #include <asm/pgtable.h> | 24 | #include <asm/pgtable.h> |
@@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = { | |||
117 | .release = mmapper_release, | 118 | .release = mmapper_release, |
118 | }; | 119 | }; |
119 | 120 | ||
121 | static struct miscdevice mmapper_dev = { | ||
122 | .minor = MISC_DYNAMIC_MINOR, | ||
123 | .name = "mmapper", | ||
124 | .fops = &mmapper_fops | ||
125 | }; | ||
126 | |||
120 | static int __init mmapper_init(void) | 127 | static int __init mmapper_init(void) |
121 | { | 128 | { |
129 | int err; | ||
130 | |||
122 | printk(KERN_INFO "Mapper v0.1\n"); | 131 | printk(KERN_INFO "Mapper v0.1\n"); |
123 | 132 | ||
124 | v_buf = (char *) find_iomem("mmapper", &mmapper_size); | 133 | v_buf = (char *) find_iomem("mmapper", &mmapper_size); |
125 | if(mmapper_size == 0){ | 134 | if(mmapper_size == 0){ |
126 | printk(KERN_ERR "mmapper_init - find_iomem failed\n"); | 135 | printk(KERN_ERR "mmapper_init - find_iomem failed\n"); |
127 | return(0); | 136 | goto out; |
128 | } | 137 | } |
129 | 138 | ||
130 | p_buf = __pa(v_buf); | 139 | err = misc_register(&mmapper_dev); |
140 | if(err){ | ||
141 | printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", | ||
142 | err); | ||
143 | goto out; | ||
144 | } | ||
131 | 145 | ||
132 | devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper"); | 146 | p_buf = __pa(v_buf); |
133 | return(0); | 147 | out: |
148 | return 0; | ||
134 | } | 149 | } |
135 | 150 | ||
136 | static void mmapper_exit(void) | 151 | static void mmapper_exit(void) |
137 | { | 152 | { |
153 | misc_deregister(&mmapper_dev); | ||
138 | } | 154 | } |
139 | 155 | ||
140 | module_init(mmapper_init); | 156 | module_init(mmapper_init); |
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 47229fe4a813..3730d4f12713 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c | |||
@@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr) | |||
32 | return(0); | 32 | return(0); |
33 | } | 33 | } |
34 | 34 | ||
35 | void tap_check_ips(char *gate_addr, char *eth_addr) | 35 | void tap_check_ips(char *gate_addr, unsigned char *eth_addr) |
36 | { | 36 | { |
37 | int tap_addr[4]; | 37 | int tap_addr[4]; |
38 | 38 | ||
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h index 495f2f1b1420..d523618cd5ac 100644 --- a/arch/um/drivers/slip.h +++ b/arch/um/drivers/slip.h | |||
@@ -12,8 +12,8 @@ struct slip_data { | |||
12 | char *addr; | 12 | char *addr; |
13 | char *gate_addr; | 13 | char *gate_addr; |
14 | int slave; | 14 | int slave; |
15 | char ibuf[ENC_BUF_SIZE]; | 15 | unsigned char ibuf[ENC_BUF_SIZE]; |
16 | char obuf[ENC_BUF_SIZE]; | 16 | unsigned char obuf[ENC_BUF_SIZE]; |
17 | int more; /* more data: do not read fd until ibuf has been drained */ | 17 | int more; /* more data: do not read fd until ibuf has been drained */ |
18 | int pos; | 18 | int pos; |
19 | int esc; | 19 | int esc; |
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_proto.h index 7206361ace45..4c4d94a33100 100644 --- a/arch/um/drivers/slip_proto.h +++ b/arch/um/drivers/slip_proto.h | |||
@@ -12,7 +12,8 @@ | |||
12 | #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ | 12 | #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ |
13 | #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ | 13 | #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ |
14 | 14 | ||
15 | static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc) | 15 | static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, |
16 | int *esc) | ||
16 | { | 17 | { |
17 | int ret; | 18 | int ret; |
18 | 19 | ||
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h index 04e407d1e44a..afa4e30284fd 100644 --- a/arch/um/drivers/slirp.h +++ b/arch/um/drivers/slirp.h | |||
@@ -24,8 +24,8 @@ struct slirp_data { | |||
24 | struct arg_list_dummy_wrapper argw; | 24 | struct arg_list_dummy_wrapper argw; |
25 | int pid; | 25 | int pid; |
26 | int slave; | 26 | int slave; |
27 | char ibuf[ENC_BUF_SIZE]; | 27 | unsigned char ibuf[ENC_BUF_SIZE]; |
28 | char obuf[ENC_BUF_SIZE]; | 28 | unsigned char obuf[ENC_BUF_SIZE]; |
29 | int more; /* more data: do not read fd until ibuf has been drained */ | 29 | int more; /* more data: do not read fd until ibuf has been drained */ |
30 | int pos; | 30 | int pos; |
31 | int esc; | 31 | int esc; |
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index 98565b53d170..429ae8e6c7e5 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c | |||
@@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string, | |||
22 | } | 22 | } |
23 | 23 | ||
24 | static struct console stderr_console = { | 24 | static struct console stderr_console = { |
25 | .name "stderr", | 25 | .name = "stderr", |
26 | .write stderr_console_write, | 26 | .write = stderr_console_write, |
27 | .flags CON_PRINTBUFFER, | 27 | .flags = CON_PRINTBUFFER, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static int __init stderr_console_init(void) | 30 | static int __init stderr_console_init(void) |
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 9fbe3083fdd8..cfa368e045a5 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h | |||
@@ -56,7 +56,7 @@ struct mc_request | |||
56 | int as_interrupt; | 56 | int as_interrupt; |
57 | 57 | ||
58 | int originating_fd; | 58 | int originating_fd; |
59 | int originlen; | 59 | unsigned int originlen; |
60 | unsigned char origin[128]; /* sockaddr_un */ | 60 | unsigned char origin[128]; /* sockaddr_un */ |
61 | 61 | ||
62 | struct mconsole_request request; | 62 | struct mconsole_request request; |
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index 36807b796e9f..89885a77a771 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h | |||
@@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out); | |||
35 | extern void free_output_buffer(void *buffer); | 35 | extern void free_output_buffer(void *buffer); |
36 | 36 | ||
37 | extern int tap_open_common(void *dev, char *gate_addr); | 37 | extern int tap_open_common(void *dev, char *gate_addr); |
38 | extern void tap_check_ips(char *gate_addr, char *eth_addr); | 38 | extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr); |
39 | 39 | ||
40 | extern void read_output(int fd, char *output_out, int len); | 40 | extern void read_output(int fd, char *output_out, int len); |
41 | 41 | ||
diff --git a/arch/um/include/os.h b/arch/um/include/os.h index d246d5a24609..881d2988d2d8 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h | |||
@@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset); | |||
136 | extern int os_open_file(char *file, struct openflags flags, int mode); | 136 | extern int os_open_file(char *file, struct openflags flags, int mode); |
137 | extern int os_read_file(int fd, void *buf, int len); | 137 | extern int os_read_file(int fd, void *buf, int len); |
138 | extern int os_write_file(int fd, const void *buf, int count); | 138 | extern int os_write_file(int fd, const void *buf, int count); |
139 | extern int os_file_size(char *file, long long *size_out); | 139 | extern int os_file_size(char *file, unsigned long long *size_out); |
140 | extern int os_file_modtime(char *file, unsigned long *modtime); | 140 | extern int os_file_modtime(char *file, unsigned long *modtime); |
141 | extern int os_pipe(int *fd, int stream, int close_on_exec); | 141 | extern int os_pipe(int *fd, int stream, int close_on_exec); |
142 | extern int os_set_fd_async(int fd, int owner); | 142 | extern int os_set_fd_async(int fd, int owner); |
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index b8c5b8a95250..7b6a24dfd302 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h | |||
@@ -41,9 +41,6 @@ extern unsigned long highmem; | |||
41 | extern char host_info[]; | 41 | extern char host_info[]; |
42 | 42 | ||
43 | extern char saved_command_line[]; | 43 | extern char saved_command_line[]; |
44 | extern char command_line[]; | ||
45 | |||
46 | extern char *tempdir; | ||
47 | 44 | ||
48 | extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; | 45 | extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; |
49 | extern unsigned long _unprotected_end; | 46 | extern unsigned long _unprotected_end; |
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index ab5d3271da0b..fc71ef295782 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -68,8 +68,11 @@ void new_thread_handler(int sig) | |||
68 | * 0 if it just exits | 68 | * 0 if it just exits |
69 | */ | 69 | */ |
70 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); | 70 | n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); |
71 | if(n == 1) | 71 | if(n == 1){ |
72 | /* Handle any immediate reschedules or signals */ | ||
73 | interrupt_end(); | ||
72 | userspace(¤t->thread.regs.regs); | 74 | userspace(¤t->thread.regs.regs); |
75 | } | ||
73 | else do_exit(0); | 76 | else do_exit(0); |
74 | } | 77 | } |
75 | 78 | ||
@@ -96,6 +99,8 @@ void fork_handler(int sig) | |||
96 | schedule_tail(current->thread.prev_sched); | 99 | schedule_tail(current->thread.prev_sched); |
97 | current->thread.prev_sched = NULL; | 100 | current->thread.prev_sched = NULL; |
98 | 101 | ||
102 | /* Handle any immediate reschedules or signals */ | ||
103 | interrupt_end(); | ||
99 | userspace(¤t->thread.regs.regs); | 104 | userspace(¤t->thread.regs.regs); |
100 | } | 105 | } |
101 | 106 | ||
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 9aee0b62ebca..f0d6060e3e57 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c | |||
@@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp) | |||
45 | elf_aux_hwcap = auxv->a_un.a_val; | 45 | elf_aux_hwcap = auxv->a_un.a_val; |
46 | break; | 46 | break; |
47 | case AT_PLATFORM: | 47 | case AT_PLATFORM: |
48 | elf_aux_platform = auxv->a_un.a_ptr; | 48 | /* elf.h removed the pointer elements from |
49 | * a_un, so we have to use a_val, which is | ||
50 | * all that's left. | ||
51 | */ | ||
52 | elf_aux_platform = (char *) auxv->a_un.a_val; | ||
49 | break; | 53 | break; |
50 | case AT_PAGESZ: | 54 | case AT_PAGESZ: |
51 | page_size = auxv->a_un.a_val; | 55 | page_size = auxv->a_un.a_val; |
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 77d4066d1af8..fd45bb260907 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c | |||
@@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len) | |||
363 | (int (*)(int, void *, int)) write, copy_to_user_proc)); | 363 | (int (*)(int, void *, int)) write, copy_to_user_proc)); |
364 | } | 364 | } |
365 | 365 | ||
366 | int os_file_size(char *file, long long *size_out) | 366 | int os_file_size(char *file, unsigned long long *size_out) |
367 | { | 367 | { |
368 | struct uml_stat buf; | 368 | struct uml_stat buf; |
369 | int err; | 369 | int err; |
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index a491f72cc966..504e63474993 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c | |||
@@ -33,12 +33,10 @@ int fallback_aper_force __initdata = 0; | |||
33 | 33 | ||
34 | int fix_aperture __initdata = 1; | 34 | int fix_aperture __initdata = 1; |
35 | 35 | ||
36 | #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) | 36 | /* This code runs before the PCI subsystem is initialized, so just |
37 | access the northbridge directly. */ | ||
37 | 38 | ||
38 | static struct resource aper_res = { | 39 | #define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) |
39 | .name = "Aperture", | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }; | ||
42 | 40 | ||
43 | static u32 __init allocate_aperture(void) | 41 | static u32 __init allocate_aperture(void) |
44 | { | 42 | { |
@@ -55,24 +53,11 @@ static u32 __init allocate_aperture(void) | |||
55 | aper_size = (32 * 1024 * 1024) << fallback_aper_order; | 53 | aper_size = (32 * 1024 * 1024) << fallback_aper_order; |
56 | 54 | ||
57 | /* | 55 | /* |
58 | * Aperture has to be naturally aligned. This means an 2GB | 56 | * Aperture has to be naturally aligned. This means an 2GB aperture won't |
59 | * aperture won't have much chances to find a place in the | 57 | * have much chances to find a place in the lower 4GB of memory. |
60 | * lower 4GB of memory. Unfortunately we cannot move it up | 58 | * Unfortunately we cannot move it up because that would make the |
61 | * because that would make the IOMMU useless. | 59 | * IOMMU useless. |
62 | */ | 60 | */ |
63 | |||
64 | /* First try to find some free unused space */ | ||
65 | if (!allocate_resource(&iomem_resource, &aper_res, | ||
66 | aper_size, | ||
67 | 0, 0xffffffff, | ||
68 | aper_size, | ||
69 | NULL, NULL)) { | ||
70 | printk(KERN_INFO "Putting aperture at %lx-%lx\n", | ||
71 | aper_res.start, aper_res.end); | ||
72 | return aper_res.start; | ||
73 | } | ||
74 | |||
75 | /* No free space found. Go on to waste some memory... */ | ||
76 | p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); | 61 | p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); |
77 | if (!p || __pa(p)+aper_size > 0xffffffff) { | 62 | if (!p || __pa(p)+aper_size > 0xffffffff) { |
78 | printk("Cannot allocate aperture memory hole (%p,%uK)\n", | 63 | printk("Cannot allocate aperture memory hole (%p,%uK)\n", |
@@ -81,7 +66,7 @@ static u32 __init allocate_aperture(void) | |||
81 | free_bootmem_node(nd0, (unsigned long)p, aper_size); | 66 | free_bootmem_node(nd0, (unsigned long)p, aper_size); |
82 | return 0; | 67 | return 0; |
83 | } | 68 | } |
84 | printk("Mapping aperture over %d KB of precious RAM @ %lx\n", | 69 | printk("Mapping aperture over %d KB of RAM @ %lx\n", |
85 | aper_size >> 10, __pa(p)); | 70 | aper_size >> 10, __pa(p)); |
86 | return (u32)__pa(p); | 71 | return (u32)__pa(p); |
87 | } | 72 | } |
@@ -102,16 +87,10 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) | |||
102 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); | 87 | printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); |
103 | return 0; | 88 | return 0; |
104 | } | 89 | } |
105 | /* Don't check the resource here because the aperture is usually | ||
106 | in an e820 reserved area, and we allocated these earlier. */ | ||
107 | return 1; | 90 | return 1; |
108 | } | 91 | } |
109 | 92 | ||
110 | /* | 93 | /* Find a PCI capability */ |
111 | * Find a PCI capability. | ||
112 | * This code runs before the PCI subsystem is initialized, so just | ||
113 | * access the northbridge directly. | ||
114 | */ | ||
115 | static __u32 __init find_cap(int num, int slot, int func, int cap) | 94 | static __u32 __init find_cap(int num, int slot, int func, int cap) |
116 | { | 95 | { |
117 | u8 pos; | 96 | u8 pos; |
@@ -276,6 +255,8 @@ void __init iommu_hole_init(void) | |||
276 | fallback_aper_force) { | 255 | fallback_aper_force) { |
277 | printk("Your BIOS doesn't leave a aperture memory hole\n"); | 256 | printk("Your BIOS doesn't leave a aperture memory hole\n"); |
278 | printk("Please enable the IOMMU option in the BIOS setup\n"); | 257 | printk("Please enable the IOMMU option in the BIOS setup\n"); |
258 | printk("This costs you %d MB of RAM\n", | ||
259 | 32 << fallback_aper_order); | ||
279 | 260 | ||
280 | aper_order = fallback_aper_order; | 261 | aper_order = fallback_aper_order; |
281 | aper_alloc = allocate_aperture(); | 262 | aper_alloc = allocate_aperture(); |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index adc4dcc306f4..19c5e59bcfa8 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -51,7 +51,7 @@ | |||
51 | * This many LUNs per USB device. | 51 | * This many LUNs per USB device. |
52 | * Every one of them takes a host, see UB_MAX_HOSTS. | 52 | * Every one of them takes a host, see UB_MAX_HOSTS. |
53 | */ | 53 | */ |
54 | #define UB_MAX_LUNS 4 | 54 | #define UB_MAX_LUNS 9 |
55 | 55 | ||
56 | /* | 56 | /* |
57 | */ | 57 | */ |
@@ -2100,7 +2100,7 @@ static int ub_probe(struct usb_interface *intf, | |||
2100 | nluns = rc; | 2100 | nluns = rc; |
2101 | break; | 2101 | break; |
2102 | } | 2102 | } |
2103 | mdelay(100); | 2103 | msleep(100); |
2104 | } | 2104 | } |
2105 | 2105 | ||
2106 | for (i = 0; i < nluns; i++) { | 2106 | for (i = 0; i < nluns; i++) { |
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index ad9c11391d81..c1fe013c64f3 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -278,6 +278,8 @@ void agp3_generic_cleanup(void); | |||
278 | #define AGP_GENERIC_SIZES_ENTRIES 11 | 278 | #define AGP_GENERIC_SIZES_ENTRIES 11 |
279 | extern struct aper_size_info_16 agp3_generic_sizes[]; | 279 | extern struct aper_size_info_16 agp3_generic_sizes[]; |
280 | 280 | ||
281 | #define virt_to_gart(x) (phys_to_gart(virt_to_phys(x))) | ||
282 | #define gart_to_virt(x) (phys_to_virt(gart_to_phys(x))) | ||
281 | 283 | ||
282 | extern int agp_off; | 284 | extern int agp_off; |
283 | extern int agp_try_unsupported_boot; | 285 | extern int agp_try_unsupported_boot; |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 0212febda654..9c9c9c2247ce 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -150,7 +150,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) | |||
150 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 150 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
151 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 151 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
152 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 152 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
153 | virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN )); | 153 | virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN )); |
154 | return addr; | 154 | return addr; |
155 | } | 155 | } |
156 | 156 | ||
@@ -174,7 +174,7 @@ static void m1541_destroy_page(void * addr) | |||
174 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 174 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
175 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 175 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
176 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 176 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
177 | virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); | 177 | virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); |
178 | agp_generic_destroy_page(addr); | 178 | agp_generic_destroy_page(addr); |
179 | } | 179 | } |
180 | 180 | ||
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index e62a3c2c44a9..3a41672e4d66 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -43,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) | |||
43 | 43 | ||
44 | SetPageReserved(virt_to_page(page_map->real)); | 44 | SetPageReserved(virt_to_page(page_map->real)); |
45 | global_cache_flush(); | 45 | global_cache_flush(); |
46 | page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), | 46 | page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), |
47 | PAGE_SIZE); | 47 | PAGE_SIZE); |
48 | if (page_map->remapped == NULL) { | 48 | if (page_map->remapped == NULL) { |
49 | ClearPageReserved(virt_to_page(page_map->real)); | 49 | ClearPageReserved(virt_to_page(page_map->real)); |
@@ -154,7 +154,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
154 | 154 | ||
155 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 155 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
156 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; | 156 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; |
157 | agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); | 157 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); |
158 | 158 | ||
159 | /* Get the address for the gart region. | 159 | /* Get the address for the gart region. |
160 | * This is a bus address even on the alpha, b/c its | 160 | * This is a bus address even on the alpha, b/c its |
@@ -167,7 +167,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) | |||
167 | 167 | ||
168 | /* Calculate the agp offset */ | 168 | /* Calculate the agp offset */ |
169 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { | 169 | for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { |
170 | writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, | 170 | writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1, |
171 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); | 171 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); |
172 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 172 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
173 | } | 173 | } |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 399c042f68f0..1407945a5892 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -219,7 +219,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] = | |||
219 | 219 | ||
220 | static int amd_8151_configure(void) | 220 | static int amd_8151_configure(void) |
221 | { | 221 | { |
222 | unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); | 222 | unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); |
223 | 223 | ||
224 | /* Configure AGP regs in each x86-64 host bridge. */ | 224 | /* Configure AGP regs in each x86-64 host bridge. */ |
225 | for_each_nb() { | 225 | for_each_nb() { |
@@ -591,7 +591,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) | |||
591 | { | 591 | { |
592 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); | 592 | struct agp_bridge_data *bridge = pci_get_drvdata(pdev); |
593 | 593 | ||
594 | release_mem_region(virt_to_phys(bridge->gatt_table_real), | 594 | release_mem_region(virt_to_gart(bridge->gatt_table_real), |
595 | amd64_aperture_sizes[bridge->aperture_size_idx].size); | 595 | amd64_aperture_sizes[bridge->aperture_size_idx].size); |
596 | agp_remove_bridge(bridge); | 596 | agp_remove_bridge(bridge); |
597 | agp_put_bridge(bridge); | 597 | agp_put_bridge(bridge); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index a65f8827c283..e572ced9100a 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_map *page_map) | |||
61 | 61 | ||
62 | SetPageReserved(virt_to_page(page_map->real)); | 62 | SetPageReserved(virt_to_page(page_map->real)); |
63 | err = map_page_into_agp(virt_to_page(page_map->real)); | 63 | err = map_page_into_agp(virt_to_page(page_map->real)); |
64 | page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), | 64 | page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), |
65 | PAGE_SIZE); | 65 | PAGE_SIZE); |
66 | if (page_map->remapped == NULL || err) { | 66 | if (page_map->remapped == NULL || err) { |
67 | ClearPageReserved(virt_to_page(page_map->real)); | 67 | ClearPageReserved(virt_to_page(page_map->real)); |
@@ -343,7 +343,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
343 | 343 | ||
344 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 344 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
345 | agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; | 345 | agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; |
346 | agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); | 346 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); |
347 | 347 | ||
348 | /* Write out the size register */ | 348 | /* Write out the size register */ |
349 | current_size = A_SIZE_LVL2(agp_bridge->current_size); | 349 | current_size = A_SIZE_LVL2(agp_bridge->current_size); |
@@ -373,7 +373,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) | |||
373 | 373 | ||
374 | /* Calculate the agp offset */ | 374 | /* Calculate the agp offset */ |
375 | for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { | 375 | for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { |
376 | writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1, | 376 | writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1, |
377 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); | 377 | page_dir.remapped+GET_PAGE_DIR_OFF(addr)); |
378 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ | 378 | readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ |
379 | } | 379 | } |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 2f3dfb63bdc6..4d4e602fdc7e 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -148,7 +148,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
148 | return -ENOMEM; | 148 | return -ENOMEM; |
149 | } | 149 | } |
150 | 150 | ||
151 | bridge->scratch_page_real = virt_to_phys(addr); | 151 | bridge->scratch_page_real = virt_to_gart(addr); |
152 | bridge->scratch_page = | 152 | bridge->scratch_page = |
153 | bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); | 153 | bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); |
154 | } | 154 | } |
@@ -189,7 +189,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
189 | err_out: | 189 | err_out: |
190 | if (bridge->driver->needs_scratch_page) | 190 | if (bridge->driver->needs_scratch_page) |
191 | bridge->driver->agp_destroy_page( | 191 | bridge->driver->agp_destroy_page( |
192 | phys_to_virt(bridge->scratch_page_real)); | 192 | gart_to_virt(bridge->scratch_page_real)); |
193 | if (got_gatt) | 193 | if (got_gatt) |
194 | bridge->driver->free_gatt_table(bridge); | 194 | bridge->driver->free_gatt_table(bridge); |
195 | if (got_keylist) { | 195 | if (got_keylist) { |
@@ -214,7 +214,7 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) | |||
214 | if (bridge->driver->agp_destroy_page && | 214 | if (bridge->driver->agp_destroy_page && |
215 | bridge->driver->needs_scratch_page) | 215 | bridge->driver->needs_scratch_page) |
216 | bridge->driver->agp_destroy_page( | 216 | bridge->driver->agp_destroy_page( |
217 | phys_to_virt(bridge->scratch_page_real)); | 217 | gart_to_virt(bridge->scratch_page_real)); |
218 | } | 218 | } |
219 | 219 | ||
220 | /* When we remove the global variable agp_bridge from all drivers | 220 | /* When we remove the global variable agp_bridge from all drivers |
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 1383c3165ea1..ac19fdcd21c1 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c | |||
@@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge) | |||
219 | 219 | ||
220 | efficeon_private.l1_table[index] = page; | 220 | efficeon_private.l1_table[index] = page; |
221 | 221 | ||
222 | value = __pa(page) | pati | present | index; | 222 | value = virt_to_gart(page) | pati | present | index; |
223 | 223 | ||
224 | pci_write_config_dword(agp_bridge->dev, | 224 | pci_write_config_dword(agp_bridge->dev, |
225 | EFFICEON_ATTPAGE, value); | 225 | EFFICEON_ATTPAGE, value); |
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index c321a924e38a..f0079e991bdc 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -153,7 +153,7 @@ void agp_free_memory(struct agp_memory *curr) | |||
153 | } | 153 | } |
154 | if (curr->page_count != 0) { | 154 | if (curr->page_count != 0) { |
155 | for (i = 0; i < curr->page_count; i++) { | 155 | for (i = 0; i < curr->page_count; i++) { |
156 | curr->bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i])); | 156 | curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | agp_free_key(curr->key); | 159 | agp_free_key(curr->key); |
@@ -209,7 +209,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
209 | agp_free_memory(new); | 209 | agp_free_memory(new); |
210 | return NULL; | 210 | return NULL; |
211 | } | 211 | } |
212 | new->memory[i] = virt_to_phys(addr); | 212 | new->memory[i] = virt_to_gart(addr); |
213 | new->page_count++; | 213 | new->page_count++; |
214 | } | 214 | } |
215 | new->bridge = bridge; | 215 | new->bridge = bridge; |
@@ -295,19 +295,6 @@ int agp_num_entries(void) | |||
295 | EXPORT_SYMBOL_GPL(agp_num_entries); | 295 | EXPORT_SYMBOL_GPL(agp_num_entries); |
296 | 296 | ||
297 | 297 | ||
298 | static int check_bridge_mode(struct pci_dev *dev) | ||
299 | { | ||
300 | u32 agp3; | ||
301 | u8 cap_ptr; | ||
302 | |||
303 | cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); | ||
304 | pci_read_config_dword(dev, cap_ptr+AGPSTAT, &agp3); | ||
305 | if (agp3 & AGPSTAT_MODE_3_0) | ||
306 | return 1; | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | |||
311 | /** | 298 | /** |
312 | * agp_copy_info - copy bridge state information | 299 | * agp_copy_info - copy bridge state information |
313 | * | 300 | * |
@@ -328,7 +315,7 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info) | |||
328 | info->version.minor = bridge->version->minor; | 315 | info->version.minor = bridge->version->minor; |
329 | info->chipset = SUPPORTED; | 316 | info->chipset = SUPPORTED; |
330 | info->device = bridge->dev; | 317 | info->device = bridge->dev; |
331 | if (check_bridge_mode(bridge->dev)) | 318 | if (bridge->mode & AGPSTAT_MODE_3_0) |
332 | info->mode = bridge->mode & ~AGP3_RESERVED_MASK; | 319 | info->mode = bridge->mode & ~AGP3_RESERVED_MASK; |
333 | else | 320 | else |
334 | info->mode = bridge->mode & ~AGP2_RESERVED_MASK; | 321 | info->mode = bridge->mode & ~AGP2_RESERVED_MASK; |
@@ -661,7 +648,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode | |||
661 | bridge_agpstat &= ~AGPSTAT_FW; | 648 | bridge_agpstat &= ~AGPSTAT_FW; |
662 | 649 | ||
663 | /* Check to see if we are operating in 3.0 mode */ | 650 | /* Check to see if we are operating in 3.0 mode */ |
664 | if (check_bridge_mode(agp_bridge->dev)) | 651 | if (agp_bridge->mode & AGPSTAT_MODE_3_0) |
665 | agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); | 652 | agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); |
666 | else | 653 | else |
667 | agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); | 654 | agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); |
@@ -732,7 +719,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) | |||
732 | 719 | ||
733 | /* Do AGP version specific frobbing. */ | 720 | /* Do AGP version specific frobbing. */ |
734 | if (bridge->major_version >= 3) { | 721 | if (bridge->major_version >= 3) { |
735 | if (check_bridge_mode(bridge->dev)) { | 722 | if (bridge->mode & AGPSTAT_MODE_3_0) { |
736 | /* If we have 3.5, we can do the isoch stuff. */ | 723 | /* If we have 3.5, we can do the isoch stuff. */ |
737 | if (bridge->minor_version >= 5) | 724 | if (bridge->minor_version >= 5) |
738 | agp_3_5_enable(bridge); | 725 | agp_3_5_enable(bridge); |
@@ -806,8 +793,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) | |||
806 | break; | 793 | break; |
807 | } | 794 | } |
808 | 795 | ||
809 | table = (char *) __get_free_pages(GFP_KERNEL, | 796 | table = alloc_gatt_pages(page_order); |
810 | page_order); | ||
811 | 797 | ||
812 | if (table == NULL) { | 798 | if (table == NULL) { |
813 | i++; | 799 | i++; |
@@ -838,7 +824,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) | |||
838 | size = ((struct aper_size_info_fixed *) temp)->size; | 824 | size = ((struct aper_size_info_fixed *) temp)->size; |
839 | page_order = ((struct aper_size_info_fixed *) temp)->page_order; | 825 | page_order = ((struct aper_size_info_fixed *) temp)->page_order; |
840 | num_entries = ((struct aper_size_info_fixed *) temp)->num_entries; | 826 | num_entries = ((struct aper_size_info_fixed *) temp)->num_entries; |
841 | table = (char *) __get_free_pages(GFP_KERNEL, page_order); | 827 | table = alloc_gatt_pages(page_order); |
842 | } | 828 | } |
843 | 829 | ||
844 | if (table == NULL) | 830 | if (table == NULL) |
@@ -853,7 +839,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) | |||
853 | agp_gatt_table = (void *)table; | 839 | agp_gatt_table = (void *)table; |
854 | 840 | ||
855 | bridge->driver->cache_flush(); | 841 | bridge->driver->cache_flush(); |
856 | bridge->gatt_table = ioremap_nocache(virt_to_phys(table), | 842 | bridge->gatt_table = ioremap_nocache(virt_to_gart(table), |
857 | (PAGE_SIZE * (1 << page_order))); | 843 | (PAGE_SIZE * (1 << page_order))); |
858 | bridge->driver->cache_flush(); | 844 | bridge->driver->cache_flush(); |
859 | 845 | ||
@@ -861,11 +847,11 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) | |||
861 | for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) | 847 | for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) |
862 | ClearPageReserved(page); | 848 | ClearPageReserved(page); |
863 | 849 | ||
864 | free_pages((unsigned long) table, page_order); | 850 | free_gatt_pages(table, page_order); |
865 | 851 | ||
866 | return -ENOMEM; | 852 | return -ENOMEM; |
867 | } | 853 | } |
868 | bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real); | 854 | bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real); |
869 | 855 | ||
870 | /* AK: bogus, should encode addresses > 4GB */ | 856 | /* AK: bogus, should encode addresses > 4GB */ |
871 | for (i = 0; i < num_entries; i++) { | 857 | for (i = 0; i < num_entries; i++) { |
@@ -919,7 +905,7 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge) | |||
919 | for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) | 905 | for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) |
920 | ClearPageReserved(page); | 906 | ClearPageReserved(page); |
921 | 907 | ||
922 | free_pages((unsigned long) bridge->gatt_table_real, page_order); | 908 | free_gatt_pages(bridge->gatt_table_real, page_order); |
923 | 909 | ||
924 | agp_gatt_table = NULL; | 910 | agp_gatt_table = NULL; |
925 | bridge->gatt_table = NULL; | 911 | bridge->gatt_table = NULL; |
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 6052bfa04c72..99762b6c19ae 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c | |||
@@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void) | |||
110 | hp->gart_size = HP_ZX1_GART_SIZE; | 110 | hp->gart_size = HP_ZX1_GART_SIZE; |
111 | hp->gatt_entries = hp->gart_size / hp->io_page_size; | 111 | hp->gatt_entries = hp->gart_size / hp->io_page_size; |
112 | 112 | ||
113 | hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); | 113 | hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); |
114 | hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; | 114 | hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; |
115 | 115 | ||
116 | if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { | 116 | if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { |
@@ -248,7 +248,7 @@ hp_zx1_configure (void) | |||
248 | agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); | 248 | agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); |
249 | 249 | ||
250 | if (hp->io_pdir_owner) { | 250 | if (hp->io_pdir_owner) { |
251 | writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); | 251 | writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); |
252 | readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); | 252 | readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); |
253 | writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); | 253 | writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); |
254 | readl(hp->ioc_regs+HP_ZX1_TCNFG); | 254 | readl(hp->ioc_regs+HP_ZX1_TCNFG); |
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index adbea896c0d2..94943298c03e 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c | |||
@@ -372,7 +372,7 @@ static int i460_alloc_large_page (struct lp_desc *lp) | |||
372 | } | 372 | } |
373 | memset(lp->alloced_map, 0, map_size); | 373 | memset(lp->alloced_map, 0, map_size); |
374 | 374 | ||
375 | lp->paddr = virt_to_phys(lpage); | 375 | lp->paddr = virt_to_gart(lpage); |
376 | lp->refcount = 0; | 376 | lp->refcount = 0; |
377 | atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); | 377 | atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); |
378 | return 0; | 378 | return 0; |
@@ -383,7 +383,7 @@ static void i460_free_large_page (struct lp_desc *lp) | |||
383 | kfree(lp->alloced_map); | 383 | kfree(lp->alloced_map); |
384 | lp->alloced_map = NULL; | 384 | lp->alloced_map = NULL; |
385 | 385 | ||
386 | free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); | 386 | free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); |
387 | atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); | 387 | atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); |
388 | } | 388 | } |
389 | 389 | ||
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 8c7d727432bb..51266d6b4d78 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -286,7 +286,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) | |||
286 | if (new == NULL) | 286 | if (new == NULL) |
287 | return NULL; | 287 | return NULL; |
288 | 288 | ||
289 | new->memory[0] = virt_to_phys(addr); | 289 | new->memory[0] = virt_to_gart(addr); |
290 | if (pg_count == 4) { | 290 | if (pg_count == 4) { |
291 | /* kludge to get 4 physical pages for ARGB cursor */ | 291 | /* kludge to get 4 physical pages for ARGB cursor */ |
292 | new->memory[1] = new->memory[0] + PAGE_SIZE; | 292 | new->memory[1] = new->memory[0] + PAGE_SIZE; |
@@ -329,10 +329,10 @@ static void intel_i810_free_by_type(struct agp_memory *curr) | |||
329 | agp_free_key(curr->key); | 329 | agp_free_key(curr->key); |
330 | if(curr->type == AGP_PHYS_MEMORY) { | 330 | if(curr->type == AGP_PHYS_MEMORY) { |
331 | if (curr->page_count == 4) | 331 | if (curr->page_count == 4) |
332 | i8xx_destroy_pages(phys_to_virt(curr->memory[0])); | 332 | i8xx_destroy_pages(gart_to_virt(curr->memory[0])); |
333 | else | 333 | else |
334 | agp_bridge->driver->agp_destroy_page( | 334 | agp_bridge->driver->agp_destroy_page( |
335 | phys_to_virt(curr->memory[0])); | 335 | gart_to_virt(curr->memory[0])); |
336 | vfree(curr->memory); | 336 | vfree(curr->memory); |
337 | } | 337 | } |
338 | kfree(curr); | 338 | kfree(curr); |
@@ -418,7 +418,8 @@ static void intel_i830_init_gtt_entries(void) | |||
418 | case I915_GMCH_GMS_STOLEN_48M: | 418 | case I915_GMCH_GMS_STOLEN_48M: |
419 | /* Check it's really I915G */ | 419 | /* Check it's really I915G */ |
420 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || | 420 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || |
421 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) | 421 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || |
422 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) | ||
422 | gtt_entries = MB(48) - KB(size); | 423 | gtt_entries = MB(48) - KB(size); |
423 | else | 424 | else |
424 | gtt_entries = 0; | 425 | gtt_entries = 0; |
@@ -426,7 +427,8 @@ static void intel_i830_init_gtt_entries(void) | |||
426 | case I915_GMCH_GMS_STOLEN_64M: | 427 | case I915_GMCH_GMS_STOLEN_64M: |
427 | /* Check it's really I915G */ | 428 | /* Check it's really I915G */ |
428 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || | 429 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || |
429 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) | 430 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || |
431 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) | ||
430 | gtt_entries = MB(64) - KB(size); | 432 | gtt_entries = MB(64) - KB(size); |
431 | else | 433 | else |
432 | gtt_entries = 0; | 434 | gtt_entries = 0; |
@@ -1662,6 +1664,14 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
1662 | } | 1664 | } |
1663 | name = "915GM"; | 1665 | name = "915GM"; |
1664 | break; | 1666 | break; |
1667 | case PCI_DEVICE_ID_INTEL_82945G_HB: | ||
1668 | if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG)) { | ||
1669 | bridge->driver = &intel_915_driver; | ||
1670 | } else { | ||
1671 | bridge->driver = &intel_845_driver; | ||
1672 | } | ||
1673 | name = "945G"; | ||
1674 | break; | ||
1665 | case PCI_DEVICE_ID_INTEL_7505_0: | 1675 | case PCI_DEVICE_ID_INTEL_7505_0: |
1666 | bridge->driver = &intel_7505_driver; | 1676 | bridge->driver = &intel_7505_driver; |
1667 | name = "E7505"; | 1677 | name = "E7505"; |
@@ -1801,6 +1811,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
1801 | ID(PCI_DEVICE_ID_INTEL_7205_0), | 1811 | ID(PCI_DEVICE_ID_INTEL_7205_0), |
1802 | ID(PCI_DEVICE_ID_INTEL_82915G_HB), | 1812 | ID(PCI_DEVICE_ID_INTEL_82915G_HB), |
1803 | ID(PCI_DEVICE_ID_INTEL_82915GM_HB), | 1813 | ID(PCI_DEVICE_ID_INTEL_82915GM_HB), |
1814 | ID(PCI_DEVICE_ID_INTEL_82945G_HB), | ||
1804 | { } | 1815 | { } |
1805 | }; | 1816 | }; |
1806 | 1817 | ||
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 4b3eda267976..d3aa159c9dec 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c | |||
@@ -133,11 +133,14 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
133 | off_t j; | 133 | off_t j; |
134 | void *temp; | 134 | void *temp; |
135 | struct agp_bridge_data *bridge; | 135 | struct agp_bridge_data *bridge; |
136 | u64 *table; | ||
136 | 137 | ||
137 | bridge = mem->bridge; | 138 | bridge = mem->bridge; |
138 | if (!bridge) | 139 | if (!bridge) |
139 | return -EINVAL; | 140 | return -EINVAL; |
140 | 141 | ||
142 | table = (u64 *)bridge->gatt_table; | ||
143 | |||
141 | temp = bridge->current_size; | 144 | temp = bridge->current_size; |
142 | 145 | ||
143 | switch (bridge->driver->size_type) { | 146 | switch (bridge->driver->size_type) { |
@@ -175,7 +178,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
175 | j = pg_start; | 178 | j = pg_start; |
176 | 179 | ||
177 | while (j < (pg_start + mem->page_count)) { | 180 | while (j < (pg_start + mem->page_count)) { |
178 | if (*(bridge->gatt_table + j)) | 181 | if (table[j]) |
179 | return -EBUSY; | 182 | return -EBUSY; |
180 | j++; | 183 | j++; |
181 | } | 184 | } |
@@ -186,7 +189,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
186 | } | 189 | } |
187 | 190 | ||
188 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 191 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
189 | *(bridge->gatt_table + j) = | 192 | table[j] = |
190 | bridge->driver->mask_memory(bridge, mem->memory[i], | 193 | bridge->driver->mask_memory(bridge, mem->memory[i], |
191 | mem->type); | 194 | mem->type); |
192 | } | 195 | } |
@@ -200,6 +203,7 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, | |||
200 | { | 203 | { |
201 | size_t i; | 204 | size_t i; |
202 | struct agp_bridge_data *bridge; | 205 | struct agp_bridge_data *bridge; |
206 | u64 *table; | ||
203 | 207 | ||
204 | bridge = mem->bridge; | 208 | bridge = mem->bridge; |
205 | if (!bridge) | 209 | if (!bridge) |
@@ -209,8 +213,10 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, | |||
209 | return -EINVAL; | 213 | return -EINVAL; |
210 | } | 214 | } |
211 | 215 | ||
216 | table = (u64 *)bridge->gatt_table; | ||
217 | |||
212 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 218 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { |
213 | *(bridge->gatt_table + i) = 0; | 219 | table[i] = 0; |
214 | } | 220 | } |
215 | 221 | ||
216 | bridge->driver->tlb_flush(mem); | 222 | bridge->driver->tlb_flush(mem); |
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 10c23302dd84..a9fb12c20eb7 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
@@ -51,7 +51,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) | |||
51 | } | 51 | } |
52 | SetPageReserved(virt_to_page(page_map->real)); | 52 | SetPageReserved(virt_to_page(page_map->real)); |
53 | global_cache_flush(); | 53 | global_cache_flush(); |
54 | page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), | 54 | page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), |
55 | PAGE_SIZE); | 55 | PAGE_SIZE); |
56 | if (page_map->remapped == NULL) { | 56 | if (page_map->remapped == NULL) { |
57 | ClearPageReserved(virt_to_page(page_map->real)); | 57 | ClearPageReserved(virt_to_page(page_map->real)); |
@@ -162,7 +162,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) | |||
162 | /* Create a fake scratch directory */ | 162 | /* Create a fake scratch directory */ |
163 | for(i = 0; i < 1024; i++) { | 163 | for(i = 0; i < 1024; i++) { |
164 | writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); | 164 | writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); |
165 | writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); | 165 | writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); |
166 | } | 166 | } |
167 | 167 | ||
168 | retval = serverworks_create_gatt_pages(value->num_entries / 1024); | 168 | retval = serverworks_create_gatt_pages(value->num_entries / 1024); |
@@ -174,7 +174,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) | |||
174 | 174 | ||
175 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; | 175 | agp_bridge->gatt_table_real = (u32 *)page_dir.real; |
176 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; | 176 | agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; |
177 | agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); | 177 | agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); |
178 | 178 | ||
179 | /* Get the address for the gart region. | 179 | /* Get the address for the gart region. |
180 | * This is a bus address even on the alpha, b/c its | 180 | * This is a bus address even on the alpha, b/c its |
@@ -187,7 +187,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) | |||
187 | /* Calculate the agp offset */ | 187 | /* Calculate the agp offset */ |
188 | 188 | ||
189 | for(i = 0; i < value->num_entries / 1024; i++) | 189 | for(i = 0; i < value->num_entries / 1024; i++) |
190 | writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); | 190 | writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); |
191 | 191 | ||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index a673971f2a90..c8255312b8c1 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
@@ -407,7 +407,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) | |||
407 | 407 | ||
408 | bridge->gatt_table_real = (u32 *) table; | 408 | bridge->gatt_table_real = (u32 *) table; |
409 | bridge->gatt_table = (u32 *)table; | 409 | bridge->gatt_table = (u32 *)table; |
410 | bridge->gatt_bus_addr = virt_to_phys(table); | 410 | bridge->gatt_bus_addr = virt_to_gart(table); |
411 | 411 | ||
412 | for (i = 0; i < num_entries; i++) | 412 | for (i = 0; i < num_entries; i++) |
413 | bridge->gatt_table[i] = 0; | 413 | bridge->gatt_table[i] = 0; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 7a245068e3e5..f022f0944434 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -1995,9 +1995,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
1995 | unsigned char ch, gdl; | 1995 | unsigned char ch, gdl; |
1996 | int ignored = 0; | 1996 | int ignored = 0; |
1997 | int cnt = 0; | 1997 | int cnt = 0; |
1998 | unsigned char *cp; | ||
1999 | char *fp; | ||
2000 | int count; | ||
2001 | int recv_room; | 1998 | int recv_room; |
2002 | int max = 256; | 1999 | int max = 256; |
2003 | unsigned long flags; | 2000 | unsigned long flags; |
@@ -2011,10 +2008,6 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
2011 | //return; | 2008 | //return; |
2012 | } | 2009 | } |
2013 | 2010 | ||
2014 | cp = tty->flip.char_buf; | ||
2015 | fp = tty->flip.flag_buf; | ||
2016 | count = 0; | ||
2017 | |||
2018 | // following add by Victor Yu. 09-02-2002 | 2011 | // following add by Victor Yu. 09-02-2002 |
2019 | if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { | 2012 | if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { |
2020 | 2013 | ||
@@ -2041,12 +2034,10 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) | |||
2041 | } | 2034 | } |
2042 | while (gdl--) { | 2035 | while (gdl--) { |
2043 | ch = inb(info->base + UART_RX); | 2036 | ch = inb(info->base + UART_RX); |
2044 | count++; | 2037 | tty_insert_flip_char(tty, ch, 0); |
2045 | *cp++ = ch; | ||
2046 | *fp++ = 0; | ||
2047 | cnt++; | 2038 | cnt++; |
2048 | /* | 2039 | /* |
2049 | if((count>=HI_WATER) && (info->stop_rx==0)){ | 2040 | if((cnt>=HI_WATER) && (info->stop_rx==0)){ |
2050 | mxser_stoprx(tty); | 2041 | mxser_stoprx(tty); |
2051 | info->stop_rx=1; | 2042 | info->stop_rx=1; |
2052 | break; | 2043 | break; |
@@ -2061,7 +2052,7 @@ intr_old: | |||
2061 | if (max-- < 0) | 2052 | if (max-- < 0) |
2062 | break; | 2053 | break; |
2063 | /* | 2054 | /* |
2064 | if((count>=HI_WATER) && (info->stop_rx==0)){ | 2055 | if((cnt>=HI_WATER) && (info->stop_rx==0)){ |
2065 | mxser_stoprx(tty); | 2056 | mxser_stoprx(tty); |
2066 | info->stop_rx=1; | 2057 | info->stop_rx=1; |
2067 | break; | 2058 | break; |
@@ -2078,36 +2069,33 @@ intr_old: | |||
2078 | if (++ignored > 100) | 2069 | if (++ignored > 100) |
2079 | break; | 2070 | break; |
2080 | } else { | 2071 | } else { |
2081 | count++; | 2072 | char flag = 0; |
2082 | if (*status & UART_LSR_SPECIAL) { | 2073 | if (*status & UART_LSR_SPECIAL) { |
2083 | if (*status & UART_LSR_BI) { | 2074 | if (*status & UART_LSR_BI) { |
2084 | *fp++ = TTY_BREAK; | 2075 | flag = TTY_BREAK; |
2085 | /* added by casper 1/11/2000 */ | 2076 | /* added by casper 1/11/2000 */ |
2086 | info->icount.brk++; | 2077 | info->icount.brk++; |
2087 | |||
2088 | /* */ | 2078 | /* */ |
2089 | if (info->flags & ASYNC_SAK) | 2079 | if (info->flags & ASYNC_SAK) |
2090 | do_SAK(tty); | 2080 | do_SAK(tty); |
2091 | } else if (*status & UART_LSR_PE) { | 2081 | } else if (*status & UART_LSR_PE) { |
2092 | *fp++ = TTY_PARITY; | 2082 | flag = TTY_PARITY; |
2093 | /* added by casper 1/11/2000 */ | 2083 | /* added by casper 1/11/2000 */ |
2094 | info->icount.parity++; | 2084 | info->icount.parity++; |
2095 | /* */ | 2085 | /* */ |
2096 | } else if (*status & UART_LSR_FE) { | 2086 | } else if (*status & UART_LSR_FE) { |
2097 | *fp++ = TTY_FRAME; | 2087 | flag = TTY_FRAME; |
2098 | /* added by casper 1/11/2000 */ | 2088 | /* added by casper 1/11/2000 */ |
2099 | info->icount.frame++; | 2089 | info->icount.frame++; |
2100 | /* */ | 2090 | /* */ |
2101 | } else if (*status & UART_LSR_OE) { | 2091 | } else if (*status & UART_LSR_OE) { |
2102 | *fp++ = TTY_OVERRUN; | 2092 | flag = TTY_OVERRUN; |
2103 | /* added by casper 1/11/2000 */ | 2093 | /* added by casper 1/11/2000 */ |
2104 | info->icount.overrun++; | 2094 | info->icount.overrun++; |
2105 | /* */ | 2095 | /* */ |
2106 | } else | 2096 | } |
2107 | *fp++ = 0; | 2097 | } |
2108 | } else | 2098 | tty_insert_flip_char(tty, ch, flag); |
2109 | *fp++ = 0; | ||
2110 | *cp++ = ch; | ||
2111 | cnt++; | 2099 | cnt++; |
2112 | if (cnt >= recv_room) { | 2100 | if (cnt >= recv_room) { |
2113 | if (!info->ldisc_stop_rx) { | 2101 | if (!info->ldisc_stop_rx) { |
@@ -2132,13 +2120,13 @@ intr_old: | |||
2132 | // above add by Victor Yu. 09-02-2002 | 2120 | // above add by Victor Yu. 09-02-2002 |
2133 | } while (*status & UART_LSR_DR); | 2121 | } while (*status & UART_LSR_DR); |
2134 | 2122 | ||
2135 | end_intr: // add by Victor Yu. 09-02-2002 | 2123 | end_intr: // add by Victor Yu. 09-02-2002 |
2136 | 2124 | ||
2137 | mxvar_log.rxcnt[info->port] += cnt; | 2125 | mxvar_log.rxcnt[info->port] += cnt; |
2138 | info->mon_data.rxcnt += cnt; | 2126 | info->mon_data.rxcnt += cnt; |
2139 | info->mon_data.up_rxcnt += cnt; | 2127 | info->mon_data.up_rxcnt += cnt; |
2140 | spin_unlock_irqrestore(&info->slock, flags); | 2128 | spin_unlock_irqrestore(&info->slock, flags); |
2141 | 2129 | ||
2142 | tty_flip_buffer_push(tty); | 2130 | tty_flip_buffer_push(tty); |
2143 | } | 2131 | } |
2144 | 2132 | ||
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index af0446c6de82..48fdf1e517cf 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -54,7 +54,7 @@ static int atkbd_softraw = 1; | |||
54 | module_param_named(softraw, atkbd_softraw, bool, 0); | 54 | module_param_named(softraw, atkbd_softraw, bool, 0); |
55 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); | 55 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); |
56 | 56 | ||
57 | static int atkbd_scroll = 1; | 57 | static int atkbd_scroll = 0; |
58 | module_param_named(scroll, atkbd_scroll, bool, 0); | 58 | module_param_named(scroll, atkbd_scroll, bool, 0); |
59 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); | 59 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); |
60 | 60 | ||
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 1e97b3c12bd5..0c1b8520ef86 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -985,6 +985,9 @@ static int do_end_io(struct multipath *m, struct bio *bio, | |||
985 | if (!error) | 985 | if (!error) |
986 | return 0; /* I/O complete */ | 986 | return 0; /* I/O complete */ |
987 | 987 | ||
988 | if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) | ||
989 | return error; | ||
990 | |||
988 | spin_lock(&m->lock); | 991 | spin_lock(&m->lock); |
989 | if (!m->nr_valid_paths) { | 992 | if (!m->nr_valid_paths) { |
990 | if (!m->queue_if_no_path || m->suspended) { | 993 | if (!m->queue_if_no_path || m->suspended) { |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index fc9b5cd957aa..a0b8848049c9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -7,7 +7,12 @@ | |||
7 | * Copyright (C) 2005 Broadcom Corporation. | 7 | * Copyright (C) 2005 Broadcom Corporation. |
8 | * | 8 | * |
9 | * Firmware is: | 9 | * Firmware is: |
10 | * Copyright (C) 2000-2003 Broadcom Corporation. | 10 | * Derived from proprietary unpublished source code, |
11 | * Copyright (C) 2000-2003 Broadcom Corporation. | ||
12 | * | ||
13 | * Permission is hereby granted for the distribution of this firmware | ||
14 | * data in hexadecimal or equivalent format, provided this copyright | ||
15 | * notice is accompanying it. | ||
11 | */ | 16 | */ |
12 | 17 | ||
13 | #include <linux/config.h> | 18 | #include <linux/config.h> |
@@ -61,8 +66,8 @@ | |||
61 | 66 | ||
62 | #define DRV_MODULE_NAME "tg3" | 67 | #define DRV_MODULE_NAME "tg3" |
63 | #define PFX DRV_MODULE_NAME ": " | 68 | #define PFX DRV_MODULE_NAME ": " |
64 | #define DRV_MODULE_VERSION "3.29" | 69 | #define DRV_MODULE_VERSION "3.31" |
65 | #define DRV_MODULE_RELDATE "May 23, 2005" | 70 | #define DRV_MODULE_RELDATE "June 8, 2005" |
66 | 71 | ||
67 | #define TG3_DEF_MAC_MODE 0 | 72 | #define TG3_DEF_MAC_MODE 0 |
68 | #define TG3_DEF_RX_MODE 0 | 73 | #define TG3_DEF_RX_MODE 0 |
@@ -8555,6 +8560,16 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
8555 | 8560 | ||
8556 | case NIC_SRAM_DATA_CFG_LED_MODE_MAC: | 8561 | case NIC_SRAM_DATA_CFG_LED_MODE_MAC: |
8557 | tp->led_ctrl = LED_CTRL_MODE_MAC; | 8562 | tp->led_ctrl = LED_CTRL_MODE_MAC; |
8563 | |||
8564 | /* Default to PHY_1_MODE if 0 (MAC_MODE) is | ||
8565 | * read on some older 5700/5701 bootcode. | ||
8566 | */ | ||
8567 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == | ||
8568 | ASIC_REV_5700 || | ||
8569 | GET_ASIC_REV(tp->pci_chip_rev_id) == | ||
8570 | ASIC_REV_5701) | ||
8571 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; | ||
8572 | |||
8558 | break; | 8573 | break; |
8559 | 8574 | ||
8560 | case SHASTA_EXT_LED_SHARED: | 8575 | case SHASTA_EXT_LED_SHARED: |
@@ -9680,10 +9695,24 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
9680 | } | 9695 | } |
9681 | if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != | 9696 | if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != |
9682 | DMA_RWCTRL_WRITE_BNDRY_16) { | 9697 | DMA_RWCTRL_WRITE_BNDRY_16) { |
9698 | static struct pci_device_id dma_wait_state_chipsets[] = { | ||
9699 | { PCI_DEVICE(PCI_VENDOR_ID_APPLE, | ||
9700 | PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, | ||
9701 | { }, | ||
9702 | }; | ||
9703 | |||
9683 | /* DMA test passed without adjusting DMA boundary, | 9704 | /* DMA test passed without adjusting DMA boundary, |
9684 | * just restore the calculated DMA boundary | 9705 | * now look for chipsets that are known to expose the |
9706 | * DMA bug without failing the test. | ||
9685 | */ | 9707 | */ |
9686 | tp->dma_rwctrl = saved_dma_rwctrl; | 9708 | if (pci_dev_present(dma_wait_state_chipsets)) { |
9709 | tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; | ||
9710 | tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; | ||
9711 | } | ||
9712 | else | ||
9713 | /* Safe to use the calculated DMA boundary. */ | ||
9714 | tp->dma_rwctrl = saved_dma_rwctrl; | ||
9715 | |||
9687 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); | 9716 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); |
9688 | } | 9717 | } |
9689 | 9718 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 8132d946c384..30af105271a2 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -217,6 +217,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
217 | kfree(slot->hotplug_slot->info); | 217 | kfree(slot->hotplug_slot->info); |
218 | kfree(slot->hotplug_slot->name); | 218 | kfree(slot->hotplug_slot->name); |
219 | kfree(slot->hotplug_slot); | 219 | kfree(slot->hotplug_slot); |
220 | if (slot->dev) | ||
221 | pci_dev_put(slot->dev); | ||
220 | kfree(slot); | 222 | kfree(slot); |
221 | } | 223 | } |
222 | 224 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index c878028ad215..225b5e551dd6 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -315,9 +315,12 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
315 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 315 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
316 | if (dev) { | 316 | if (dev) { |
317 | pci_remove_bus_device(dev); | 317 | pci_remove_bus_device(dev); |
318 | slot->dev = NULL; | 318 | pci_dev_put(dev); |
319 | } | 319 | } |
320 | } | 320 | } |
321 | pci_dev_put(slot->dev); | ||
322 | slot->dev = NULL; | ||
323 | |||
321 | dbg("%s - exit", __FUNCTION__); | 324 | dbg("%s - exit", __FUNCTION__); |
322 | return 0; | 325 | return 0; |
323 | } | 326 | } |
diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index 93481b41b613..1d2ef1e2ffc6 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids | |||
@@ -7173,6 +7173,7 @@ | |||
7173 | 080f Sentry5 DDR/SDR RAM Controller | 7173 | 080f Sentry5 DDR/SDR RAM Controller |
7174 | 0811 Sentry5 External Interface Core | 7174 | 0811 Sentry5 External Interface Core |
7175 | 0816 BCM3302 Sentry5 MIPS32 CPU | 7175 | 0816 BCM3302 Sentry5 MIPS32 CPU |
7176 | 1600 NetXtreme BCM5752 Gigabit Ethernet PCI Express | ||
7176 | 1644 NetXtreme BCM5700 Gigabit Ethernet | 7177 | 1644 NetXtreme BCM5700 Gigabit Ethernet |
7177 | 1014 0277 Broadcom Vigil B5700 1000Base-T | 7178 | 1014 0277 Broadcom Vigil B5700 1000Base-T |
7178 | 1028 00d1 Broadcom BCM5700 | 7179 | 1028 00d1 Broadcom BCM5700 |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 637e9493034b..2194669300bf 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -460,17 +460,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, | |||
460 | 460 | ||
461 | 461 | ||
462 | /* | 462 | /* |
463 | * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip | ||
464 | * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: | ||
465 | * when written, it makes an internal connection to the PIC. | ||
466 | * For these devices, this register is defined to be 4 bits wide. | ||
467 | * Normally this is fine. However for IO-APIC motherboards, or | ||
468 | * non-x86 architectures (yes Via exists on PPC among other places), | ||
469 | * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get | ||
470 | * interrupts delivered properly. | ||
471 | */ | ||
472 | |||
473 | /* | ||
474 | * FIXME: it is questionable that quirk_via_acpi | 463 | * FIXME: it is questionable that quirk_via_acpi |
475 | * is needed. It shows up as an ISA bridge, and does not | 464 | * is needed. It shows up as an ISA bridge, and does not |
476 | * support the PCI_INTERRUPT_LINE register at all. Therefore | 465 | * support the PCI_INTERRUPT_LINE register at all. Therefore |
@@ -492,28 +481,30 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) | |||
492 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); | 481 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); |
493 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); | 482 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); |
494 | 483 | ||
495 | static void quirk_via_irqpic(struct pci_dev *dev) | 484 | /* |
485 | * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip | ||
486 | * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: | ||
487 | * when written, it makes an internal connection to the PIC. | ||
488 | * For these devices, this register is defined to be 4 bits wide. | ||
489 | * Normally this is fine. However for IO-APIC motherboards, or | ||
490 | * non-x86 architectures (yes Via exists on PPC among other places), | ||
491 | * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get | ||
492 | * interrupts delivered properly. | ||
493 | */ | ||
494 | static void quirk_via_irq(struct pci_dev *dev) | ||
496 | { | 495 | { |
497 | u8 irq, new_irq; | 496 | u8 irq, new_irq; |
498 | 497 | ||
499 | #ifdef CONFIG_X86_IO_APIC | ||
500 | if (nr_ioapics && !skip_ioapic_setup) | ||
501 | return; | ||
502 | #endif | ||
503 | #ifdef CONFIG_ACPI | ||
504 | if (acpi_irq_model != ACPI_IRQ_MODEL_PIC) | ||
505 | return; | ||
506 | #endif | ||
507 | new_irq = dev->irq & 0xf; | 498 | new_irq = dev->irq & 0xf; |
508 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 499 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
509 | if (new_irq != irq) { | 500 | if (new_irq != irq) { |
510 | printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n", | 501 | printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n", |
511 | pci_name(dev), irq, new_irq); | 502 | pci_name(dev), irq, new_irq); |
512 | udelay(15); /* unknown if delay really needed */ | 503 | udelay(15); /* unknown if delay really needed */ |
513 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); | 504 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); |
514 | } | 505 | } |
515 | } | 506 | } |
516 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic); | 507 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); |
517 | 508 | ||
518 | /* | 509 | /* |
519 | * PIIX3 USB: We have to disable USB interrupts that are | 510 | * PIIX3 USB: We have to disable USB interrupts that are |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 21d194c6ace3..9e58f134f68b 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -2577,7 +2577,6 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) | |||
2577 | next_sg: | 2577 | next_sg: |
2578 | sg = &qc->sg[qc->cursg]; | 2578 | sg = &qc->sg[qc->cursg]; |
2579 | 2579 | ||
2580 | next_page: | ||
2581 | page = sg->page; | 2580 | page = sg->page; |
2582 | offset = sg->offset + qc->cursg_ofs; | 2581 | offset = sg->offset + qc->cursg_ofs; |
2583 | 2582 | ||
@@ -2585,6 +2584,7 @@ next_page: | |||
2585 | page = nth_page(page, (offset >> PAGE_SHIFT)); | 2584 | page = nth_page(page, (offset >> PAGE_SHIFT)); |
2586 | offset %= PAGE_SIZE; | 2585 | offset %= PAGE_SIZE; |
2587 | 2586 | ||
2587 | /* don't overrun current sg */ | ||
2588 | count = min(sg->length - qc->cursg_ofs, bytes); | 2588 | count = min(sg->length - qc->cursg_ofs, bytes); |
2589 | 2589 | ||
2590 | /* don't cross page boundaries */ | 2590 | /* don't cross page boundaries */ |
@@ -2609,8 +2609,6 @@ next_page: | |||
2609 | kunmap(page); | 2609 | kunmap(page); |
2610 | 2610 | ||
2611 | if (bytes) { | 2611 | if (bytes) { |
2612 | if (qc->cursg_ofs < sg->length) | ||
2613 | goto next_page; | ||
2614 | goto next_sg; | 2612 | goto next_sg; |
2615 | } | 2613 | } |
2616 | } | 2614 | } |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 238580d244e6..49ed557a4b66 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -432,7 +432,13 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
432 | writeb(cls, mmio_base + SIL_FIFO_R0); | 432 | writeb(cls, mmio_base + SIL_FIFO_R0); |
433 | writeb(cls, mmio_base + SIL_FIFO_W0); | 433 | writeb(cls, mmio_base + SIL_FIFO_W0); |
434 | writeb(cls, mmio_base + SIL_FIFO_R1); | 434 | writeb(cls, mmio_base + SIL_FIFO_R1); |
435 | writeb(cls, mmio_base + SIL_FIFO_W2); | 435 | writeb(cls, mmio_base + SIL_FIFO_W1); |
436 | if (ent->driver_data == sil_3114) { | ||
437 | writeb(cls, mmio_base + SIL_FIFO_R2); | ||
438 | writeb(cls, mmio_base + SIL_FIFO_W2); | ||
439 | writeb(cls, mmio_base + SIL_FIFO_R3); | ||
440 | writeb(cls, mmio_base + SIL_FIFO_W3); | ||
441 | } | ||
436 | } else | 442 | } else |
437 | printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n", | 443 | printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n", |
438 | pci_name(pdev)); | 444 | pci_name(pdev)); |
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 22565a67a57c..98641c3f5ab9 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -197,7 +197,7 @@ static void | |||
197 | sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) | 197 | sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) |
198 | { | 198 | { |
199 | struct tty_struct *tty = sport->port.info->tty; | 199 | struct tty_struct *tty = sport->port.info->tty; |
200 | unsigned int status, ch, flg, ignored = 0; | 200 | unsigned int status, ch, flg; |
201 | 201 | ||
202 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 202 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
203 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); | 203 | UTSR0_TO_SM(UART_GET_UTSR0(sport)); |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 051c3a77b41b..3bfcc7b9f861 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -264,7 +264,7 @@ | |||
264 | /* | 264 | /* |
265 | * Version Information | 265 | * Version Information |
266 | */ | 266 | */ |
267 | #define DRIVER_VERSION "v1.4.1" | 267 | #define DRIVER_VERSION "v1.4.2" |
268 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" | 268 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" |
269 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" | 269 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" |
270 | 270 | ||
@@ -687,6 +687,8 @@ struct ftdi_private { | |||
687 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | 687 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ |
688 | __u8 rx_flags; /* receive state flags (throttling) */ | 688 | __u8 rx_flags; /* receive state flags (throttling) */ |
689 | spinlock_t rx_lock; /* spinlock for receive state */ | 689 | spinlock_t rx_lock; /* spinlock for receive state */ |
690 | struct work_struct rx_work; | ||
691 | int rx_processed; | ||
690 | 692 | ||
691 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ | 693 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ |
692 | 694 | ||
@@ -717,7 +719,7 @@ static int ftdi_write_room (struct usb_serial_port *port); | |||
717 | static int ftdi_chars_in_buffer (struct usb_serial_port *port); | 719 | static int ftdi_chars_in_buffer (struct usb_serial_port *port); |
718 | static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs); | 720 | static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs); |
719 | static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs); | 721 | static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs); |
720 | static void ftdi_process_read (struct usb_serial_port *port); | 722 | static void ftdi_process_read (void *param); |
721 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); | 723 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); |
722 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); | 724 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); |
723 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); | 725 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); |
@@ -1387,6 +1389,8 @@ static int ftdi_common_startup (struct usb_serial *serial) | |||
1387 | port->read_urb->transfer_buffer_length = BUFSZ; | 1389 | port->read_urb->transfer_buffer_length = BUFSZ; |
1388 | } | 1390 | } |
1389 | 1391 | ||
1392 | INIT_WORK(&priv->rx_work, ftdi_process_read, port); | ||
1393 | |||
1390 | /* Free port's existing write urb and transfer buffer. */ | 1394 | /* Free port's existing write urb and transfer buffer. */ |
1391 | if (port->write_urb) { | 1395 | if (port->write_urb) { |
1392 | usb_free_urb (port->write_urb); | 1396 | usb_free_urb (port->write_urb); |
@@ -1617,6 +1621,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) | |||
1617 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1621 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
1618 | 1622 | ||
1619 | /* Start reading from the device */ | 1623 | /* Start reading from the device */ |
1624 | priv->rx_processed = 0; | ||
1620 | usb_fill_bulk_urb(port->read_urb, dev, | 1625 | usb_fill_bulk_urb(port->read_urb, dev, |
1621 | usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), | 1626 | usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), |
1622 | port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, | 1627 | port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, |
@@ -1667,6 +1672,10 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) | |||
1667 | err("Error from RTS LOW urb"); | 1672 | err("Error from RTS LOW urb"); |
1668 | } | 1673 | } |
1669 | } /* Note change no line if hupcl is off */ | 1674 | } /* Note change no line if hupcl is off */ |
1675 | |||
1676 | /* cancel any scheduled reading */ | ||
1677 | cancel_delayed_work(&priv->rx_work); | ||
1678 | flush_scheduled_work(); | ||
1670 | 1679 | ||
1671 | /* shutdown our bulk read */ | 1680 | /* shutdown our bulk read */ |
1672 | if (port->read_urb) | 1681 | if (port->read_urb) |
@@ -1862,23 +1871,14 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
1862 | return; | 1871 | return; |
1863 | } | 1872 | } |
1864 | 1873 | ||
1865 | /* If throttled, delay receive processing until unthrottled. */ | ||
1866 | spin_lock(&priv->rx_lock); | ||
1867 | if (priv->rx_flags & THROTTLED) { | ||
1868 | dbg("Deferring read urb processing until unthrottled"); | ||
1869 | priv->rx_flags |= ACTUALLY_THROTTLED; | ||
1870 | spin_unlock(&priv->rx_lock); | ||
1871 | return; | ||
1872 | } | ||
1873 | spin_unlock(&priv->rx_lock); | ||
1874 | |||
1875 | ftdi_process_read(port); | 1874 | ftdi_process_read(port); |
1876 | 1875 | ||
1877 | } /* ftdi_read_bulk_callback */ | 1876 | } /* ftdi_read_bulk_callback */ |
1878 | 1877 | ||
1879 | 1878 | ||
1880 | static void ftdi_process_read (struct usb_serial_port *port) | 1879 | static void ftdi_process_read (void *param) |
1881 | { /* ftdi_process_read */ | 1880 | { /* ftdi_process_read */ |
1881 | struct usb_serial_port *port = (struct usb_serial_port*)param; | ||
1882 | struct urb *urb; | 1882 | struct urb *urb; |
1883 | struct tty_struct *tty; | 1883 | struct tty_struct *tty; |
1884 | struct ftdi_private *priv; | 1884 | struct ftdi_private *priv; |
@@ -1889,6 +1889,7 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1889 | int result; | 1889 | int result; |
1890 | int need_flip; | 1890 | int need_flip; |
1891 | int packet_offset; | 1891 | int packet_offset; |
1892 | unsigned long flags; | ||
1892 | 1893 | ||
1893 | dbg("%s - port %d", __FUNCTION__, port->number); | 1894 | dbg("%s - port %d", __FUNCTION__, port->number); |
1894 | 1895 | ||
@@ -1915,12 +1916,18 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1915 | 1916 | ||
1916 | data = urb->transfer_buffer; | 1917 | data = urb->transfer_buffer; |
1917 | 1918 | ||
1918 | /* The first two bytes of every read packet are status */ | 1919 | if (priv->rx_processed) { |
1919 | if (urb->actual_length > 2) { | 1920 | dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__, |
1920 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); | 1921 | priv->rx_processed, |
1922 | urb->actual_length - priv->rx_processed); | ||
1921 | } else { | 1923 | } else { |
1922 | dbg("Status only: %03oo %03oo",data[0],data[1]); | 1924 | /* The first two bytes of every read packet are status */ |
1923 | } | 1925 | if (urb->actual_length > 2) { |
1926 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); | ||
1927 | } else { | ||
1928 | dbg("Status only: %03oo %03oo",data[0],data[1]); | ||
1929 | } | ||
1930 | } | ||
1924 | 1931 | ||
1925 | 1932 | ||
1926 | /* TO DO -- check for hung up line and handle appropriately: */ | 1933 | /* TO DO -- check for hung up line and handle appropriately: */ |
@@ -1929,8 +1936,12 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1929 | /* if CD is dropped and the line is not CLOCAL then we should hangup */ | 1936 | /* if CD is dropped and the line is not CLOCAL then we should hangup */ |
1930 | 1937 | ||
1931 | need_flip = 0; | 1938 | need_flip = 0; |
1932 | for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) { | 1939 | for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) { |
1940 | int length; | ||
1941 | |||
1933 | /* Compare new line status to the old one, signal if different */ | 1942 | /* Compare new line status to the old one, signal if different */ |
1943 | /* N.B. packet may be processed more than once, but differences | ||
1944 | * are only processed once. */ | ||
1934 | if (priv != NULL) { | 1945 | if (priv != NULL) { |
1935 | char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK; | 1946 | char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK; |
1936 | if (new_status != priv->prev_status) { | 1947 | if (new_status != priv->prev_status) { |
@@ -1940,6 +1951,35 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1940 | } | 1951 | } |
1941 | } | 1952 | } |
1942 | 1953 | ||
1954 | length = min(PKTSZ, urb->actual_length-packet_offset)-2; | ||
1955 | if (length < 0) { | ||
1956 | err("%s - bad packet length: %d", __FUNCTION__, length+2); | ||
1957 | length = 0; | ||
1958 | } | ||
1959 | |||
1960 | /* have to make sure we don't overflow the buffer | ||
1961 | with tty_insert_flip_char's */ | ||
1962 | if (tty->flip.count+length > TTY_FLIPBUF_SIZE) { | ||
1963 | tty_flip_buffer_push(tty); | ||
1964 | need_flip = 0; | ||
1965 | |||
1966 | if (tty->flip.count != 0) { | ||
1967 | /* flip didn't work, this happens when ftdi_process_read() is | ||
1968 | * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */ | ||
1969 | dbg("%s - flip buffer push failed", __FUNCTION__); | ||
1970 | break; | ||
1971 | } | ||
1972 | } | ||
1973 | if (priv->rx_flags & THROTTLED) { | ||
1974 | dbg("%s - throttled", __FUNCTION__); | ||
1975 | break; | ||
1976 | } | ||
1977 | if (tty->ldisc.receive_room(tty)-tty->flip.count < length) { | ||
1978 | /* break out & wait for throttling/unthrottling to happen */ | ||
1979 | dbg("%s - receive room low", __FUNCTION__); | ||
1980 | break; | ||
1981 | } | ||
1982 | |||
1943 | /* Handle errors and break */ | 1983 | /* Handle errors and break */ |
1944 | error_flag = TTY_NORMAL; | 1984 | error_flag = TTY_NORMAL; |
1945 | /* Although the device uses a bitmask and hence can have multiple */ | 1985 | /* Although the device uses a bitmask and hence can have multiple */ |
@@ -1962,13 +2002,8 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1962 | error_flag = TTY_FRAME; | 2002 | error_flag = TTY_FRAME; |
1963 | dbg("FRAMING error"); | 2003 | dbg("FRAMING error"); |
1964 | } | 2004 | } |
1965 | if (urb->actual_length > packet_offset + 2) { | 2005 | if (length > 0) { |
1966 | for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) { | 2006 | for (i = 2; i < length+2; i++) { |
1967 | /* have to make sure we don't overflow the buffer | ||
1968 | with tty_insert_flip_char's */ | ||
1969 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
1970 | tty_flip_buffer_push(tty); | ||
1971 | } | ||
1972 | /* Note that the error flag is duplicated for | 2007 | /* Note that the error flag is duplicated for |
1973 | every character received since we don't know | 2008 | every character received since we don't know |
1974 | which character it applied to */ | 2009 | which character it applied to */ |
@@ -2005,6 +2040,35 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
2005 | tty_flip_buffer_push(tty); | 2040 | tty_flip_buffer_push(tty); |
2006 | } | 2041 | } |
2007 | 2042 | ||
2043 | if (packet_offset < urb->actual_length) { | ||
2044 | /* not completely processed - record progress */ | ||
2045 | priv->rx_processed = packet_offset; | ||
2046 | dbg("%s - incomplete, %d bytes processed, %d remain", | ||
2047 | __FUNCTION__, packet_offset, | ||
2048 | urb->actual_length - packet_offset); | ||
2049 | /* check if we were throttled while processing */ | ||
2050 | spin_lock_irqsave(&priv->rx_lock, flags); | ||
2051 | if (priv->rx_flags & THROTTLED) { | ||
2052 | priv->rx_flags |= ACTUALLY_THROTTLED; | ||
2053 | spin_unlock_irqrestore(&priv->rx_lock, flags); | ||
2054 | dbg("%s - deferring remainder until unthrottled", | ||
2055 | __FUNCTION__); | ||
2056 | return; | ||
2057 | } | ||
2058 | spin_unlock_irqrestore(&priv->rx_lock, flags); | ||
2059 | /* if the port is closed stop trying to read */ | ||
2060 | if (port->open_count > 0){ | ||
2061 | /* delay processing of remainder */ | ||
2062 | schedule_delayed_work(&priv->rx_work, 1); | ||
2063 | } else { | ||
2064 | dbg("%s - port is closed", __FUNCTION__); | ||
2065 | } | ||
2066 | return; | ||
2067 | } | ||
2068 | |||
2069 | /* urb is completely processed */ | ||
2070 | priv->rx_processed = 0; | ||
2071 | |||
2008 | /* if the port is closed stop trying to read */ | 2072 | /* if the port is closed stop trying to read */ |
2009 | if (port->open_count > 0){ | 2073 | if (port->open_count > 0){ |
2010 | /* Continue trying to always read */ | 2074 | /* Continue trying to always read */ |
@@ -2444,7 +2508,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port) | |||
2444 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 2508 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
2445 | 2509 | ||
2446 | if (actually_throttled) | 2510 | if (actually_throttled) |
2447 | ftdi_process_read(port); | 2511 | schedule_work(&priv->rx_work); |
2448 | } | 2512 | } |
2449 | 2513 | ||
2450 | static int __init ftdi_init (void) | 2514 | static int __init ftdi_init (void) |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index f0cd67d9d31b..c8998dc66882 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -520,7 +520,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
520 | DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); | 520 | DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); |
521 | 521 | ||
522 | down_write(¤t->mm->mmap_sem); | 522 | down_write(¤t->mm->mmap_sem); |
523 | textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0); | 523 | textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0); |
524 | up_write(¤t->mm->mmap_sem); | 524 | up_write(¤t->mm->mmap_sem); |
525 | if (!textpos || textpos >= (unsigned long) -4096) { | 525 | if (!textpos || textpos >= (unsigned long) -4096) { |
526 | if (!textpos) | 526 | if (!textpos) |
@@ -532,7 +532,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
532 | down_write(¤t->mm->mmap_sem); | 532 | down_write(¤t->mm->mmap_sem); |
533 | realdatastart = do_mmap(0, 0, data_len + extra + | 533 | realdatastart = do_mmap(0, 0, data_len + extra + |
534 | MAX_SHARED_LIBS * sizeof(unsigned long), | 534 | MAX_SHARED_LIBS * sizeof(unsigned long), |
535 | PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0); | 535 | PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); |
536 | up_write(¤t->mm->mmap_sem); | 536 | up_write(¤t->mm->mmap_sem); |
537 | 537 | ||
538 | if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { | 538 | if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { |
@@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
574 | down_write(¤t->mm->mmap_sem); | 574 | down_write(¤t->mm->mmap_sem); |
575 | textpos = do_mmap(0, 0, text_len + data_len + extra + | 575 | textpos = do_mmap(0, 0, text_len + data_len + extra + |
576 | MAX_SHARED_LIBS * sizeof(unsigned long), | 576 | MAX_SHARED_LIBS * sizeof(unsigned long), |
577 | PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0); | 577 | PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); |
578 | up_write(¤t->mm->mmap_sem); | 578 | up_write(¤t->mm->mmap_sem); |
579 | if (!textpos || textpos >= (unsigned long) -4096) { | 579 | if (!textpos || textpos >= (unsigned long) -4096) { |
580 | if (!textpos) | 580 | if (!textpos) |
diff --git a/fs/namei.c b/fs/namei.c index dd78f01b6de8..a7f7f44119b3 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -493,12 +493,21 @@ fail: | |||
493 | return PTR_ERR(link); | 493 | return PTR_ERR(link); |
494 | } | 494 | } |
495 | 495 | ||
496 | static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) | 496 | struct path { |
497 | struct vfsmount *mnt; | ||
498 | struct dentry *dentry; | ||
499 | }; | ||
500 | |||
501 | static inline int __do_follow_link(struct path *path, struct nameidata *nd) | ||
497 | { | 502 | { |
498 | int error; | 503 | int error; |
504 | struct dentry *dentry = path->dentry; | ||
499 | 505 | ||
500 | touch_atime(nd->mnt, dentry); | 506 | touch_atime(path->mnt, dentry); |
501 | nd_set_link(nd, NULL); | 507 | nd_set_link(nd, NULL); |
508 | |||
509 | if (path->mnt == nd->mnt) | ||
510 | mntget(path->mnt); | ||
502 | error = dentry->d_inode->i_op->follow_link(dentry, nd); | 511 | error = dentry->d_inode->i_op->follow_link(dentry, nd); |
503 | if (!error) { | 512 | if (!error) { |
504 | char *s = nd_get_link(nd); | 513 | char *s = nd_get_link(nd); |
@@ -507,6 +516,8 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
507 | if (dentry->d_inode->i_op->put_link) | 516 | if (dentry->d_inode->i_op->put_link) |
508 | dentry->d_inode->i_op->put_link(dentry, nd); | 517 | dentry->d_inode->i_op->put_link(dentry, nd); |
509 | } | 518 | } |
519 | dput(dentry); | ||
520 | mntput(path->mnt); | ||
510 | 521 | ||
511 | return error; | 522 | return error; |
512 | } | 523 | } |
@@ -518,7 +529,7 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
518 | * Without that kind of total limit, nasty chains of consecutive | 529 | * Without that kind of total limit, nasty chains of consecutive |
519 | * symlinks can cause almost arbitrarily long lookups. | 530 | * symlinks can cause almost arbitrarily long lookups. |
520 | */ | 531 | */ |
521 | static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) | 532 | static inline int do_follow_link(struct path *path, struct nameidata *nd) |
522 | { | 533 | { |
523 | int err = -ELOOP; | 534 | int err = -ELOOP; |
524 | if (current->link_count >= MAX_NESTED_LINKS) | 535 | if (current->link_count >= MAX_NESTED_LINKS) |
@@ -527,17 +538,20 @@ static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
527 | goto loop; | 538 | goto loop; |
528 | BUG_ON(nd->depth >= MAX_NESTED_LINKS); | 539 | BUG_ON(nd->depth >= MAX_NESTED_LINKS); |
529 | cond_resched(); | 540 | cond_resched(); |
530 | err = security_inode_follow_link(dentry, nd); | 541 | err = security_inode_follow_link(path->dentry, nd); |
531 | if (err) | 542 | if (err) |
532 | goto loop; | 543 | goto loop; |
533 | current->link_count++; | 544 | current->link_count++; |
534 | current->total_link_count++; | 545 | current->total_link_count++; |
535 | nd->depth++; | 546 | nd->depth++; |
536 | err = __do_follow_link(dentry, nd); | 547 | err = __do_follow_link(path, nd); |
537 | current->link_count--; | 548 | current->link_count--; |
538 | nd->depth--; | 549 | nd->depth--; |
539 | return err; | 550 | return err; |
540 | loop: | 551 | loop: |
552 | dput(path->dentry); | ||
553 | if (path->mnt != nd->mnt) | ||
554 | mntput(path->mnt); | ||
541 | path_release(nd); | 555 | path_release(nd); |
542 | return err; | 556 | return err; |
543 | } | 557 | } |
@@ -565,87 +579,91 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry) | |||
565 | /* no need for dcache_lock, as serialization is taken care in | 579 | /* no need for dcache_lock, as serialization is taken care in |
566 | * namespace.c | 580 | * namespace.c |
567 | */ | 581 | */ |
568 | static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) | 582 | static int __follow_mount(struct path *path) |
569 | { | 583 | { |
570 | int res = 0; | 584 | int res = 0; |
585 | while (d_mountpoint(path->dentry)) { | ||
586 | struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry); | ||
587 | if (!mounted) | ||
588 | break; | ||
589 | dput(path->dentry); | ||
590 | if (res) | ||
591 | mntput(path->mnt); | ||
592 | path->mnt = mounted; | ||
593 | path->dentry = dget(mounted->mnt_root); | ||
594 | res = 1; | ||
595 | } | ||
596 | return res; | ||
597 | } | ||
598 | |||
599 | static void follow_mount(struct vfsmount **mnt, struct dentry **dentry) | ||
600 | { | ||
571 | while (d_mountpoint(*dentry)) { | 601 | while (d_mountpoint(*dentry)) { |
572 | struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); | 602 | struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); |
573 | if (!mounted) | 603 | if (!mounted) |
574 | break; | 604 | break; |
605 | dput(*dentry); | ||
575 | mntput(*mnt); | 606 | mntput(*mnt); |
576 | *mnt = mounted; | 607 | *mnt = mounted; |
577 | dput(*dentry); | ||
578 | *dentry = dget(mounted->mnt_root); | 608 | *dentry = dget(mounted->mnt_root); |
579 | res = 1; | ||
580 | } | 609 | } |
581 | return res; | ||
582 | } | 610 | } |
583 | 611 | ||
584 | /* no need for dcache_lock, as serialization is taken care in | 612 | /* no need for dcache_lock, as serialization is taken care in |
585 | * namespace.c | 613 | * namespace.c |
586 | */ | 614 | */ |
587 | static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) | 615 | int follow_down(struct vfsmount **mnt, struct dentry **dentry) |
588 | { | 616 | { |
589 | struct vfsmount *mounted; | 617 | struct vfsmount *mounted; |
590 | 618 | ||
591 | mounted = lookup_mnt(*mnt, *dentry); | 619 | mounted = lookup_mnt(*mnt, *dentry); |
592 | if (mounted) { | 620 | if (mounted) { |
621 | dput(*dentry); | ||
593 | mntput(*mnt); | 622 | mntput(*mnt); |
594 | *mnt = mounted; | 623 | *mnt = mounted; |
595 | dput(*dentry); | ||
596 | *dentry = dget(mounted->mnt_root); | 624 | *dentry = dget(mounted->mnt_root); |
597 | return 1; | 625 | return 1; |
598 | } | 626 | } |
599 | return 0; | 627 | return 0; |
600 | } | 628 | } |
601 | 629 | ||
602 | int follow_down(struct vfsmount **mnt, struct dentry **dentry) | 630 | static inline void follow_dotdot(struct nameidata *nd) |
603 | { | ||
604 | return __follow_down(mnt,dentry); | ||
605 | } | ||
606 | |||
607 | static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry) | ||
608 | { | 631 | { |
609 | while(1) { | 632 | while(1) { |
610 | struct vfsmount *parent; | 633 | struct vfsmount *parent; |
611 | struct dentry *old = *dentry; | 634 | struct dentry *old = nd->dentry; |
612 | 635 | ||
613 | read_lock(¤t->fs->lock); | 636 | read_lock(¤t->fs->lock); |
614 | if (*dentry == current->fs->root && | 637 | if (nd->dentry == current->fs->root && |
615 | *mnt == current->fs->rootmnt) { | 638 | nd->mnt == current->fs->rootmnt) { |
616 | read_unlock(¤t->fs->lock); | 639 | read_unlock(¤t->fs->lock); |
617 | break; | 640 | break; |
618 | } | 641 | } |
619 | read_unlock(¤t->fs->lock); | 642 | read_unlock(¤t->fs->lock); |
620 | spin_lock(&dcache_lock); | 643 | spin_lock(&dcache_lock); |
621 | if (*dentry != (*mnt)->mnt_root) { | 644 | if (nd->dentry != nd->mnt->mnt_root) { |
622 | *dentry = dget((*dentry)->d_parent); | 645 | nd->dentry = dget(nd->dentry->d_parent); |
623 | spin_unlock(&dcache_lock); | 646 | spin_unlock(&dcache_lock); |
624 | dput(old); | 647 | dput(old); |
625 | break; | 648 | break; |
626 | } | 649 | } |
627 | spin_unlock(&dcache_lock); | 650 | spin_unlock(&dcache_lock); |
628 | spin_lock(&vfsmount_lock); | 651 | spin_lock(&vfsmount_lock); |
629 | parent = (*mnt)->mnt_parent; | 652 | parent = nd->mnt->mnt_parent; |
630 | if (parent == *mnt) { | 653 | if (parent == nd->mnt) { |
631 | spin_unlock(&vfsmount_lock); | 654 | spin_unlock(&vfsmount_lock); |
632 | break; | 655 | break; |
633 | } | 656 | } |
634 | mntget(parent); | 657 | mntget(parent); |
635 | *dentry = dget((*mnt)->mnt_mountpoint); | 658 | nd->dentry = dget(nd->mnt->mnt_mountpoint); |
636 | spin_unlock(&vfsmount_lock); | 659 | spin_unlock(&vfsmount_lock); |
637 | dput(old); | 660 | dput(old); |
638 | mntput(*mnt); | 661 | mntput(nd->mnt); |
639 | *mnt = parent; | 662 | nd->mnt = parent; |
640 | } | 663 | } |
641 | follow_mount(mnt, dentry); | 664 | follow_mount(&nd->mnt, &nd->dentry); |
642 | } | 665 | } |
643 | 666 | ||
644 | struct path { | ||
645 | struct vfsmount *mnt; | ||
646 | struct dentry *dentry; | ||
647 | }; | ||
648 | |||
649 | /* | 667 | /* |
650 | * It's more convoluted than I'd like it to be, but... it's still fairly | 668 | * It's more convoluted than I'd like it to be, but... it's still fairly |
651 | * small and for now I'd prefer to have fast path as straight as possible. | 669 | * small and for now I'd prefer to have fast path as straight as possible. |
@@ -664,6 +682,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
664 | done: | 682 | done: |
665 | path->mnt = mnt; | 683 | path->mnt = mnt; |
666 | path->dentry = dentry; | 684 | path->dentry = dentry; |
685 | __follow_mount(path); | ||
667 | return 0; | 686 | return 0; |
668 | 687 | ||
669 | need_lookup: | 688 | need_lookup: |
@@ -751,7 +770,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) | |||
751 | case 2: | 770 | case 2: |
752 | if (this.name[1] != '.') | 771 | if (this.name[1] != '.') |
753 | break; | 772 | break; |
754 | follow_dotdot(&nd->mnt, &nd->dentry); | 773 | follow_dotdot(nd); |
755 | inode = nd->dentry->d_inode; | 774 | inode = nd->dentry->d_inode; |
756 | /* fallthrough */ | 775 | /* fallthrough */ |
757 | case 1: | 776 | case 1: |
@@ -771,8 +790,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) | |||
771 | err = do_lookup(nd, &this, &next); | 790 | err = do_lookup(nd, &this, &next); |
772 | if (err) | 791 | if (err) |
773 | break; | 792 | break; |
774 | /* Check mountpoints.. */ | ||
775 | follow_mount(&next.mnt, &next.dentry); | ||
776 | 793 | ||
777 | err = -ENOENT; | 794 | err = -ENOENT; |
778 | inode = next.dentry->d_inode; | 795 | inode = next.dentry->d_inode; |
@@ -783,10 +800,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) | |||
783 | goto out_dput; | 800 | goto out_dput; |
784 | 801 | ||
785 | if (inode->i_op->follow_link) { | 802 | if (inode->i_op->follow_link) { |
786 | mntget(next.mnt); | 803 | err = do_follow_link(&next, nd); |
787 | err = do_follow_link(next.dentry, nd); | ||
788 | dput(next.dentry); | ||
789 | mntput(next.mnt); | ||
790 | if (err) | 804 | if (err) |
791 | goto return_err; | 805 | goto return_err; |
792 | err = -ENOENT; | 806 | err = -ENOENT; |
@@ -798,6 +812,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) | |||
798 | break; | 812 | break; |
799 | } else { | 813 | } else { |
800 | dput(nd->dentry); | 814 | dput(nd->dentry); |
815 | if (nd->mnt != next.mnt) | ||
816 | mntput(nd->mnt); | ||
801 | nd->mnt = next.mnt; | 817 | nd->mnt = next.mnt; |
802 | nd->dentry = next.dentry; | 818 | nd->dentry = next.dentry; |
803 | } | 819 | } |
@@ -819,7 +835,7 @@ last_component: | |||
819 | case 2: | 835 | case 2: |
820 | if (this.name[1] != '.') | 836 | if (this.name[1] != '.') |
821 | break; | 837 | break; |
822 | follow_dotdot(&nd->mnt, &nd->dentry); | 838 | follow_dotdot(nd); |
823 | inode = nd->dentry->d_inode; | 839 | inode = nd->dentry->d_inode; |
824 | /* fallthrough */ | 840 | /* fallthrough */ |
825 | case 1: | 841 | case 1: |
@@ -833,19 +849,17 @@ last_component: | |||
833 | err = do_lookup(nd, &this, &next); | 849 | err = do_lookup(nd, &this, &next); |
834 | if (err) | 850 | if (err) |
835 | break; | 851 | break; |
836 | follow_mount(&next.mnt, &next.dentry); | ||
837 | inode = next.dentry->d_inode; | 852 | inode = next.dentry->d_inode; |
838 | if ((lookup_flags & LOOKUP_FOLLOW) | 853 | if ((lookup_flags & LOOKUP_FOLLOW) |
839 | && inode && inode->i_op && inode->i_op->follow_link) { | 854 | && inode && inode->i_op && inode->i_op->follow_link) { |
840 | mntget(next.mnt); | 855 | err = do_follow_link(&next, nd); |
841 | err = do_follow_link(next.dentry, nd); | ||
842 | dput(next.dentry); | ||
843 | mntput(next.mnt); | ||
844 | if (err) | 856 | if (err) |
845 | goto return_err; | 857 | goto return_err; |
846 | inode = nd->dentry->d_inode; | 858 | inode = nd->dentry->d_inode; |
847 | } else { | 859 | } else { |
848 | dput(nd->dentry); | 860 | dput(nd->dentry); |
861 | if (nd->mnt != next.mnt) | ||
862 | mntput(nd->mnt); | ||
849 | nd->mnt = next.mnt; | 863 | nd->mnt = next.mnt; |
850 | nd->dentry = next.dentry; | 864 | nd->dentry = next.dentry; |
851 | } | 865 | } |
@@ -885,6 +899,8 @@ return_base: | |||
885 | return 0; | 899 | return 0; |
886 | out_dput: | 900 | out_dput: |
887 | dput(next.dentry); | 901 | dput(next.dentry); |
902 | if (nd->mnt != next.mnt) | ||
903 | mntput(next.mnt); | ||
888 | break; | 904 | break; |
889 | } | 905 | } |
890 | path_release(nd); | 906 | path_release(nd); |
@@ -1398,7 +1414,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1398 | int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) | 1414 | int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) |
1399 | { | 1415 | { |
1400 | int acc_mode, error = 0; | 1416 | int acc_mode, error = 0; |
1401 | struct dentry *dentry; | 1417 | struct path path; |
1402 | struct dentry *dir; | 1418 | struct dentry *dir; |
1403 | int count = 0; | 1419 | int count = 0; |
1404 | 1420 | ||
@@ -1442,23 +1458,24 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) | |||
1442 | dir = nd->dentry; | 1458 | dir = nd->dentry; |
1443 | nd->flags &= ~LOOKUP_PARENT; | 1459 | nd->flags &= ~LOOKUP_PARENT; |
1444 | down(&dir->d_inode->i_sem); | 1460 | down(&dir->d_inode->i_sem); |
1445 | dentry = __lookup_hash(&nd->last, nd->dentry, nd); | 1461 | path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); |
1462 | path.mnt = nd->mnt; | ||
1446 | 1463 | ||
1447 | do_last: | 1464 | do_last: |
1448 | error = PTR_ERR(dentry); | 1465 | error = PTR_ERR(path.dentry); |
1449 | if (IS_ERR(dentry)) { | 1466 | if (IS_ERR(path.dentry)) { |
1450 | up(&dir->d_inode->i_sem); | 1467 | up(&dir->d_inode->i_sem); |
1451 | goto exit; | 1468 | goto exit; |
1452 | } | 1469 | } |
1453 | 1470 | ||
1454 | /* Negative dentry, just create the file */ | 1471 | /* Negative dentry, just create the file */ |
1455 | if (!dentry->d_inode) { | 1472 | if (!path.dentry->d_inode) { |
1456 | if (!IS_POSIXACL(dir->d_inode)) | 1473 | if (!IS_POSIXACL(dir->d_inode)) |
1457 | mode &= ~current->fs->umask; | 1474 | mode &= ~current->fs->umask; |
1458 | error = vfs_create(dir->d_inode, dentry, mode, nd); | 1475 | error = vfs_create(dir->d_inode, path.dentry, mode, nd); |
1459 | up(&dir->d_inode->i_sem); | 1476 | up(&dir->d_inode->i_sem); |
1460 | dput(nd->dentry); | 1477 | dput(nd->dentry); |
1461 | nd->dentry = dentry; | 1478 | nd->dentry = path.dentry; |
1462 | if (error) | 1479 | if (error) |
1463 | goto exit; | 1480 | goto exit; |
1464 | /* Don't check for write permission, don't truncate */ | 1481 | /* Don't check for write permission, don't truncate */ |
@@ -1476,22 +1493,24 @@ do_last: | |||
1476 | if (flag & O_EXCL) | 1493 | if (flag & O_EXCL) |
1477 | goto exit_dput; | 1494 | goto exit_dput; |
1478 | 1495 | ||
1479 | if (d_mountpoint(dentry)) { | 1496 | if (__follow_mount(&path)) { |
1480 | error = -ELOOP; | 1497 | error = -ELOOP; |
1481 | if (flag & O_NOFOLLOW) | 1498 | if (flag & O_NOFOLLOW) |
1482 | goto exit_dput; | 1499 | goto exit_dput; |
1483 | while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry)); | ||
1484 | } | 1500 | } |
1485 | error = -ENOENT; | 1501 | error = -ENOENT; |
1486 | if (!dentry->d_inode) | 1502 | if (!path.dentry->d_inode) |
1487 | goto exit_dput; | 1503 | goto exit_dput; |
1488 | if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) | 1504 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) |
1489 | goto do_link; | 1505 | goto do_link; |
1490 | 1506 | ||
1491 | dput(nd->dentry); | 1507 | dput(nd->dentry); |
1492 | nd->dentry = dentry; | 1508 | nd->dentry = path.dentry; |
1509 | if (nd->mnt != path.mnt) | ||
1510 | mntput(nd->mnt); | ||
1511 | nd->mnt = path.mnt; | ||
1493 | error = -EISDIR; | 1512 | error = -EISDIR; |
1494 | if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) | 1513 | if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) |
1495 | goto exit; | 1514 | goto exit; |
1496 | ok: | 1515 | ok: |
1497 | error = may_open(nd, acc_mode, flag); | 1516 | error = may_open(nd, acc_mode, flag); |
@@ -1500,7 +1519,9 @@ ok: | |||
1500 | return 0; | 1519 | return 0; |
1501 | 1520 | ||
1502 | exit_dput: | 1521 | exit_dput: |
1503 | dput(dentry); | 1522 | dput(path.dentry); |
1523 | if (nd->mnt != path.mnt) | ||
1524 | mntput(path.mnt); | ||
1504 | exit: | 1525 | exit: |
1505 | path_release(nd); | 1526 | path_release(nd); |
1506 | return error; | 1527 | return error; |
@@ -1520,18 +1541,15 @@ do_link: | |||
1520 | * are done. Procfs-like symlinks just set LAST_BIND. | 1541 | * are done. Procfs-like symlinks just set LAST_BIND. |
1521 | */ | 1542 | */ |
1522 | nd->flags |= LOOKUP_PARENT; | 1543 | nd->flags |= LOOKUP_PARENT; |
1523 | error = security_inode_follow_link(dentry, nd); | 1544 | error = security_inode_follow_link(path.dentry, nd); |
1524 | if (error) | 1545 | if (error) |
1525 | goto exit_dput; | 1546 | goto exit_dput; |
1526 | error = __do_follow_link(dentry, nd); | 1547 | error = __do_follow_link(&path, nd); |
1527 | dput(dentry); | ||
1528 | if (error) | 1548 | if (error) |
1529 | return error; | 1549 | return error; |
1530 | nd->flags &= ~LOOKUP_PARENT; | 1550 | nd->flags &= ~LOOKUP_PARENT; |
1531 | if (nd->last_type == LAST_BIND) { | 1551 | if (nd->last_type == LAST_BIND) |
1532 | dentry = nd->dentry; | ||
1533 | goto ok; | 1552 | goto ok; |
1534 | } | ||
1535 | error = -EISDIR; | 1553 | error = -EISDIR; |
1536 | if (nd->last_type != LAST_NORM) | 1554 | if (nd->last_type != LAST_NORM) |
1537 | goto exit; | 1555 | goto exit; |
@@ -1546,7 +1564,8 @@ do_link: | |||
1546 | } | 1564 | } |
1547 | dir = nd->dentry; | 1565 | dir = nd->dentry; |
1548 | down(&dir->d_inode->i_sem); | 1566 | down(&dir->d_inode->i_sem); |
1549 | dentry = __lookup_hash(&nd->last, nd->dentry, nd); | 1567 | path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); |
1568 | path.mnt = nd->mnt; | ||
1550 | putname(nd->last.name); | 1569 | putname(nd->last.name); |
1551 | goto do_last; | 1570 | goto do_last; |
1552 | } | 1571 | } |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 73f96acd5d37..ff6155f5e8d9 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -528,19 +528,39 @@ static inline void nfs_renew_times(struct dentry * dentry) | |||
528 | dentry->d_time = jiffies; | 528 | dentry->d_time = jiffies; |
529 | } | 529 | } |
530 | 530 | ||
531 | /* | ||
532 | * Return the intent data that applies to this particular path component | ||
533 | * | ||
534 | * Note that the current set of intents only apply to the very last | ||
535 | * component of the path. | ||
536 | * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT. | ||
537 | */ | ||
538 | static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask) | ||
539 | { | ||
540 | if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT)) | ||
541 | return 0; | ||
542 | return nd->flags & mask; | ||
543 | } | ||
544 | |||
545 | /* | ||
546 | * Inode and filehandle revalidation for lookups. | ||
547 | * | ||
548 | * We force revalidation in the cases where the VFS sets LOOKUP_REVAL, | ||
549 | * or if the intent information indicates that we're about to open this | ||
550 | * particular file and the "nocto" mount flag is not set. | ||
551 | * | ||
552 | */ | ||
531 | static inline | 553 | static inline |
532 | int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) | 554 | int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) |
533 | { | 555 | { |
534 | struct nfs_server *server = NFS_SERVER(inode); | 556 | struct nfs_server *server = NFS_SERVER(inode); |
535 | 557 | ||
536 | if (nd != NULL) { | 558 | if (nd != NULL) { |
537 | int ndflags = nd->flags; | ||
538 | /* VFS wants an on-the-wire revalidation */ | 559 | /* VFS wants an on-the-wire revalidation */ |
539 | if (ndflags & LOOKUP_REVAL) | 560 | if (nd->flags & LOOKUP_REVAL) |
540 | goto out_force; | 561 | goto out_force; |
541 | /* This is an open(2) */ | 562 | /* This is an open(2) */ |
542 | if ((ndflags & LOOKUP_OPEN) && | 563 | if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && |
543 | !(ndflags & LOOKUP_CONTINUE) && | ||
544 | !(server->flags & NFS_MOUNT_NOCTO)) | 564 | !(server->flags & NFS_MOUNT_NOCTO)) |
545 | goto out_force; | 565 | goto out_force; |
546 | } | 566 | } |
@@ -560,12 +580,8 @@ static inline | |||
560 | int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, | 580 | int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, |
561 | struct nameidata *nd) | 581 | struct nameidata *nd) |
562 | { | 582 | { |
563 | int ndflags = 0; | ||
564 | |||
565 | if (nd) | ||
566 | ndflags = nd->flags; | ||
567 | /* Don't revalidate a negative dentry if we're creating a new file */ | 583 | /* Don't revalidate a negative dentry if we're creating a new file */ |
568 | if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE)) | 584 | if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0) |
569 | return 0; | 585 | return 0; |
570 | return !nfs_check_verifier(dir, dentry); | 586 | return !nfs_check_verifier(dir, dentry); |
571 | } | 587 | } |
@@ -700,12 +716,16 @@ struct dentry_operations nfs_dentry_operations = { | |||
700 | .d_iput = nfs_dentry_iput, | 716 | .d_iput = nfs_dentry_iput, |
701 | }; | 717 | }; |
702 | 718 | ||
719 | /* | ||
720 | * Use intent information to check whether or not we're going to do | ||
721 | * an O_EXCL create using this path component. | ||
722 | */ | ||
703 | static inline | 723 | static inline |
704 | int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) | 724 | int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) |
705 | { | 725 | { |
706 | if (NFS_PROTO(dir)->version == 2) | 726 | if (NFS_PROTO(dir)->version == 2) |
707 | return 0; | 727 | return 0; |
708 | if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE)) | 728 | if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) |
709 | return 0; | 729 | return 0; |
710 | return (nd->intent.open.flags & O_EXCL) != 0; | 730 | return (nd->intent.open.flags & O_EXCL) != 0; |
711 | } | 731 | } |
@@ -772,12 +792,13 @@ struct dentry_operations nfs4_dentry_operations = { | |||
772 | .d_iput = nfs_dentry_iput, | 792 | .d_iput = nfs_dentry_iput, |
773 | }; | 793 | }; |
774 | 794 | ||
795 | /* | ||
796 | * Use intent information to determine whether we need to substitute | ||
797 | * the NFSv4-style stateful OPEN for the LOOKUP call | ||
798 | */ | ||
775 | static int is_atomic_open(struct inode *dir, struct nameidata *nd) | 799 | static int is_atomic_open(struct inode *dir, struct nameidata *nd) |
776 | { | 800 | { |
777 | if (!nd) | 801 | if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) |
778 | return 0; | ||
779 | /* Check that we are indeed trying to open this file */ | ||
780 | if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN)) | ||
781 | return 0; | 802 | return 0; |
782 | /* NFS does not (yet) have a stateful open for directories */ | 803 | /* NFS does not (yet) have a stateful open for directories */ |
783 | if (nd->flags & LOOKUP_DIRECTORY) | 804 | if (nd->flags & LOOKUP_DIRECTORY) |
diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h index c99dbbb5bcb5..ef855a3bc0f5 100644 --- a/include/asm-alpha/agp.h +++ b/include/asm-alpha/agp.h | |||
@@ -10,4 +10,14 @@ | |||
10 | #define flush_agp_mappings() | 10 | #define flush_agp_mappings() |
11 | #define flush_agp_cache() mb() | 11 | #define flush_agp_cache() mb() |
12 | 12 | ||
13 | /* Convert a physical address to an address suitable for the GART. */ | ||
14 | #define phys_to_gart(x) (x) | ||
15 | #define gart_to_phys(x) (x) | ||
16 | |||
17 | /* GATT allocation. Returns/accepts GATT kernel virtual address. */ | ||
18 | #define alloc_gatt_pages(order) \ | ||
19 | ((char *)__get_free_pages(GFP_KERNEL, (order))) | ||
20 | #define free_gatt_pages(table, order) \ | ||
21 | free_pages((unsigned long)(table), (order)) | ||
22 | |||
13 | #endif | 23 | #endif |
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h index a8e3c2daefd6..083462668e18 100644 --- a/include/asm-arm/arch-ixp2000/io.h +++ b/include/asm-arm/arch-ixp2000/io.h | |||
@@ -75,8 +75,8 @@ static inline void insw(u32 ptr, void *buf, int length) | |||
75 | * Is this cycle meant for the CS8900? | 75 | * Is this cycle meant for the CS8900? |
76 | */ | 76 | */ |
77 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && | 77 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && |
78 | ((port >= IXDP2X01_CS8900_VIRT_BASE) && | 78 | (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && |
79 | (port <= IXDP2X01_CS8900_VIRT_END))) { | 79 | ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { |
80 | u8 *buf8 = (u8*)buf; | 80 | u8 *buf8 = (u8*)buf; |
81 | register u32 tmp32; | 81 | register u32 tmp32; |
82 | 82 | ||
@@ -100,8 +100,8 @@ static inline void outsw(u32 ptr, void *buf, int length) | |||
100 | * Is this cycle meant for the CS8900? | 100 | * Is this cycle meant for the CS8900? |
101 | */ | 101 | */ |
102 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && | 102 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && |
103 | ((port >= IXDP2X01_CS8900_VIRT_BASE) && | 103 | (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && |
104 | (port <= IXDP2X01_CS8900_VIRT_END))) { | 104 | ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { |
105 | register u32 tmp32; | 105 | register u32 tmp32; |
106 | u8 *buf8 = (u8*)buf; | 106 | u8 *buf8 = (u8*)buf; |
107 | do { | 107 | do { |
@@ -124,8 +124,8 @@ static inline u16 inw(u32 ptr) | |||
124 | * Is this cycle meant for the CS8900? | 124 | * Is this cycle meant for the CS8900? |
125 | */ | 125 | */ |
126 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && | 126 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && |
127 | ((port >= IXDP2X01_CS8900_VIRT_BASE) && | 127 | (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && |
128 | (port <= IXDP2X01_CS8900_VIRT_END))) { | 128 | ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { |
129 | return (u16)(*port); | 129 | return (u16)(*port); |
130 | } | 130 | } |
131 | 131 | ||
@@ -137,8 +137,8 @@ static inline void outw(u16 value, u32 ptr) | |||
137 | register volatile u32 *port = (volatile u32 *)ptr; | 137 | register volatile u32 *port = (volatile u32 *)ptr; |
138 | 138 | ||
139 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && | 139 | if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && |
140 | ((port >= IXDP2X01_CS8900_VIRT_BASE) && | 140 | (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && |
141 | (port <= IXDP2X01_CS8900_VIRT_END))) { | 141 | ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { |
142 | *port = value; | 142 | *port = value; |
143 | return; | 143 | return; |
144 | } | 144 | } |
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 39741d3c9a34..b5e54a9e9fa7 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h | |||
@@ -1296,6 +1296,7 @@ | |||
1296 | #define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ | 1296 | #define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ |
1297 | #define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ | 1297 | #define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ |
1298 | #define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ | 1298 | #define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ |
1299 | #define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ | ||
1299 | #define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ | 1300 | #define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ |
1300 | 1301 | ||
1301 | /* GPIO alternate function mode & direction */ | 1302 | /* GPIO alternate function mode & direction */ |
@@ -1428,6 +1429,7 @@ | |||
1428 | #define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) | 1429 | #define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) |
1429 | #define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) | 1430 | #define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) |
1430 | #define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) | 1431 | #define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) |
1432 | #define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) | ||
1431 | #define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) | 1433 | #define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) |
1432 | #define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) | 1434 | #define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) |
1433 | #define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) | 1435 | #define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) |
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h index cbceacbe5afa..a1696ba238d3 100644 --- a/include/asm-arm/elf.h +++ b/include/asm-arm/elf.h | |||
@@ -38,9 +38,9 @@ typedef struct user_fp elf_fpregset_t; | |||
38 | */ | 38 | */ |
39 | #define ELF_CLASS ELFCLASS32 | 39 | #define ELF_CLASS ELFCLASS32 |
40 | #ifdef __ARMEB__ | 40 | #ifdef __ARMEB__ |
41 | #define ELF_DATA ELFDATA2MSB; | 41 | #define ELF_DATA ELFDATA2MSB |
42 | #else | 42 | #else |
43 | #define ELF_DATA ELFDATA2LSB; | 43 | #define ELF_DATA ELFDATA2LSB |
44 | #endif | 44 | #endif |
45 | #define ELF_ARCH EM_ARM | 45 | #define ELF_ARCH EM_ARM |
46 | 46 | ||
diff --git a/include/asm-arm26/elf.h b/include/asm-arm26/elf.h index 8b149474db24..5a47fdb3015d 100644 --- a/include/asm-arm26/elf.h +++ b/include/asm-arm26/elf.h | |||
@@ -36,7 +36,7 @@ typedef struct { void *null; } elf_fpregset_t; | |||
36 | * These are used to set parameters in the core dumps. | 36 | * These are used to set parameters in the core dumps. |
37 | */ | 37 | */ |
38 | #define ELF_CLASS ELFCLASS32 | 38 | #define ELF_CLASS ELFCLASS32 |
39 | #define ELF_DATA ELFDATA2LSB; | 39 | #define ELF_DATA ELFDATA2LSB |
40 | #define ELF_ARCH EM_ARM | 40 | #define ELF_ARCH EM_ARM |
41 | 41 | ||
42 | #define USE_ELF_CORE_DUMP | 42 | #define USE_ELF_CORE_DUMP |
diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h index 82431edeb2a1..1ec8a3427120 100644 --- a/include/asm-h8300/kmap_types.h +++ b/include/asm-h8300/kmap_types.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #ifndef _ASM_KMAP_TYPES_H | 1 | #ifndef _ASM_H8300_KMAP_TYPES_H |
2 | #define _ASM_KMAP_TYPES_H | 2 | #define _ASM_H8300_KMAP_TYPES_H |
3 | 3 | ||
4 | enum km_type { | 4 | enum km_type { |
5 | KM_BOUNCE_READ, | 5 | KM_BOUNCE_READ, |
@@ -13,6 +13,8 @@ enum km_type { | |||
13 | KM_PTE1, | 13 | KM_PTE1, |
14 | KM_IRQ0, | 14 | KM_IRQ0, |
15 | KM_IRQ1, | 15 | KM_IRQ1, |
16 | KM_SOFTIRQ0, | ||
17 | KM_SOFTIRQ1, | ||
16 | KM_TYPE_NR | 18 | KM_TYPE_NR |
17 | }; | 19 | }; |
18 | 20 | ||
diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h index abe08856c84f..63f727a59850 100644 --- a/include/asm-h8300/mman.h +++ b/include/asm-h8300/mman.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #define PROT_READ 0x1 /* page can be read */ | 4 | #define PROT_READ 0x1 /* page can be read */ |
5 | #define PROT_WRITE 0x2 /* page can be written */ | 5 | #define PROT_WRITE 0x2 /* page can be written */ |
6 | #define PROT_EXEC 0x4 /* page can be executed */ | 6 | #define PROT_EXEC 0x4 /* page can be executed */ |
7 | #define PROT_SEM 0x8 /* page may be used for atomic ops */ | ||
7 | #define PROT_NONE 0x0 /* page can not be accessed */ | 8 | #define PROT_NONE 0x0 /* page can not be accessed */ |
8 | #define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ | 9 | #define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ |
9 | #define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ | 10 | #define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ |
@@ -19,6 +20,8 @@ | |||
19 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ | 20 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ |
20 | #define MAP_LOCKED 0x2000 /* pages are locked */ | 21 | #define MAP_LOCKED 0x2000 /* pages are locked */ |
21 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ | 22 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ |
23 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ | ||
24 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ | ||
22 | 25 | ||
23 | #define MS_ASYNC 1 /* sync memory asynchronously */ | 26 | #define MS_ASYNC 1 /* sync memory asynchronously */ |
24 | #define MS_INVALIDATE 2 /* invalidate the caches */ | 27 | #define MS_INVALIDATE 2 /* invalidate the caches */ |
diff --git a/include/asm-i386/agp.h b/include/asm-i386/agp.h index a917ff50354f..b82f5f3ab887 100644 --- a/include/asm-i386/agp.h +++ b/include/asm-i386/agp.h | |||
@@ -21,4 +21,14 @@ int unmap_page_from_agp(struct page *page); | |||
21 | worth it. Would need a page for it. */ | 21 | worth it. Would need a page for it. */ |
22 | #define flush_agp_cache() asm volatile("wbinvd":::"memory") | 22 | #define flush_agp_cache() asm volatile("wbinvd":::"memory") |
23 | 23 | ||
24 | /* Convert a physical address to an address suitable for the GART. */ | ||
25 | #define phys_to_gart(x) (x) | ||
26 | #define gart_to_phys(x) (x) | ||
27 | |||
28 | /* GATT allocation. Returns/accepts GATT kernel virtual address. */ | ||
29 | #define alloc_gatt_pages(order) \ | ||
30 | ((char *)__get_free_pages(GFP_KERNEL, (order))) | ||
31 | #define free_gatt_pages(table, order) \ | ||
32 | free_pages((unsigned long)(table), (order)) | ||
33 | |||
24 | #endif | 34 | #endif |
diff --git a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h index 1b46fd3f2ae3..c6044488e9e6 100644 --- a/include/asm-i386/mach-numaq/mach_ipi.h +++ b/include/asm-i386/mach-numaq/mach_ipi.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef __ASM_MACH_IPI_H | 1 | #ifndef __ASM_MACH_IPI_H |
2 | #define __ASM_MACH_IPI_H | 2 | #define __ASM_MACH_IPI_H |
3 | 3 | ||
4 | inline void send_IPI_mask_sequence(cpumask_t, int vector); | 4 | void send_IPI_mask_sequence(cpumask_t, int vector); |
5 | 5 | ||
6 | static inline void send_IPI_mask(cpumask_t mask, int vector) | 6 | static inline void send_IPI_mask(cpumask_t mask, int vector) |
7 | { | 7 | { |
diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h index d1316f1e6ee1..4e517f0e6afa 100644 --- a/include/asm-ia64/agp.h +++ b/include/asm-ia64/agp.h | |||
@@ -18,4 +18,14 @@ | |||
18 | #define flush_agp_mappings() /* nothing */ | 18 | #define flush_agp_mappings() /* nothing */ |
19 | #define flush_agp_cache() mb() | 19 | #define flush_agp_cache() mb() |
20 | 20 | ||
21 | /* Convert a physical address to an address suitable for the GART. */ | ||
22 | #define phys_to_gart(x) (x) | ||
23 | #define gart_to_phys(x) (x) | ||
24 | |||
25 | /* GATT allocation. Returns/accepts GATT kernel virtual address. */ | ||
26 | #define alloc_gatt_pages(order) \ | ||
27 | ((char *)__get_free_pages(GFP_KERNEL, (order))) | ||
28 | #define free_gatt_pages(table, order) \ | ||
29 | free_pages((unsigned long)(table), (order)) | ||
30 | |||
21 | #endif /* _ASM_IA64_AGP_H */ | 31 | #endif /* _ASM_IA64_AGP_H */ |
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h index ea121a002309..fcc9c3344ab4 100644 --- a/include/asm-ia64/pgtable.h +++ b/include/asm-ia64/pgtable.h | |||
@@ -8,7 +8,7 @@ | |||
8 | * This hopefully works with any (fixed) IA-64 page-size, as defined | 8 | * This hopefully works with any (fixed) IA-64 page-size, as defined |
9 | * in <asm/page.h>. | 9 | * in <asm/page.h>. |
10 | * | 10 | * |
11 | * Copyright (C) 1998-2004 Hewlett-Packard Co | 11 | * Copyright (C) 1998-2005 Hewlett-Packard Co |
12 | * David Mosberger-Tang <davidm@hpl.hp.com> | 12 | * David Mosberger-Tang <davidm@hpl.hp.com> |
13 | */ | 13 | */ |
14 | 14 | ||
@@ -551,7 +551,11 @@ do { \ | |||
551 | 551 | ||
552 | /* These tell get_user_pages() that the first gate page is accessible from user-level. */ | 552 | /* These tell get_user_pages() that the first gate page is accessible from user-level. */ |
553 | #define FIXADDR_USER_START GATE_ADDR | 553 | #define FIXADDR_USER_START GATE_ADDR |
554 | #define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE) | 554 | #ifdef HAVE_BUGGY_SEGREL |
555 | # define FIXADDR_USER_END (GATE_ADDR + 2*PAGE_SIZE) | ||
556 | #else | ||
557 | # define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE) | ||
558 | #endif | ||
555 | 559 | ||
556 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 560 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
557 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY | 561 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY |
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 9e1ba8b7fb68..91bbd1f22461 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h | |||
@@ -403,7 +403,10 @@ extern void ia64_setreg_unknown_kr (void); | |||
403 | * task_struct at this point. | 403 | * task_struct at this point. |
404 | */ | 404 | */ |
405 | 405 | ||
406 | /* Return TRUE if task T owns the fph partition of the CPU we're running on. */ | 406 | /* |
407 | * Return TRUE if task T owns the fph partition of the CPU we're running on. | ||
408 | * Must be called from code that has preemption disabled. | ||
409 | */ | ||
407 | #define ia64_is_local_fpu_owner(t) \ | 410 | #define ia64_is_local_fpu_owner(t) \ |
408 | ({ \ | 411 | ({ \ |
409 | struct task_struct *__ia64_islfo_task = (t); \ | 412 | struct task_struct *__ia64_islfo_task = (t); \ |
@@ -411,7 +414,10 @@ extern void ia64_setreg_unknown_kr (void); | |||
411 | && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER)); \ | 414 | && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER)); \ |
412 | }) | 415 | }) |
413 | 416 | ||
414 | /* Mark task T as owning the fph partition of the CPU we're running on. */ | 417 | /* |
418 | * Mark task T as owning the fph partition of the CPU we're running on. | ||
419 | * Must be called from code that has preemption disabled. | ||
420 | */ | ||
415 | #define ia64_set_local_fpu_owner(t) do { \ | 421 | #define ia64_set_local_fpu_owner(t) do { \ |
416 | struct task_struct *__ia64_slfo_task = (t); \ | 422 | struct task_struct *__ia64_slfo_task = (t); \ |
417 | __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id(); \ | 423 | __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id(); \ |
diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h index be27cfa8c5b0..ca9e423307f4 100644 --- a/include/asm-ppc/agp.h +++ b/include/asm-ppc/agp.h | |||
@@ -10,4 +10,14 @@ | |||
10 | #define flush_agp_mappings() | 10 | #define flush_agp_mappings() |
11 | #define flush_agp_cache() mb() | 11 | #define flush_agp_cache() mb() |
12 | 12 | ||
13 | /* Convert a physical address to an address suitable for the GART. */ | ||
14 | #define phys_to_gart(x) (x) | ||
15 | #define gart_to_phys(x) (x) | ||
16 | |||
17 | /* GATT allocation. Returns/accepts GATT kernel virtual address. */ | ||
18 | #define alloc_gatt_pages(order) \ | ||
19 | ((char *)__get_free_pages(GFP_KERNEL, (order))) | ||
20 | #define free_gatt_pages(table, order) \ | ||
21 | free_pages((unsigned long)(table), (order)) | ||
22 | |||
13 | #endif | 23 | #endif |
diff --git a/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h index f82dcccdee1e..b7a417e0a921 100644 --- a/include/asm-ppc/sigcontext.h +++ b/include/asm-ppc/sigcontext.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _ASM_PPC_SIGCONTEXT_H | 2 | #define _ASM_PPC_SIGCONTEXT_H |
3 | 3 | ||
4 | #include <asm/ptrace.h> | 4 | #include <asm/ptrace.h> |
5 | 5 | #include <linux/compiler.h> | |
6 | 6 | ||
7 | struct sigcontext { | 7 | struct sigcontext { |
8 | unsigned long _unused[4]; | 8 | unsigned long _unused[4]; |
diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h index be27cfa8c5b0..ca9e423307f4 100644 --- a/include/asm-ppc64/agp.h +++ b/include/asm-ppc64/agp.h | |||
@@ -10,4 +10,14 @@ | |||
10 | #define flush_agp_mappings() | 10 | #define flush_agp_mappings() |
11 | #define flush_agp_cache() mb() | 11 | #define flush_agp_cache() mb() |
12 | 12 | ||
13 | /* Convert a physical address to an address suitable for the GART. */ | ||
14 | #define phys_to_gart(x) (x) | ||
15 | #define gart_to_phys(x) (x) | ||
16 | |||
17 | /* GATT allocation. Returns/accepts GATT kernel virtual address. */ | ||
18 | #define alloc_gatt_pages(order) \ | ||
19 | ((char *)__get_free_pages(GFP_KERNEL, (order))) | ||
20 | #define free_gatt_pages(table, order) \ | ||
21 | free_pages((unsigned long)(table), (order)) | ||
22 | |||
13 | #endif | 23 | #endif |
diff --git a/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h index 6c42d61bedd1..085eedb956fe 100644 --- a/include/asm-ppc64/elf.h +++ b/include/asm-ppc64/elf.h | |||
@@ -221,9 +221,7 @@ do { \ | |||
221 | set_thread_flag(TIF_ABI_PENDING); \ | 221 | set_thread_flag(TIF_ABI_PENDING); \ |
222 | else \ | 222 | else \ |
223 | clear_thread_flag(TIF_ABI_PENDING); \ | 223 | clear_thread_flag(TIF_ABI_PENDING); \ |
224 | if (ibcs2) \ | 224 | if (personality(current->personality) != PER_LINUX32) \ |
225 | set_personality(PER_SVR4); \ | ||
226 | else if (current->personality != PER_LINUX32) \ | ||
227 | set_personality(PER_LINUX); \ | 225 | set_personality(PER_LINUX); \ |
228 | } while (0) | 226 | } while (0) |
229 | 227 | ||
diff --git a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index f461144067ee..0a780e84a12b 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h | |||
@@ -41,10 +41,11 @@ | |||
41 | * No one can read/write anything from userland in the kernel space by setting | 41 | * No one can read/write anything from userland in the kernel space by setting |
42 | * large size and address near to PAGE_OFFSET - a fault will break his intentions. | 42 | * large size and address near to PAGE_OFFSET - a fault will break his intentions. |
43 | */ | 43 | */ |
44 | #define __user_ok(addr,size) ((addr) < STACK_TOP) | 44 | #define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) |
45 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) | 45 | #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) |
46 | #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) | 46 | #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) |
47 | #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) | 47 | #define access_ok(type, addr, size) \ |
48 | ({ (void)(type); __access_ok((unsigned long)(addr), size); }) | ||
48 | 49 | ||
49 | /* this function will go away soon - use access_ok() instead */ | 50 | /* this function will go away soon - use access_ok() instead */ |
50 | static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size) | 51 | static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size) |
diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h index ba05bdf9a211..58f8cb6ae767 100644 --- a/include/asm-sparc64/agp.h +++ b/include/asm-sparc64/agp.h | |||
@@ -8,4 +8,14 @@ | |||
8 | #define flush_agp_mappings() | 8 | #define flush_agp_mappings() |
9 | #define flush_agp_cache() mb() | 9 | #define flush_agp_cache() mb() |
10 | 10 | ||
11 | /* Convert a physical address to an address suitable for the GART. */ | ||
12 | #define phys_to_gart(x) (x) | ||
13 | #define gart_to_phys(x) (x) | ||
14 | |||
15 | /* GATT allocation. Returns/accepts GATT kernel virtual address. */ | ||
16 | #define alloc_gatt_pages(order) \ | ||
17 | ((char *)__get_free_pages(GFP_KERNEL, (order))) | ||
18 | #define free_gatt_pages(table, order) \ | ||
19 | free_pages((unsigned long)(table), (order)) | ||
20 | |||
11 | #endif | 21 | #endif |
diff --git a/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h index 0bb9019d58aa..06c52ee9c06b 100644 --- a/include/asm-x86_64/agp.h +++ b/include/asm-x86_64/agp.h | |||
@@ -19,4 +19,14 @@ int unmap_page_from_agp(struct page *page); | |||
19 | worth it. Would need a page for it. */ | 19 | worth it. Would need a page for it. */ |
20 | #define flush_agp_cache() asm volatile("wbinvd":::"memory") | 20 | #define flush_agp_cache() asm volatile("wbinvd":::"memory") |
21 | 21 | ||
22 | /* Convert a physical address to an address suitable for the GART. */ | ||
23 | #define phys_to_gart(x) (x) | ||
24 | #define gart_to_phys(x) (x) | ||
25 | |||
26 | /* GATT allocation. Returns/accepts GATT kernel virtual address. */ | ||
27 | #define alloc_gatt_pages(order) \ | ||
28 | ((char *)__get_free_pages(GFP_KERNEL, (order))) | ||
29 | #define free_gatt_pages(table, order) \ | ||
30 | free_pages((unsigned long)(table), (order)) | ||
31 | |||
22 | #endif | 32 | #endif |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index d5a55bdb9c3c..b123cc08773d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -25,6 +25,8 @@ | |||
25 | #ifndef _LINUX_ACPI_H | 25 | #ifndef _LINUX_ACPI_H |
26 | #define _LINUX_ACPI_H | 26 | #define _LINUX_ACPI_H |
27 | 27 | ||
28 | #include <linux/config.h> | ||
29 | |||
28 | #ifdef CONFIG_ACPI | 30 | #ifdef CONFIG_ACPI |
29 | 31 | ||
30 | #ifndef _LINUX | 32 | #ifndef _LINUX |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b0d6134e1ee6..b8b4ebf9abf1 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -874,6 +874,7 @@ | |||
874 | #define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026 | 874 | #define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026 |
875 | #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 | 875 | #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 |
876 | #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d | 876 | #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d |
877 | #define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e | ||
877 | #define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 | 878 | #define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 |
878 | #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 | 879 | #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 |
879 | #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA 0x0033 | 880 | #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA 0x0033 |
@@ -2382,6 +2383,8 @@ | |||
2382 | #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 | 2383 | #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 |
2383 | #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 | 2384 | #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 |
2384 | #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 | 2385 | #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 |
2386 | #define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 | ||
2387 | #define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 | ||
2385 | #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 | 2388 | #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 |
2386 | #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 | 2389 | #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 |
2387 | #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 | 2390 | #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 |
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index aa6b48bb4dcd..a6b2cc530af5 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h | |||
@@ -56,6 +56,36 @@ enum | |||
56 | TCF_META_ID_TCCLASSID, | 56 | TCF_META_ID_TCCLASSID, |
57 | TCF_META_ID_RTCLASSID, | 57 | TCF_META_ID_RTCLASSID, |
58 | TCF_META_ID_RTIIF, | 58 | TCF_META_ID_RTIIF, |
59 | TCF_META_ID_SK_FAMILY, | ||
60 | TCF_META_ID_SK_STATE, | ||
61 | TCF_META_ID_SK_REUSE, | ||
62 | TCF_META_ID_SK_BOUND_IF, | ||
63 | TCF_META_ID_SK_REFCNT, | ||
64 | TCF_META_ID_SK_SHUTDOWN, | ||
65 | TCF_META_ID_SK_PROTO, | ||
66 | TCF_META_ID_SK_TYPE, | ||
67 | TCF_META_ID_SK_RCVBUF, | ||
68 | TCF_META_ID_SK_RMEM_ALLOC, | ||
69 | TCF_META_ID_SK_WMEM_ALLOC, | ||
70 | TCF_META_ID_SK_OMEM_ALLOC, | ||
71 | TCF_META_ID_SK_WMEM_QUEUED, | ||
72 | TCF_META_ID_SK_RCV_QLEN, | ||
73 | TCF_META_ID_SK_SND_QLEN, | ||
74 | TCF_META_ID_SK_ERR_QLEN, | ||
75 | TCF_META_ID_SK_FORWARD_ALLOCS, | ||
76 | TCF_META_ID_SK_SNDBUF, | ||
77 | TCF_META_ID_SK_ALLOCS, | ||
78 | TCF_META_ID_SK_ROUTE_CAPS, | ||
79 | TCF_META_ID_SK_HASHENT, | ||
80 | TCF_META_ID_SK_LINGERTIME, | ||
81 | TCF_META_ID_SK_ACK_BACKLOG, | ||
82 | TCF_META_ID_SK_MAX_ACK_BACKLOG, | ||
83 | TCF_META_ID_SK_PRIO, | ||
84 | TCF_META_ID_SK_RCVLOWAT, | ||
85 | TCF_META_ID_SK_RCVTIMEO, | ||
86 | TCF_META_ID_SK_SNDTIMEO, | ||
87 | TCF_META_ID_SK_SENDMSG_OFF, | ||
88 | TCF_META_ID_SK_WRITE_PENDING, | ||
59 | __TCF_META_ID_MAX | 89 | __TCF_META_ID_MAX |
60 | }; | 90 | }; |
61 | #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) | 91 | #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) |
diff --git a/mm/filemap.c b/mm/filemap.c index 1d33fec7bac6..4a2fee2cb62b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1968,6 +1968,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
1968 | do { | 1968 | do { |
1969 | unsigned long index; | 1969 | unsigned long index; |
1970 | unsigned long offset; | 1970 | unsigned long offset; |
1971 | unsigned long maxlen; | ||
1971 | size_t copied; | 1972 | size_t copied; |
1972 | 1973 | ||
1973 | offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ | 1974 | offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ |
@@ -1982,7 +1983,10 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
1982 | * same page as we're writing to, without it being marked | 1983 | * same page as we're writing to, without it being marked |
1983 | * up-to-date. | 1984 | * up-to-date. |
1984 | */ | 1985 | */ |
1985 | fault_in_pages_readable(buf, bytes); | 1986 | maxlen = cur_iov->iov_len - iov_base; |
1987 | if (maxlen > bytes) | ||
1988 | maxlen = bytes; | ||
1989 | fault_in_pages_readable(buf, maxlen); | ||
1986 | 1990 | ||
1987 | page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); | 1991 | page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); |
1988 | if (!page) { | 1992 | if (!page) { |
@@ -2024,6 +2028,8 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, | |||
2024 | filemap_set_next_iovec(&cur_iov, | 2028 | filemap_set_next_iovec(&cur_iov, |
2025 | &iov_base, status); | 2029 | &iov_base, status); |
2026 | buf = cur_iov->iov_base + iov_base; | 2030 | buf = cur_iov->iov_base + iov_base; |
2031 | } else { | ||
2032 | iov_base += status; | ||
2027 | } | 2033 | } |
2028 | } | 2034 | } |
2029 | } | 2035 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index f15a3ffff635..ab935778ce81 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1744,6 +1744,7 @@ static int process_backlog(struct net_device *backlog_dev, int *budget) | |||
1744 | struct softnet_data *queue = &__get_cpu_var(softnet_data); | 1744 | struct softnet_data *queue = &__get_cpu_var(softnet_data); |
1745 | unsigned long start_time = jiffies; | 1745 | unsigned long start_time = jiffies; |
1746 | 1746 | ||
1747 | backlog_dev->weight = weight_p; | ||
1747 | for (;;) { | 1748 | for (;;) { |
1748 | struct sk_buff *skb; | 1749 | struct sk_buff *skb; |
1749 | struct net_device *dev; | 1750 | struct net_device *dev; |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 8ec484894d68..a3eeb88e1c81 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -356,7 +356,7 @@ static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) | |||
356 | { | 356 | { |
357 | struct ethtool_coalesce coalesce; | 357 | struct ethtool_coalesce coalesce; |
358 | 358 | ||
359 | if (!dev->ethtool_ops->get_coalesce) | 359 | if (!dev->ethtool_ops->set_coalesce) |
360 | return -EOPNOTSUPP; | 360 | return -EOPNOTSUPP; |
361 | 361 | ||
362 | if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) | 362 | if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 910eb4c05a47..e2137f3e489d 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -185,6 +185,22 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz | |||
185 | static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, | 185 | static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, |
186 | store_tx_queue_len); | 186 | store_tx_queue_len); |
187 | 187 | ||
188 | NETDEVICE_SHOW(weight, fmt_dec); | ||
189 | |||
190 | static int change_weight(struct net_device *net, unsigned long new_weight) | ||
191 | { | ||
192 | net->weight = new_weight; | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len) | ||
197 | { | ||
198 | return netdev_store(dev, buf, len, change_weight); | ||
199 | } | ||
200 | |||
201 | static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, | ||
202 | store_weight); | ||
203 | |||
188 | 204 | ||
189 | static struct class_device_attribute *net_class_attributes[] = { | 205 | static struct class_device_attribute *net_class_attributes[] = { |
190 | &class_device_attr_ifindex, | 206 | &class_device_attr_ifindex, |
@@ -194,6 +210,7 @@ static struct class_device_attribute *net_class_attributes[] = { | |||
194 | &class_device_attr_features, | 210 | &class_device_attr_features, |
195 | &class_device_attr_mtu, | 211 | &class_device_attr_mtu, |
196 | &class_device_attr_flags, | 212 | &class_device_attr_flags, |
213 | &class_device_attr_weight, | ||
197 | &class_device_attr_type, | 214 | &class_device_attr_type, |
198 | &class_device_attr_address, | 215 | &class_device_attr_address, |
199 | &class_device_attr_broadcast, | 216 | &class_device_attr_broadcast, |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 3b1c9fa184ae..ba3b0c267f75 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -882,6 +882,7 @@ ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p) | |||
882 | t->parms.hop_limit = p->hop_limit; | 882 | t->parms.hop_limit = p->hop_limit; |
883 | t->parms.encap_limit = p->encap_limit; | 883 | t->parms.encap_limit = p->encap_limit; |
884 | t->parms.flowinfo = p->flowinfo; | 884 | t->parms.flowinfo = p->flowinfo; |
885 | t->parms.link = p->link; | ||
885 | ip6ip6_tnl_link_config(t); | 886 | ip6ip6_tnl_link_config(t); |
886 | return 0; | 887 | return 0; |
887 | } | 888 | } |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index b0941186f867..b22c9beb604d 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -405,7 +405,7 @@ config NET_EMATCH_STACK | |||
405 | ---help--- | 405 | ---help--- |
406 | Size of the local stack variable used while evaluating the tree of | 406 | Size of the local stack variable used while evaluating the tree of |
407 | ematches. Limits the depth of the tree, i.e. the number of | 407 | ematches. Limits the depth of the tree, i.e. the number of |
408 | encapsulated precedences. Every level requires 4 bytes of addtional | 408 | encapsulated precedences. Every level requires 4 bytes of additional |
409 | stack space. | 409 | stack space. |
410 | 410 | ||
411 | config NET_EMATCH_CMP | 411 | config NET_EMATCH_CMP |
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 0d2d4415f334..dfb300bb6baa 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c | |||
@@ -261,6 +261,9 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, | |||
261 | rta = (struct rtattr *) b; | 261 | rta = (struct rtattr *) b; |
262 | RTA_PUT(skb, TCA_OPTIONS, 0, NULL); | 262 | RTA_PUT(skb, TCA_OPTIONS, 0, NULL); |
263 | 263 | ||
264 | if (f->res.classid) | ||
265 | RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid); | ||
266 | |||
264 | if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 || | 267 | if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 || |
265 | tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) | 268 | tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) |
266 | goto rtattr_failure; | 269 | goto rtattr_failure; |
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index f1eeaf65cee5..48bb23c2a35a 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * +-----------+ +-----------+ | 32 | * +-----------+ +-----------+ |
33 | * | | | 33 | * | | |
34 | * ---> meta_ops[INT][INDEV](...) | | 34 | * ---> meta_ops[INT][INDEV](...) | |
35 | * | | | 35 | * | | |
36 | * ----------- | | 36 | * ----------- | |
37 | * V V | 37 | * V V |
38 | * +-----------+ +-----------+ | 38 | * +-----------+ +-----------+ |
@@ -70,6 +70,7 @@ | |||
70 | #include <net/dst.h> | 70 | #include <net/dst.h> |
71 | #include <net/route.h> | 71 | #include <net/route.h> |
72 | #include <net/pkt_cls.h> | 72 | #include <net/pkt_cls.h> |
73 | #include <net/sock.h> | ||
73 | 74 | ||
74 | struct meta_obj | 75 | struct meta_obj |
75 | { | 76 | { |
@@ -284,6 +285,214 @@ META_COLLECTOR(int_rtiif) | |||
284 | } | 285 | } |
285 | 286 | ||
286 | /************************************************************************** | 287 | /************************************************************************** |
288 | * Socket Attributes | ||
289 | **************************************************************************/ | ||
290 | |||
291 | #define SKIP_NONLOCAL(skb) \ | ||
292 | if (unlikely(skb->sk == NULL)) { \ | ||
293 | *err = -1; \ | ||
294 | return; \ | ||
295 | } | ||
296 | |||
297 | META_COLLECTOR(int_sk_family) | ||
298 | { | ||
299 | SKIP_NONLOCAL(skb); | ||
300 | dst->value = skb->sk->sk_family; | ||
301 | } | ||
302 | |||
303 | META_COLLECTOR(int_sk_state) | ||
304 | { | ||
305 | SKIP_NONLOCAL(skb); | ||
306 | dst->value = skb->sk->sk_state; | ||
307 | } | ||
308 | |||
309 | META_COLLECTOR(int_sk_reuse) | ||
310 | { | ||
311 | SKIP_NONLOCAL(skb); | ||
312 | dst->value = skb->sk->sk_reuse; | ||
313 | } | ||
314 | |||
315 | META_COLLECTOR(int_sk_bound_if) | ||
316 | { | ||
317 | SKIP_NONLOCAL(skb); | ||
318 | /* No error if bound_dev_if is 0, legal userspace check */ | ||
319 | dst->value = skb->sk->sk_bound_dev_if; | ||
320 | } | ||
321 | |||
322 | META_COLLECTOR(var_sk_bound_if) | ||
323 | { | ||
324 | SKIP_NONLOCAL(skb); | ||
325 | |||
326 | if (skb->sk->sk_bound_dev_if == 0) { | ||
327 | dst->value = (unsigned long) "any"; | ||
328 | dst->len = 3; | ||
329 | } else { | ||
330 | struct net_device *dev; | ||
331 | |||
332 | dev = dev_get_by_index(skb->sk->sk_bound_dev_if); | ||
333 | *err = var_dev(dev, dst); | ||
334 | if (dev) | ||
335 | dev_put(dev); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | META_COLLECTOR(int_sk_refcnt) | ||
340 | { | ||
341 | SKIP_NONLOCAL(skb); | ||
342 | dst->value = atomic_read(&skb->sk->sk_refcnt); | ||
343 | } | ||
344 | |||
345 | META_COLLECTOR(int_sk_rcvbuf) | ||
346 | { | ||
347 | SKIP_NONLOCAL(skb); | ||
348 | dst->value = skb->sk->sk_rcvbuf; | ||
349 | } | ||
350 | |||
351 | META_COLLECTOR(int_sk_shutdown) | ||
352 | { | ||
353 | SKIP_NONLOCAL(skb); | ||
354 | dst->value = skb->sk->sk_shutdown; | ||
355 | } | ||
356 | |||
357 | META_COLLECTOR(int_sk_proto) | ||
358 | { | ||
359 | SKIP_NONLOCAL(skb); | ||
360 | dst->value = skb->sk->sk_protocol; | ||
361 | } | ||
362 | |||
363 | META_COLLECTOR(int_sk_type) | ||
364 | { | ||
365 | SKIP_NONLOCAL(skb); | ||
366 | dst->value = skb->sk->sk_type; | ||
367 | } | ||
368 | |||
369 | META_COLLECTOR(int_sk_rmem_alloc) | ||
370 | { | ||
371 | SKIP_NONLOCAL(skb); | ||
372 | dst->value = atomic_read(&skb->sk->sk_rmem_alloc); | ||
373 | } | ||
374 | |||
375 | META_COLLECTOR(int_sk_wmem_alloc) | ||
376 | { | ||
377 | SKIP_NONLOCAL(skb); | ||
378 | dst->value = atomic_read(&skb->sk->sk_wmem_alloc); | ||
379 | } | ||
380 | |||
381 | META_COLLECTOR(int_sk_omem_alloc) | ||
382 | { | ||
383 | SKIP_NONLOCAL(skb); | ||
384 | dst->value = atomic_read(&skb->sk->sk_omem_alloc); | ||
385 | } | ||
386 | |||
387 | META_COLLECTOR(int_sk_rcv_qlen) | ||
388 | { | ||
389 | SKIP_NONLOCAL(skb); | ||
390 | dst->value = skb->sk->sk_receive_queue.qlen; | ||
391 | } | ||
392 | |||
393 | META_COLLECTOR(int_sk_snd_qlen) | ||
394 | { | ||
395 | SKIP_NONLOCAL(skb); | ||
396 | dst->value = skb->sk->sk_write_queue.qlen; | ||
397 | } | ||
398 | |||
399 | META_COLLECTOR(int_sk_wmem_queued) | ||
400 | { | ||
401 | SKIP_NONLOCAL(skb); | ||
402 | dst->value = skb->sk->sk_wmem_queued; | ||
403 | } | ||
404 | |||
405 | META_COLLECTOR(int_sk_fwd_alloc) | ||
406 | { | ||
407 | SKIP_NONLOCAL(skb); | ||
408 | dst->value = skb->sk->sk_forward_alloc; | ||
409 | } | ||
410 | |||
411 | META_COLLECTOR(int_sk_sndbuf) | ||
412 | { | ||
413 | SKIP_NONLOCAL(skb); | ||
414 | dst->value = skb->sk->sk_sndbuf; | ||
415 | } | ||
416 | |||
417 | META_COLLECTOR(int_sk_alloc) | ||
418 | { | ||
419 | SKIP_NONLOCAL(skb); | ||
420 | dst->value = skb->sk->sk_allocation; | ||
421 | } | ||
422 | |||
423 | META_COLLECTOR(int_sk_route_caps) | ||
424 | { | ||
425 | SKIP_NONLOCAL(skb); | ||
426 | dst->value = skb->sk->sk_route_caps; | ||
427 | } | ||
428 | |||
429 | META_COLLECTOR(int_sk_hashent) | ||
430 | { | ||
431 | SKIP_NONLOCAL(skb); | ||
432 | dst->value = skb->sk->sk_hashent; | ||
433 | } | ||
434 | |||
435 | META_COLLECTOR(int_sk_lingertime) | ||
436 | { | ||
437 | SKIP_NONLOCAL(skb); | ||
438 | dst->value = skb->sk->sk_lingertime / HZ; | ||
439 | } | ||
440 | |||
441 | META_COLLECTOR(int_sk_err_qlen) | ||
442 | { | ||
443 | SKIP_NONLOCAL(skb); | ||
444 | dst->value = skb->sk->sk_error_queue.qlen; | ||
445 | } | ||
446 | |||
447 | META_COLLECTOR(int_sk_ack_bl) | ||
448 | { | ||
449 | SKIP_NONLOCAL(skb); | ||
450 | dst->value = skb->sk->sk_ack_backlog; | ||
451 | } | ||
452 | |||
453 | META_COLLECTOR(int_sk_max_ack_bl) | ||
454 | { | ||
455 | SKIP_NONLOCAL(skb); | ||
456 | dst->value = skb->sk->sk_max_ack_backlog; | ||
457 | } | ||
458 | |||
459 | META_COLLECTOR(int_sk_prio) | ||
460 | { | ||
461 | SKIP_NONLOCAL(skb); | ||
462 | dst->value = skb->sk->sk_priority; | ||
463 | } | ||
464 | |||
465 | META_COLLECTOR(int_sk_rcvlowat) | ||
466 | { | ||
467 | SKIP_NONLOCAL(skb); | ||
468 | dst->value = skb->sk->sk_rcvlowat; | ||
469 | } | ||
470 | |||
471 | META_COLLECTOR(int_sk_rcvtimeo) | ||
472 | { | ||
473 | SKIP_NONLOCAL(skb); | ||
474 | dst->value = skb->sk->sk_rcvtimeo / HZ; | ||
475 | } | ||
476 | |||
477 | META_COLLECTOR(int_sk_sndtimeo) | ||
478 | { | ||
479 | SKIP_NONLOCAL(skb); | ||
480 | dst->value = skb->sk->sk_sndtimeo / HZ; | ||
481 | } | ||
482 | |||
483 | META_COLLECTOR(int_sk_sendmsg_off) | ||
484 | { | ||
485 | SKIP_NONLOCAL(skb); | ||
486 | dst->value = skb->sk->sk_sndmsg_off; | ||
487 | } | ||
488 | |||
489 | META_COLLECTOR(int_sk_write_pend) | ||
490 | { | ||
491 | SKIP_NONLOCAL(skb); | ||
492 | dst->value = skb->sk->sk_write_pending; | ||
493 | } | ||
494 | |||
495 | /************************************************************************** | ||
287 | * Meta value collectors assignment table | 496 | * Meta value collectors assignment table |
288 | **************************************************************************/ | 497 | **************************************************************************/ |
289 | 498 | ||
@@ -293,41 +502,75 @@ struct meta_ops | |||
293 | struct meta_value *, struct meta_obj *, int *); | 502 | struct meta_value *, struct meta_obj *, int *); |
294 | }; | 503 | }; |
295 | 504 | ||
505 | #define META_ID(name) TCF_META_ID_##name | ||
506 | #define META_FUNC(name) { .get = meta_##name } | ||
507 | |||
296 | /* Meta value operations table listing all meta value collectors and | 508 | /* Meta value operations table listing all meta value collectors and |
297 | * assigns them to a type and meta id. */ | 509 | * assigns them to a type and meta id. */ |
298 | static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { | 510 | static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { |
299 | [TCF_META_TYPE_VAR] = { | 511 | [TCF_META_TYPE_VAR] = { |
300 | [TCF_META_ID_DEV] = { .get = meta_var_dev }, | 512 | [META_ID(DEV)] = META_FUNC(var_dev), |
301 | [TCF_META_ID_INDEV] = { .get = meta_var_indev }, | 513 | [META_ID(INDEV)] = META_FUNC(var_indev), |
302 | [TCF_META_ID_REALDEV] = { .get = meta_var_realdev } | 514 | [META_ID(REALDEV)] = META_FUNC(var_realdev), |
515 | [META_ID(SK_BOUND_IF)] = META_FUNC(var_sk_bound_if), | ||
303 | }, | 516 | }, |
304 | [TCF_META_TYPE_INT] = { | 517 | [TCF_META_TYPE_INT] = { |
305 | [TCF_META_ID_RANDOM] = { .get = meta_int_random }, | 518 | [META_ID(RANDOM)] = META_FUNC(int_random), |
306 | [TCF_META_ID_LOADAVG_0] = { .get = meta_int_loadavg_0 }, | 519 | [META_ID(LOADAVG_0)] = META_FUNC(int_loadavg_0), |
307 | [TCF_META_ID_LOADAVG_1] = { .get = meta_int_loadavg_1 }, | 520 | [META_ID(LOADAVG_1)] = META_FUNC(int_loadavg_1), |
308 | [TCF_META_ID_LOADAVG_2] = { .get = meta_int_loadavg_2 }, | 521 | [META_ID(LOADAVG_2)] = META_FUNC(int_loadavg_2), |
309 | [TCF_META_ID_DEV] = { .get = meta_int_dev }, | 522 | [META_ID(DEV)] = META_FUNC(int_dev), |
310 | [TCF_META_ID_INDEV] = { .get = meta_int_indev }, | 523 | [META_ID(INDEV)] = META_FUNC(int_indev), |
311 | [TCF_META_ID_REALDEV] = { .get = meta_int_realdev }, | 524 | [META_ID(REALDEV)] = META_FUNC(int_realdev), |
312 | [TCF_META_ID_PRIORITY] = { .get = meta_int_priority }, | 525 | [META_ID(PRIORITY)] = META_FUNC(int_priority), |
313 | [TCF_META_ID_PROTOCOL] = { .get = meta_int_protocol }, | 526 | [META_ID(PROTOCOL)] = META_FUNC(int_protocol), |
314 | [TCF_META_ID_SECURITY] = { .get = meta_int_security }, | 527 | [META_ID(SECURITY)] = META_FUNC(int_security), |
315 | [TCF_META_ID_PKTTYPE] = { .get = meta_int_pkttype }, | 528 | [META_ID(PKTTYPE)] = META_FUNC(int_pkttype), |
316 | [TCF_META_ID_PKTLEN] = { .get = meta_int_pktlen }, | 529 | [META_ID(PKTLEN)] = META_FUNC(int_pktlen), |
317 | [TCF_META_ID_DATALEN] = { .get = meta_int_datalen }, | 530 | [META_ID(DATALEN)] = META_FUNC(int_datalen), |
318 | [TCF_META_ID_MACLEN] = { .get = meta_int_maclen }, | 531 | [META_ID(MACLEN)] = META_FUNC(int_maclen), |
319 | #ifdef CONFIG_NETFILTER | 532 | #ifdef CONFIG_NETFILTER |
320 | [TCF_META_ID_NFMARK] = { .get = meta_int_nfmark }, | 533 | [META_ID(NFMARK)] = META_FUNC(int_nfmark), |
321 | #endif | 534 | #endif |
322 | [TCF_META_ID_TCINDEX] = { .get = meta_int_tcindex }, | 535 | [META_ID(TCINDEX)] = META_FUNC(int_tcindex), |
323 | #ifdef CONFIG_NET_CLS_ACT | 536 | #ifdef CONFIG_NET_CLS_ACT |
324 | [TCF_META_ID_TCVERDICT] = { .get = meta_int_tcverd }, | 537 | [META_ID(TCVERDICT)] = META_FUNC(int_tcverd), |
325 | [TCF_META_ID_TCCLASSID] = { .get = meta_int_tcclassid }, | 538 | [META_ID(TCCLASSID)] = META_FUNC(int_tcclassid), |
326 | #endif | 539 | #endif |
327 | #ifdef CONFIG_NET_CLS_ROUTE | 540 | #ifdef CONFIG_NET_CLS_ROUTE |
328 | [TCF_META_ID_RTCLASSID] = { .get = meta_int_rtclassid }, | 541 | [META_ID(RTCLASSID)] = META_FUNC(int_rtclassid), |
329 | #endif | 542 | #endif |
330 | [TCF_META_ID_RTIIF] = { .get = meta_int_rtiif } | 543 | [META_ID(RTIIF)] = META_FUNC(int_rtiif), |
544 | [META_ID(SK_FAMILY)] = META_FUNC(int_sk_family), | ||
545 | [META_ID(SK_STATE)] = META_FUNC(int_sk_state), | ||
546 | [META_ID(SK_REUSE)] = META_FUNC(int_sk_reuse), | ||
547 | [META_ID(SK_BOUND_IF)] = META_FUNC(int_sk_bound_if), | ||
548 | [META_ID(SK_REFCNT)] = META_FUNC(int_sk_refcnt), | ||
549 | [META_ID(SK_RCVBUF)] = META_FUNC(int_sk_rcvbuf), | ||
550 | [META_ID(SK_SNDBUF)] = META_FUNC(int_sk_sndbuf), | ||
551 | [META_ID(SK_SHUTDOWN)] = META_FUNC(int_sk_shutdown), | ||
552 | [META_ID(SK_PROTO)] = META_FUNC(int_sk_proto), | ||
553 | [META_ID(SK_TYPE)] = META_FUNC(int_sk_type), | ||
554 | [META_ID(SK_RMEM_ALLOC)] = META_FUNC(int_sk_rmem_alloc), | ||
555 | [META_ID(SK_WMEM_ALLOC)] = META_FUNC(int_sk_wmem_alloc), | ||
556 | [META_ID(SK_OMEM_ALLOC)] = META_FUNC(int_sk_omem_alloc), | ||
557 | [META_ID(SK_WMEM_QUEUED)] = META_FUNC(int_sk_wmem_queued), | ||
558 | [META_ID(SK_RCV_QLEN)] = META_FUNC(int_sk_rcv_qlen), | ||
559 | [META_ID(SK_SND_QLEN)] = META_FUNC(int_sk_snd_qlen), | ||
560 | [META_ID(SK_ERR_QLEN)] = META_FUNC(int_sk_err_qlen), | ||
561 | [META_ID(SK_FORWARD_ALLOCS)] = META_FUNC(int_sk_fwd_alloc), | ||
562 | [META_ID(SK_ALLOCS)] = META_FUNC(int_sk_alloc), | ||
563 | [META_ID(SK_ROUTE_CAPS)] = META_FUNC(int_sk_route_caps), | ||
564 | [META_ID(SK_HASHENT)] = META_FUNC(int_sk_hashent), | ||
565 | [META_ID(SK_LINGERTIME)] = META_FUNC(int_sk_lingertime), | ||
566 | [META_ID(SK_ACK_BACKLOG)] = META_FUNC(int_sk_ack_bl), | ||
567 | [META_ID(SK_MAX_ACK_BACKLOG)] = META_FUNC(int_sk_max_ack_bl), | ||
568 | [META_ID(SK_PRIO)] = META_FUNC(int_sk_prio), | ||
569 | [META_ID(SK_RCVLOWAT)] = META_FUNC(int_sk_rcvlowat), | ||
570 | [META_ID(SK_RCVTIMEO)] = META_FUNC(int_sk_rcvtimeo), | ||
571 | [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo), | ||
572 | [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), | ||
573 | [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), | ||
331 | } | 574 | } |
332 | }; | 575 | }; |
333 | 576 | ||
@@ -396,9 +639,9 @@ static int meta_int_compare(struct meta_obj *a, struct meta_obj *b) | |||
396 | /* Let gcc optimize it, the unlikely is not really based on | 639 | /* Let gcc optimize it, the unlikely is not really based on |
397 | * some numbers but jump free code for mismatches seems | 640 | * some numbers but jump free code for mismatches seems |
398 | * more logical. */ | 641 | * more logical. */ |
399 | if (unlikely(a == b)) | 642 | if (unlikely(a->value == b->value)) |
400 | return 0; | 643 | return 0; |
401 | else if (a < b) | 644 | else if (a->value < b->value) |
402 | return -1; | 645 | return -1; |
403 | else | 646 | else |
404 | return 1; | 647 | return 1; |