diff options
682 files changed, 10656 insertions, 6309 deletions
@@ -1856,7 +1856,7 @@ E: rfkoenig@immd4.informatik.uni-erlangen.de | |||
1856 | D: The Linux Support Team Erlangen | 1856 | D: The Linux Support Team Erlangen |
1857 | 1857 | ||
1858 | N: Andreas Koensgen | 1858 | N: Andreas Koensgen |
1859 | E: ajk@iehk.rwth-aachen.de | 1859 | E: ajk@comnets.uni-bremen.de |
1860 | D: 6pack driver for AX.25 | 1860 | D: 6pack driver for AX.25 |
1861 | 1861 | ||
1862 | N: Harald Koerfgen | 1862 | N: Harald Koerfgen |
diff --git a/Documentation/RCU/rculist_nulls.txt b/Documentation/RCU/rculist_nulls.txt index 93cb28d05dcd..18f9651ff23d 100644 --- a/Documentation/RCU/rculist_nulls.txt +++ b/Documentation/RCU/rculist_nulls.txt | |||
@@ -83,11 +83,12 @@ not detect it missed following items in original chain. | |||
83 | obj = kmem_cache_alloc(...); | 83 | obj = kmem_cache_alloc(...); |
84 | lock_chain(); // typically a spin_lock() | 84 | lock_chain(); // typically a spin_lock() |
85 | obj->key = key; | 85 | obj->key = key; |
86 | atomic_inc(&obj->refcnt); | ||
87 | /* | 86 | /* |
88 | * we need to make sure obj->key is updated before obj->next | 87 | * we need to make sure obj->key is updated before obj->next |
88 | * or obj->refcnt | ||
89 | */ | 89 | */ |
90 | smp_wmb(); | 90 | smp_wmb(); |
91 | atomic_set(&obj->refcnt, 1); | ||
91 | hlist_add_head_rcu(&obj->obj_node, list); | 92 | hlist_add_head_rcu(&obj->obj_node, list); |
92 | unlock_chain(); // typically a spin_unlock() | 93 | unlock_chain(); // typically a spin_unlock() |
93 | 94 | ||
@@ -159,6 +160,10 @@ out: | |||
159 | obj = kmem_cache_alloc(cachep); | 160 | obj = kmem_cache_alloc(cachep); |
160 | lock_chain(); // typically a spin_lock() | 161 | lock_chain(); // typically a spin_lock() |
161 | obj->key = key; | 162 | obj->key = key; |
163 | /* | ||
164 | * changes to obj->key must be visible before refcnt one | ||
165 | */ | ||
166 | smp_wmb(); | ||
162 | atomic_set(&obj->refcnt, 1); | 167 | atomic_set(&obj->refcnt, 1); |
163 | /* | 168 | /* |
164 | * insert obj in RCU way (readers might be traversing chain) | 169 | * insert obj in RCU way (readers might be traversing chain) |
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c index f688eba87704..6a5be5d5c8e4 100644 --- a/Documentation/connector/cn_test.c +++ b/Documentation/connector/cn_test.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cn_test.c | 2 | * cn_test.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -194,5 +194,5 @@ module_init(cn_test_init); | |||
194 | module_exit(cn_test_fini); | 194 | module_exit(cn_test_fini); |
195 | 195 | ||
196 | MODULE_LICENSE("GPL"); | 196 | MODULE_LICENSE("GPL"); |
197 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | 197 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
198 | MODULE_DESCRIPTION("Connector's test module"); | 198 | MODULE_DESCRIPTION("Connector's test module"); |
diff --git a/Documentation/connector/ucon.c b/Documentation/connector/ucon.c index d738cde2a8d5..c5092ad0ce4b 100644 --- a/Documentation/connector/ucon.c +++ b/Documentation/connector/ucon.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * ucon.c | 2 | * ucon.c |
3 | * | 3 | * |
4 | * Copyright (c) 2004+ Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * Copyright (c) 2004+ Evgeniy Polyakov <zbr@ioremap.net> |
5 | * | 5 | * |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt index 82132169d47a..60120fb3b961 100644 --- a/Documentation/driver-model/driver.txt +++ b/Documentation/driver-model/driver.txt | |||
@@ -207,8 +207,8 @@ Attributes | |||
207 | ~~~~~~~~~~ | 207 | ~~~~~~~~~~ |
208 | struct driver_attribute { | 208 | struct driver_attribute { |
209 | struct attribute attr; | 209 | struct attribute attr; |
210 | ssize_t (*show)(struct device_driver *, char * buf, size_t count, loff_t off); | 210 | ssize_t (*show)(struct device_driver *driver, char *buf); |
211 | ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off); | 211 | ssize_t (*store)(struct device_driver *, const char * buf, size_t count); |
212 | }; | 212 | }; |
213 | 213 | ||
214 | Device drivers can export attributes via their sysfs directories. | 214 | Device drivers can export attributes via their sysfs directories. |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index d77fbd8b79ac..dd1a6d4bb747 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1720,8 +1720,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1720 | oprofile.cpu_type= Force an oprofile cpu type | 1720 | oprofile.cpu_type= Force an oprofile cpu type |
1721 | This might be useful if you have an older oprofile | 1721 | This might be useful if you have an older oprofile |
1722 | userland or if you want common events. | 1722 | userland or if you want common events. |
1723 | Format: { archperfmon } | 1723 | Format: { arch_perfmon } |
1724 | archperfmon: [X86] Force use of architectural | 1724 | arch_perfmon: [X86] Force use of architectural |
1725 | perfmon on Intel CPUs instead of the | 1725 | perfmon on Intel CPUs instead of the |
1726 | CPU specific event set. | 1726 | CPU specific event set. |
1727 | 1727 | ||
diff --git a/Documentation/networking/6pack.txt b/Documentation/networking/6pack.txt index d0777a1200e1..8f339428fdf4 100644 --- a/Documentation/networking/6pack.txt +++ b/Documentation/networking/6pack.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | This is the 6pack-mini-HOWTO, written by | 1 | This is the 6pack-mini-HOWTO, written by |
2 | 2 | ||
3 | Andreas Könsgen DG3KQ | 3 | Andreas Könsgen DG3KQ |
4 | Internet: ajk@iehk.rwth-aachen.de | 4 | Internet: ajk@comnets.uni-bremen.de |
5 | AMPR-net: dg3kq@db0pra.ampr.org | 5 | AMPR-net: dg3kq@db0pra.ampr.org |
6 | AX.25: dg3kq@db0ach.#nrw.deu.eu | 6 | AX.25: dg3kq@db0ach.#nrw.deu.eu |
7 | 7 | ||
diff --git a/Documentation/scheduler/sched-rt-group.txt b/Documentation/scheduler/sched-rt-group.txt index 1df7f9cdab05..86eabe6c3419 100644 --- a/Documentation/scheduler/sched-rt-group.txt +++ b/Documentation/scheduler/sched-rt-group.txt | |||
@@ -73,7 +73,7 @@ The remaining CPU time will be used for user input and other tasks. Because | |||
73 | realtime tasks have explicitly allocated the CPU time they need to perform | 73 | realtime tasks have explicitly allocated the CPU time they need to perform |
74 | their tasks, buffer underruns in the graphics or audio can be eliminated. | 74 | their tasks, buffer underruns in the graphics or audio can be eliminated. |
75 | 75 | ||
76 | NOTE: the above example is not fully implemented as of yet (2.6.25). We still | 76 | NOTE: the above example is not fully implemented yet. We still |
77 | lack an EDF scheduler to make non-uniform periods usable. | 77 | lack an EDF scheduler to make non-uniform periods usable. |
78 | 78 | ||
79 | 79 | ||
@@ -140,14 +140,15 @@ The other option is: | |||
140 | 140 | ||
141 | .o CONFIG_CGROUP_SCHED (aka "Basis for grouping tasks" = "Control groups") | 141 | .o CONFIG_CGROUP_SCHED (aka "Basis for grouping tasks" = "Control groups") |
142 | 142 | ||
143 | This uses the /cgroup virtual file system and "/cgroup/<cgroup>/cpu.rt_runtime_us" | 143 | This uses the /cgroup virtual file system and |
144 | to control the CPU time reserved for each control group instead. | 144 | "/cgroup/<cgroup>/cpu.rt_runtime_us" to control the CPU time reserved for each |
145 | control group instead. | ||
145 | 146 | ||
146 | For more information on working with control groups, you should read | 147 | For more information on working with control groups, you should read |
147 | Documentation/cgroups/cgroups.txt as well. | 148 | Documentation/cgroups/cgroups.txt as well. |
148 | 149 | ||
149 | Group settings are checked against the following limits in order to keep the configuration | 150 | Group settings are checked against the following limits in order to keep the |
150 | schedulable: | 151 | configuration schedulable: |
151 | 152 | ||
152 | \Sum_{i} runtime_{i} / global_period <= global_runtime / global_period | 153 | \Sum_{i} runtime_{i} / global_period <= global_runtime / global_period |
153 | 154 | ||
@@ -189,7 +190,7 @@ Implementing SCHED_EDF might take a while to complete. Priority Inheritance is | |||
189 | the biggest challenge as the current linux PI infrastructure is geared towards | 190 | the biggest challenge as the current linux PI infrastructure is geared towards |
190 | the limited static priority levels 0-99. With deadline scheduling you need to | 191 | the limited static priority levels 0-99. With deadline scheduling you need to |
191 | do deadline inheritance (since priority is inversely proportional to the | 192 | do deadline inheritance (since priority is inversely proportional to the |
192 | deadline delta (deadline - now). | 193 | deadline delta (deadline - now)). |
193 | 194 | ||
194 | This means the whole PI machinery will have to be reworked - and that is one of | 195 | This means the whole PI machinery will have to be reworked - and that is one of |
195 | the most complex pieces of code we have. | 196 | the most complex pieces of code we have. |
diff --git a/Documentation/x86/00-INDEX b/Documentation/x86/00-INDEX index dbe3377754af..f37b46d34861 100644 --- a/Documentation/x86/00-INDEX +++ b/Documentation/x86/00-INDEX | |||
@@ -2,3 +2,5 @@ | |||
2 | - this file | 2 | - this file |
3 | mtrr.txt | 3 | mtrr.txt |
4 | - how to use x86 Memory Type Range Registers to increase performance | 4 | - how to use x86 Memory Type Range Registers to increase performance |
5 | exception-tables.txt | ||
6 | - why and how Linux kernel uses exception tables on x86 | ||
diff --git a/Documentation/exception.txt b/Documentation/x86/exception-tables.txt index 2d5aded64247..32901aa36f0a 100644 --- a/Documentation/exception.txt +++ b/Documentation/x86/exception-tables.txt | |||
@@ -1,123 +1,123 @@ | |||
1 | Kernel level exception handling in Linux 2.1.8 | 1 | Kernel level exception handling in Linux |
2 | Commentary by Joerg Pommnitz <joerg@raleigh.ibm.com> | 2 | Commentary by Joerg Pommnitz <joerg@raleigh.ibm.com> |
3 | 3 | ||
4 | When a process runs in kernel mode, it often has to access user | 4 | When a process runs in kernel mode, it often has to access user |
5 | mode memory whose address has been passed by an untrusted program. | 5 | mode memory whose address has been passed by an untrusted program. |
6 | To protect itself the kernel has to verify this address. | 6 | To protect itself the kernel has to verify this address. |
7 | 7 | ||
8 | In older versions of Linux this was done with the | 8 | In older versions of Linux this was done with the |
9 | int verify_area(int type, const void * addr, unsigned long size) | 9 | int verify_area(int type, const void * addr, unsigned long size) |
10 | function (which has since been replaced by access_ok()). | 10 | function (which has since been replaced by access_ok()). |
11 | 11 | ||
12 | This function verified that the memory area starting at address | 12 | This function verified that the memory area starting at address |
13 | 'addr' and of size 'size' was accessible for the operation specified | 13 | 'addr' and of size 'size' was accessible for the operation specified |
14 | in type (read or write). To do this, verify_read had to look up the | 14 | in type (read or write). To do this, verify_read had to look up the |
15 | virtual memory area (vma) that contained the address addr. In the | 15 | virtual memory area (vma) that contained the address addr. In the |
16 | normal case (correctly working program), this test was successful. | 16 | normal case (correctly working program), this test was successful. |
17 | It only failed for a few buggy programs. In some kernel profiling | 17 | It only failed for a few buggy programs. In some kernel profiling |
18 | tests, this normally unneeded verification used up a considerable | 18 | tests, this normally unneeded verification used up a considerable |
19 | amount of time. | 19 | amount of time. |
20 | 20 | ||
21 | To overcome this situation, Linus decided to let the virtual memory | 21 | To overcome this situation, Linus decided to let the virtual memory |
22 | hardware present in every Linux-capable CPU handle this test. | 22 | hardware present in every Linux-capable CPU handle this test. |
23 | 23 | ||
24 | How does this work? | 24 | How does this work? |
25 | 25 | ||
26 | Whenever the kernel tries to access an address that is currently not | 26 | Whenever the kernel tries to access an address that is currently not |
27 | accessible, the CPU generates a page fault exception and calls the | 27 | accessible, the CPU generates a page fault exception and calls the |
28 | page fault handler | 28 | page fault handler |
29 | 29 | ||
30 | void do_page_fault(struct pt_regs *regs, unsigned long error_code) | 30 | void do_page_fault(struct pt_regs *regs, unsigned long error_code) |
31 | 31 | ||
32 | in arch/i386/mm/fault.c. The parameters on the stack are set up by | 32 | in arch/x86/mm/fault.c. The parameters on the stack are set up by |
33 | the low level assembly glue in arch/i386/kernel/entry.S. The parameter | 33 | the low level assembly glue in arch/x86/kernel/entry_32.S. The parameter |
34 | regs is a pointer to the saved registers on the stack, error_code | 34 | regs is a pointer to the saved registers on the stack, error_code |
35 | contains a reason code for the exception. | 35 | contains a reason code for the exception. |
36 | 36 | ||
37 | do_page_fault first obtains the unaccessible address from the CPU | 37 | do_page_fault first obtains the unaccessible address from the CPU |
38 | control register CR2. If the address is within the virtual address | 38 | control register CR2. If the address is within the virtual address |
39 | space of the process, the fault probably occurred, because the page | 39 | space of the process, the fault probably occurred, because the page |
40 | was not swapped in, write protected or something similar. However, | 40 | was not swapped in, write protected or something similar. However, |
41 | we are interested in the other case: the address is not valid, there | 41 | we are interested in the other case: the address is not valid, there |
42 | is no vma that contains this address. In this case, the kernel jumps | 42 | is no vma that contains this address. In this case, the kernel jumps |
43 | to the bad_area label. | 43 | to the bad_area label. |
44 | 44 | ||
45 | There it uses the address of the instruction that caused the exception | 45 | There it uses the address of the instruction that caused the exception |
46 | (i.e. regs->eip) to find an address where the execution can continue | 46 | (i.e. regs->eip) to find an address where the execution can continue |
47 | (fixup). If this search is successful, the fault handler modifies the | 47 | (fixup). If this search is successful, the fault handler modifies the |
48 | return address (again regs->eip) and returns. The execution will | 48 | return address (again regs->eip) and returns. The execution will |
49 | continue at the address in fixup. | 49 | continue at the address in fixup. |
50 | 50 | ||
51 | Where does fixup point to? | 51 | Where does fixup point to? |
52 | 52 | ||
53 | Since we jump to the contents of fixup, fixup obviously points | 53 | Since we jump to the contents of fixup, fixup obviously points |
54 | to executable code. This code is hidden inside the user access macros. | 54 | to executable code. This code is hidden inside the user access macros. |
55 | I have picked the get_user macro defined in include/asm/uaccess.h as an | 55 | I have picked the get_user macro defined in arch/x86/include/asm/uaccess.h |
56 | example. The definition is somewhat hard to follow, so let's peek at | 56 | as an example. The definition is somewhat hard to follow, so let's peek at |
57 | the code generated by the preprocessor and the compiler. I selected | 57 | the code generated by the preprocessor and the compiler. I selected |
58 | the get_user call in drivers/char/console.c for a detailed examination. | 58 | the get_user call in drivers/char/sysrq.c for a detailed examination. |
59 | 59 | ||
60 | The original code in console.c line 1405: | 60 | The original code in sysrq.c line 587: |
61 | get_user(c, buf); | 61 | get_user(c, buf); |
62 | 62 | ||
63 | The preprocessor output (edited to become somewhat readable): | 63 | The preprocessor output (edited to become somewhat readable): |
64 | 64 | ||
65 | ( | 65 | ( |
66 | { | 66 | { |
67 | long __gu_err = - 14 , __gu_val = 0; | 67 | long __gu_err = - 14 , __gu_val = 0; |
68 | const __typeof__(*( ( buf ) )) *__gu_addr = ((buf)); | 68 | const __typeof__(*( ( buf ) )) *__gu_addr = ((buf)); |
69 | if (((((0 + current_set[0])->tss.segment) == 0x18 ) || | 69 | if (((((0 + current_set[0])->tss.segment) == 0x18 ) || |
70 | (((sizeof(*(buf))) <= 0xC0000000UL) && | 70 | (((sizeof(*(buf))) <= 0xC0000000UL) && |
71 | ((unsigned long)(__gu_addr ) <= 0xC0000000UL - (sizeof(*(buf))))))) | 71 | ((unsigned long)(__gu_addr ) <= 0xC0000000UL - (sizeof(*(buf))))))) |
72 | do { | 72 | do { |
73 | __gu_err = 0; | 73 | __gu_err = 0; |
74 | switch ((sizeof(*(buf)))) { | 74 | switch ((sizeof(*(buf)))) { |
75 | case 1: | 75 | case 1: |
76 | __asm__ __volatile__( | 76 | __asm__ __volatile__( |
77 | "1: mov" "b" " %2,%" "b" "1\n" | 77 | "1: mov" "b" " %2,%" "b" "1\n" |
78 | "2:\n" | 78 | "2:\n" |
79 | ".section .fixup,\"ax\"\n" | 79 | ".section .fixup,\"ax\"\n" |
80 | "3: movl %3,%0\n" | 80 | "3: movl %3,%0\n" |
81 | " xor" "b" " %" "b" "1,%" "b" "1\n" | 81 | " xor" "b" " %" "b" "1,%" "b" "1\n" |
82 | " jmp 2b\n" | 82 | " jmp 2b\n" |
83 | ".section __ex_table,\"a\"\n" | 83 | ".section __ex_table,\"a\"\n" |
84 | " .align 4\n" | 84 | " .align 4\n" |
85 | " .long 1b,3b\n" | 85 | " .long 1b,3b\n" |
86 | ".text" : "=r"(__gu_err), "=q" (__gu_val): "m"((*(struct __large_struct *) | 86 | ".text" : "=r"(__gu_err), "=q" (__gu_val): "m"((*(struct __large_struct *) |
87 | ( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err )) ; | 87 | ( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err )) ; |
88 | break; | 88 | break; |
89 | case 2: | 89 | case 2: |
90 | __asm__ __volatile__( | 90 | __asm__ __volatile__( |
91 | "1: mov" "w" " %2,%" "w" "1\n" | 91 | "1: mov" "w" " %2,%" "w" "1\n" |
92 | "2:\n" | 92 | "2:\n" |
93 | ".section .fixup,\"ax\"\n" | 93 | ".section .fixup,\"ax\"\n" |
94 | "3: movl %3,%0\n" | 94 | "3: movl %3,%0\n" |
95 | " xor" "w" " %" "w" "1,%" "w" "1\n" | 95 | " xor" "w" " %" "w" "1,%" "w" "1\n" |
96 | " jmp 2b\n" | 96 | " jmp 2b\n" |
97 | ".section __ex_table,\"a\"\n" | 97 | ".section __ex_table,\"a\"\n" |
98 | " .align 4\n" | 98 | " .align 4\n" |
99 | " .long 1b,3b\n" | 99 | " .long 1b,3b\n" |
100 | ".text" : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *) | 100 | ".text" : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *) |
101 | ( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err )); | 101 | ( __gu_addr )) ), "i"(- 14 ), "0"( __gu_err )); |
102 | break; | 102 | break; |
103 | case 4: | 103 | case 4: |
104 | __asm__ __volatile__( | 104 | __asm__ __volatile__( |
105 | "1: mov" "l" " %2,%" "" "1\n" | 105 | "1: mov" "l" " %2,%" "" "1\n" |
106 | "2:\n" | 106 | "2:\n" |
107 | ".section .fixup,\"ax\"\n" | 107 | ".section .fixup,\"ax\"\n" |
108 | "3: movl %3,%0\n" | 108 | "3: movl %3,%0\n" |
109 | " xor" "l" " %" "" "1,%" "" "1\n" | 109 | " xor" "l" " %" "" "1,%" "" "1\n" |
110 | " jmp 2b\n" | 110 | " jmp 2b\n" |
111 | ".section __ex_table,\"a\"\n" | 111 | ".section __ex_table,\"a\"\n" |
112 | " .align 4\n" " .long 1b,3b\n" | 112 | " .align 4\n" " .long 1b,3b\n" |
113 | ".text" : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *) | 113 | ".text" : "=r"(__gu_err), "=r" (__gu_val) : "m"((*(struct __large_struct *) |
114 | ( __gu_addr )) ), "i"(- 14 ), "0"(__gu_err)); | 114 | ( __gu_addr )) ), "i"(- 14 ), "0"(__gu_err)); |
115 | break; | 115 | break; |
116 | default: | 116 | default: |
117 | (__gu_val) = __get_user_bad(); | 117 | (__gu_val) = __get_user_bad(); |
118 | } | 118 | } |
119 | } while (0) ; | 119 | } while (0) ; |
120 | ((c)) = (__typeof__(*((buf))))__gu_val; | 120 | ((c)) = (__typeof__(*((buf))))__gu_val; |
121 | __gu_err; | 121 | __gu_err; |
122 | } | 122 | } |
123 | ); | 123 | ); |
@@ -127,12 +127,12 @@ see what code gcc generates: | |||
127 | 127 | ||
128 | > xorl %edx,%edx | 128 | > xorl %edx,%edx |
129 | > movl current_set,%eax | 129 | > movl current_set,%eax |
130 | > cmpl $24,788(%eax) | 130 | > cmpl $24,788(%eax) |
131 | > je .L1424 | 131 | > je .L1424 |
132 | > cmpl $-1073741825,64(%esp) | 132 | > cmpl $-1073741825,64(%esp) |
133 | > ja .L1423 | 133 | > ja .L1423 |
134 | > .L1424: | 134 | > .L1424: |
135 | > movl %edx,%eax | 135 | > movl %edx,%eax |
136 | > movl 64(%esp),%ebx | 136 | > movl 64(%esp),%ebx |
137 | > #APP | 137 | > #APP |
138 | > 1: movb (%ebx),%dl /* this is the actual user access */ | 138 | > 1: movb (%ebx),%dl /* this is the actual user access */ |
@@ -149,17 +149,17 @@ see what code gcc generates: | |||
149 | > .L1423: | 149 | > .L1423: |
150 | > movzbl %dl,%esi | 150 | > movzbl %dl,%esi |
151 | 151 | ||
152 | The optimizer does a good job and gives us something we can actually | 152 | The optimizer does a good job and gives us something we can actually |
153 | understand. Can we? The actual user access is quite obvious. Thanks | 153 | understand. Can we? The actual user access is quite obvious. Thanks |
154 | to the unified address space we can just access the address in user | 154 | to the unified address space we can just access the address in user |
155 | memory. But what does the .section stuff do????? | 155 | memory. But what does the .section stuff do????? |
156 | 156 | ||
157 | To understand this we have to look at the final kernel: | 157 | To understand this we have to look at the final kernel: |
158 | 158 | ||
159 | > objdump --section-headers vmlinux | 159 | > objdump --section-headers vmlinux |
160 | > | 160 | > |
161 | > vmlinux: file format elf32-i386 | 161 | > vmlinux: file format elf32-i386 |
162 | > | 162 | > |
163 | > Sections: | 163 | > Sections: |
164 | > Idx Name Size VMA LMA File off Algn | 164 | > Idx Name Size VMA LMA File off Algn |
165 | > 0 .text 00098f40 c0100000 c0100000 00001000 2**4 | 165 | > 0 .text 00098f40 c0100000 c0100000 00001000 2**4 |
@@ -198,18 +198,18 @@ final kernel executable: | |||
198 | 198 | ||
199 | The whole user memory access is reduced to 10 x86 machine instructions. | 199 | The whole user memory access is reduced to 10 x86 machine instructions. |
200 | The instructions bracketed in the .section directives are no longer | 200 | The instructions bracketed in the .section directives are no longer |
201 | in the normal execution path. They are located in a different section | 201 | in the normal execution path. They are located in a different section |
202 | of the executable file: | 202 | of the executable file: |
203 | 203 | ||
204 | > objdump --disassemble --section=.fixup vmlinux | 204 | > objdump --disassemble --section=.fixup vmlinux |
205 | > | 205 | > |
206 | > c0199ff5 <.fixup+10b5> movl $0xfffffff2,%eax | 206 | > c0199ff5 <.fixup+10b5> movl $0xfffffff2,%eax |
207 | > c0199ffa <.fixup+10ba> xorb %dl,%dl | 207 | > c0199ffa <.fixup+10ba> xorb %dl,%dl |
208 | > c0199ffc <.fixup+10bc> jmp c017e7a7 <do_con_write+e3> | 208 | > c0199ffc <.fixup+10bc> jmp c017e7a7 <do_con_write+e3> |
209 | 209 | ||
210 | And finally: | 210 | And finally: |
211 | > objdump --full-contents --section=__ex_table vmlinux | 211 | > objdump --full-contents --section=__ex_table vmlinux |
212 | > | 212 | > |
213 | > c01aa7c4 93c017c0 e09f19c0 97c017c0 99c017c0 ................ | 213 | > c01aa7c4 93c017c0 e09f19c0 97c017c0 99c017c0 ................ |
214 | > c01aa7d4 f6c217c0 e99f19c0 a5e717c0 f59f19c0 ................ | 214 | > c01aa7d4 f6c217c0 e99f19c0 a5e717c0 f59f19c0 ................ |
215 | > c01aa7e4 080a18c0 01a019c0 0a0a18c0 04a019c0 ................ | 215 | > c01aa7e4 080a18c0 01a019c0 0a0a18c0 04a019c0 ................ |
@@ -235,8 +235,8 @@ sections in the ELF object file. So the instructions | |||
235 | ended up in the .fixup section of the object file and the addresses | 235 | ended up in the .fixup section of the object file and the addresses |
236 | .long 1b,3b | 236 | .long 1b,3b |
237 | ended up in the __ex_table section of the object file. 1b and 3b | 237 | ended up in the __ex_table section of the object file. 1b and 3b |
238 | are local labels. The local label 1b (1b stands for next label 1 | 238 | are local labels. The local label 1b (1b stands for next label 1 |
239 | backward) is the address of the instruction that might fault, i.e. | 239 | backward) is the address of the instruction that might fault, i.e. |
240 | in our case the address of the label 1 is c017e7a5: | 240 | in our case the address of the label 1 is c017e7a5: |
241 | the original assembly code: > 1: movb (%ebx),%dl | 241 | the original assembly code: > 1: movb (%ebx),%dl |
242 | and linked in vmlinux : > c017e7a5 <do_con_write+e1> movb (%ebx),%dl | 242 | and linked in vmlinux : > c017e7a5 <do_con_write+e1> movb (%ebx),%dl |
@@ -254,7 +254,7 @@ The assembly code | |||
254 | becomes the value pair | 254 | becomes the value pair |
255 | > c01aa7d4 c017c2f6 c0199fe9 c017e7a5 c0199ff5 ................ | 255 | > c01aa7d4 c017c2f6 c0199fe9 c017e7a5 c0199ff5 ................ |
256 | ^this is ^this is | 256 | ^this is ^this is |
257 | 1b 3b | 257 | 1b 3b |
258 | c017e7a5,c0199ff5 in the exception table of the kernel. | 258 | c017e7a5,c0199ff5 in the exception table of the kernel. |
259 | 259 | ||
260 | So, what actually happens if a fault from kernel mode with no suitable | 260 | So, what actually happens if a fault from kernel mode with no suitable |
@@ -266,9 +266,9 @@ vma occurs? | |||
266 | 3.) CPU calls do_page_fault | 266 | 3.) CPU calls do_page_fault |
267 | 4.) do page fault calls search_exception_table (regs->eip == c017e7a5); | 267 | 4.) do page fault calls search_exception_table (regs->eip == c017e7a5); |
268 | 5.) search_exception_table looks up the address c017e7a5 in the | 268 | 5.) search_exception_table looks up the address c017e7a5 in the |
269 | exception table (i.e. the contents of the ELF section __ex_table) | 269 | exception table (i.e. the contents of the ELF section __ex_table) |
270 | and returns the address of the associated fault handle code c0199ff5. | 270 | and returns the address of the associated fault handle code c0199ff5. |
271 | 6.) do_page_fault modifies its own return address to point to the fault | 271 | 6.) do_page_fault modifies its own return address to point to the fault |
272 | handle code and returns. | 272 | handle code and returns. |
273 | 7.) execution continues in the fault handling code. | 273 | 7.) execution continues in the fault handling code. |
274 | 8.) 8a) EAX becomes -EFAULT (== -14) | 274 | 8.) 8a) EAX becomes -EFAULT (== -14) |
diff --git a/MAINTAINERS b/MAINTAINERS index e4b1a3d596cc..ebc269152faf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -150,7 +150,7 @@ F: drivers/scsi/53c700* | |||
150 | 150 | ||
151 | 6PACK NETWORK DRIVER FOR AX.25 | 151 | 6PACK NETWORK DRIVER FOR AX.25 |
152 | P: Andreas Koensgen | 152 | P: Andreas Koensgen |
153 | M: ajk@iehk.rwth-aachen.de | 153 | M: ajk@comnets.uni-bremen.de |
154 | L: linux-hams@vger.kernel.org | 154 | L: linux-hams@vger.kernel.org |
155 | S: Maintained | 155 | S: Maintained |
156 | F: drivers/net/hamradio/6pack.c | 156 | F: drivers/net/hamradio/6pack.c |
@@ -1612,6 +1612,13 @@ S: Supported | |||
1612 | F: fs/configfs/ | 1612 | F: fs/configfs/ |
1613 | F: include/linux/configfs.h | 1613 | F: include/linux/configfs.h |
1614 | 1614 | ||
1615 | CONNECTOR | ||
1616 | P: Evgeniy Polyakov | ||
1617 | M: zbr@ioremap.net | ||
1618 | L: netdev@vger.kernel.org | ||
1619 | S: Maintained | ||
1620 | F: drivers/connector/ | ||
1621 | |||
1615 | CONTROL GROUPS (CGROUPS) | 1622 | CONTROL GROUPS (CGROUPS) |
1616 | P: Paul Menage | 1623 | P: Paul Menage |
1617 | M: menage@google.com | 1624 | M: menage@google.com |
@@ -3287,11 +3294,11 @@ F: include/linux/ivtv* | |||
3287 | 3294 | ||
3288 | JFS FILESYSTEM | 3295 | JFS FILESYSTEM |
3289 | P: Dave Kleikamp | 3296 | P: Dave Kleikamp |
3290 | M: shaggy@austin.ibm.com | 3297 | M: shaggy@linux.vnet.ibm.com |
3291 | L: jfs-discussion@lists.sourceforge.net | 3298 | L: jfs-discussion@lists.sourceforge.net |
3292 | W: http://jfs.sourceforge.net/ | 3299 | W: http://jfs.sourceforge.net/ |
3293 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git | 3300 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git |
3294 | S: Supported | 3301 | S: Maintained |
3295 | F: Documentation/filesystems/jfs.txt | 3302 | F: Documentation/filesystems/jfs.txt |
3296 | F: fs/jfs/ | 3303 | F: fs/jfs/ |
3297 | 3304 | ||
@@ -4089,6 +4096,7 @@ L: netfilter@vger.kernel.org | |||
4089 | L: coreteam@netfilter.org | 4096 | L: coreteam@netfilter.org |
4090 | W: http://www.netfilter.org/ | 4097 | W: http://www.netfilter.org/ |
4091 | W: http://www.iptables.org/ | 4098 | W: http://www.iptables.org/ |
4099 | T: git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git | ||
4092 | S: Supported | 4100 | S: Supported |
4093 | F: include/linux/netfilter* | 4101 | F: include/linux/netfilter* |
4094 | F: include/linux/netfilter/ | 4102 | F: include/linux/netfilter/ |
@@ -4407,7 +4415,7 @@ W: http://www.nongnu.org/orinoco/ | |||
4407 | S: Maintained | 4415 | S: Maintained |
4408 | F: drivers/net/wireless/orinoco/ | 4416 | F: drivers/net/wireless/orinoco/ |
4409 | 4417 | ||
4410 | OSD LIBRARY | 4418 | OSD LIBRARY and FILESYSTEM |
4411 | P: Boaz Harrosh | 4419 | P: Boaz Harrosh |
4412 | M: bharrosh@panasas.com | 4420 | M: bharrosh@panasas.com |
4413 | P: Benny Halevy | 4421 | P: Benny Halevy |
@@ -4416,6 +4424,9 @@ L: osd-dev@open-osd.org | |||
4416 | W: http://open-osd.org | 4424 | W: http://open-osd.org |
4417 | T: git git://git.open-osd.org/open-osd.git | 4425 | T: git git://git.open-osd.org/open-osd.git |
4418 | S: Maintained | 4426 | S: Maintained |
4427 | F: drivers/scsi/osd/ | ||
4428 | F: drivers/include/scsi/osd_* | ||
4429 | F: fs/exofs/ | ||
4419 | 4430 | ||
4420 | P54 WIRELESS DRIVER | 4431 | P54 WIRELESS DRIVER |
4421 | P: Michael Wu | 4432 | P: Michael Wu |
@@ -5583,7 +5594,6 @@ S: Odd Fixes | |||
5583 | F: drivers/net/starfire* | 5594 | F: drivers/net/starfire* |
5584 | 5595 | ||
5585 | STARMODE RADIO IP (STRIP) PROTOCOL DRIVER | 5596 | STARMODE RADIO IP (STRIP) PROTOCOL DRIVER |
5586 | W: http://mosquitonet.Stanford.EDU/strip.html | ||
5587 | S: Orphan | 5597 | S: Orphan |
5588 | F: drivers/net/wireless/strip.c | 5598 | F: drivers/net/wireless/strip.c |
5589 | F: include/linux/if_strip.h | 5599 | F: include/linux/if_strip.h |
@@ -5851,7 +5861,7 @@ UBI FILE SYSTEM (UBIFS) | |||
5851 | P: Artem Bityutskiy | 5861 | P: Artem Bityutskiy |
5852 | M: dedekind@infradead.org | 5862 | M: dedekind@infradead.org |
5853 | P: Adrian Hunter | 5863 | P: Adrian Hunter |
5854 | M: ext-adrian.hunter@nokia.com | 5864 | M: adrian.hunter@nokia.com |
5855 | L: linux-mtd@lists.infradead.org | 5865 | L: linux-mtd@lists.infradead.org |
5856 | T: git git://git.infradead.org/ubifs-2.6.git | 5866 | T: git git://git.infradead.org/ubifs-2.6.git |
5857 | W: http://www.linux-mtd.infradead.org/doc/ubifs.html | 5867 | W: http://www.linux-mtd.infradead.org/doc/ubifs.html |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 31 | 3 | SUBLEVEL = 31 |
4 | EXTRAVERSION = -rc2 | 4 | EXTRAVERSION = -rc3 |
5 | NAME = Man-Eating Seals of Antiquity | 5 | NAME = Man-Eating Seals of Antiquity |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
@@ -343,7 +343,8 @@ KBUILD_CPPFLAGS := -D__KERNEL__ | |||
343 | KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ | 343 | KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
344 | -fno-strict-aliasing -fno-common \ | 344 | -fno-strict-aliasing -fno-common \ |
345 | -Werror-implicit-function-declaration \ | 345 | -Werror-implicit-function-declaration \ |
346 | -Wno-format-security | 346 | -Wno-format-security \ |
347 | -fno-delete-null-pointer-checks | ||
347 | KBUILD_AFLAGS := -D__ASSEMBLY__ | 348 | KBUILD_AFLAGS := -D__ASSEMBLY__ |
348 | 349 | ||
349 | # Read KERNELRELEASE from include/config/kernel.release (if it exists) | 350 | # Read KERNELRELEASE from include/config/kernel.release (if it exists) |
@@ -565,7 +566,7 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) | |||
565 | KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) | 566 | KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) |
566 | 567 | ||
567 | # disable invalid "can't wrap" optimizations for signed / pointers | 568 | # disable invalid "can't wrap" optimizations for signed / pointers |
568 | KBUILD_CFLAGS += $(call cc-option,-fwrapv) | 569 | KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) |
569 | 570 | ||
570 | # revert to pre-gcc-4.4 behaviour of .eh_frame | 571 | # revert to pre-gcc-4.4 behaviour of .eh_frame |
571 | KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) | 572 | KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) |
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h index d069526bd767..60c83abfde70 100644 --- a/arch/alpha/include/asm/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h | |||
@@ -37,6 +37,7 @@ struct thread_info { | |||
37 | .task = &tsk, \ | 37 | .task = &tsk, \ |
38 | .exec_domain = &default_exec_domain, \ | 38 | .exec_domain = &default_exec_domain, \ |
39 | .addr_limit = KERNEL_DS, \ | 39 | .addr_limit = KERNEL_DS, \ |
40 | .preempt_count = INIT_PREEMPT_COUNT, \ | ||
40 | .restart_block = { \ | 41 | .restart_block = { \ |
41 | .fn = do_no_restart_syscall, \ | 42 | .fn = do_no_restart_syscall, \ |
42 | }, \ | 43 | }, \ |
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c index 1e9ad52c460e..e072041d19f8 100644 --- a/arch/alpha/kernel/ptrace.c +++ b/arch/alpha/kernel/ptrace.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/smp.h> | 10 | #include <linux/smp.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
13 | #include <linux/ptrace.h> | 12 | #include <linux/ptrace.h> |
14 | #include <linux/user.h> | 13 | #include <linux/user.h> |
diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 4762d9001298..7d61ae6e75da 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.31-rc1 | 3 | # Linux kernel version: 2.6.31-rc3 |
4 | # Thu Jul 2 00:16:59 2009 | 4 | # Thu Jul 16 23:36:10 2009 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | 7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y |
@@ -9,7 +9,6 @@ CONFIG_GENERIC_GPIO=y | |||
9 | CONFIG_GENERIC_TIME=y | 9 | CONFIG_GENERIC_TIME=y |
10 | CONFIG_GENERIC_CLOCKEVENTS=y | 10 | CONFIG_GENERIC_CLOCKEVENTS=y |
11 | CONFIG_MMU=y | 11 | CONFIG_MMU=y |
12 | CONFIG_HAVE_TCM=y | ||
13 | CONFIG_GENERIC_HARDIRQS=y | 12 | CONFIG_GENERIC_HARDIRQS=y |
14 | CONFIG_STACKTRACE_SUPPORT=y | 13 | CONFIG_STACKTRACE_SUPPORT=y |
15 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | 14 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y |
@@ -113,7 +112,7 @@ CONFIG_MODULE_UNLOAD=y | |||
113 | # CONFIG_MODVERSIONS is not set | 112 | # CONFIG_MODVERSIONS is not set |
114 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 113 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
115 | CONFIG_BLOCK=y | 114 | CONFIG_BLOCK=y |
116 | CONFIG_LBDAF=y | 115 | # CONFIG_LBDAF is not set |
117 | # CONFIG_BLK_DEV_BSG is not set | 116 | # CONFIG_BLK_DEV_BSG is not set |
118 | # CONFIG_BLK_DEV_INTEGRITY is not set | 117 | # CONFIG_BLK_DEV_INTEGRITY is not set |
119 | 118 | ||
@@ -542,13 +541,14 @@ CONFIG_INPUT_EVDEV=y | |||
542 | # | 541 | # |
543 | CONFIG_INPUT_KEYBOARD=y | 542 | CONFIG_INPUT_KEYBOARD=y |
544 | # CONFIG_KEYBOARD_ATKBD is not set | 543 | # CONFIG_KEYBOARD_ATKBD is not set |
545 | # CONFIG_KEYBOARD_SUNKBD is not set | ||
546 | # CONFIG_KEYBOARD_LKKBD is not set | 544 | # CONFIG_KEYBOARD_LKKBD is not set |
547 | # CONFIG_KEYBOARD_XTKBD is not set | 545 | # CONFIG_KEYBOARD_GPIO is not set |
546 | # CONFIG_KEYBOARD_MATRIX is not set | ||
547 | # CONFIG_KEYBOARD_LM8323 is not set | ||
548 | # CONFIG_KEYBOARD_NEWTON is not set | 548 | # CONFIG_KEYBOARD_NEWTON is not set |
549 | # CONFIG_KEYBOARD_STOWAWAY is not set | 549 | # CONFIG_KEYBOARD_STOWAWAY is not set |
550 | # CONFIG_KEYBOARD_LM8323 is not set | 550 | # CONFIG_KEYBOARD_SUNKBD is not set |
551 | # CONFIG_KEYBOARD_GPIO is not set | 551 | # CONFIG_KEYBOARD_XTKBD is not set |
552 | # CONFIG_INPUT_MOUSE is not set | 552 | # CONFIG_INPUT_MOUSE is not set |
553 | # CONFIG_INPUT_JOYSTICK is not set | 553 | # CONFIG_INPUT_JOYSTICK is not set |
554 | # CONFIG_INPUT_TABLET is not set | 554 | # CONFIG_INPUT_TABLET is not set |
@@ -911,7 +911,6 @@ CONFIG_REGULATOR=y | |||
911 | # CONFIG_JFS_FS is not set | 911 | # CONFIG_JFS_FS is not set |
912 | # CONFIG_FS_POSIX_ACL is not set | 912 | # CONFIG_FS_POSIX_ACL is not set |
913 | # CONFIG_XFS_FS is not set | 913 | # CONFIG_XFS_FS is not set |
914 | # CONFIG_GFS2_FS is not set | ||
915 | # CONFIG_OCFS2_FS is not set | 914 | # CONFIG_OCFS2_FS is not set |
916 | # CONFIG_BTRFS_FS is not set | 915 | # CONFIG_BTRFS_FS is not set |
917 | CONFIG_FILE_LOCKING=y | 916 | CONFIG_FILE_LOCKING=y |
@@ -1122,7 +1121,6 @@ CONFIG_GENERIC_FIND_LAST_BIT=y | |||
1122 | # CONFIG_CRC32 is not set | 1121 | # CONFIG_CRC32 is not set |
1123 | # CONFIG_CRC7 is not set | 1122 | # CONFIG_CRC7 is not set |
1124 | # CONFIG_LIBCRC32C is not set | 1123 | # CONFIG_LIBCRC32C is not set |
1125 | CONFIG_GENERIC_ALLOCATOR=y | ||
1126 | CONFIG_HAS_IOMEM=y | 1124 | CONFIG_HAS_IOMEM=y |
1127 | CONFIG_HAS_IOPORT=y | 1125 | CONFIG_HAS_IOPORT=y |
1128 | CONFIG_HAS_DMA=y | 1126 | CONFIG_HAS_DMA=y |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index 4f8848260ee2..73394e50cbca 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
@@ -73,7 +73,7 @@ struct thread_info { | |||
73 | .task = &tsk, \ | 73 | .task = &tsk, \ |
74 | .exec_domain = &default_exec_domain, \ | 74 | .exec_domain = &default_exec_domain, \ |
75 | .flags = 0, \ | 75 | .flags = 0, \ |
76 | .preempt_count = 1, \ | 76 | .preempt_count = INIT_PREEMPT_COUNT, \ |
77 | .addr_limit = KERNEL_DS, \ | 77 | .addr_limit = KERNEL_DS, \ |
78 | .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ | 78 | .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ |
79 | domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ | 79 | domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ |
diff --git a/arch/arm/mach-ep93xx/dma-m2p.c b/arch/arm/mach-ep93xx/dma-m2p.c index a2df5bb7dff0..dbcac9c40a28 100644 --- a/arch/arm/mach-ep93xx/dma-m2p.c +++ b/arch/arm/mach-ep93xx/dma-m2p.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/err.h> | 33 | #include <linux/err.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/io.h> | ||
36 | 37 | ||
37 | #include <mach/dma.h> | 38 | #include <mach/dma.h> |
38 | #include <mach/hardware.h> | 39 | #include <mach/hardware.h> |
diff --git a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h index e021a80c2caf..bc74278ed311 100644 --- a/arch/arm/mach-kirkwood/mpp.h +++ b/arch/arm/mach-kirkwood/mpp.h | |||
@@ -289,7 +289,7 @@ | |||
289 | 289 | ||
290 | #define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1 ) | 290 | #define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1 ) |
291 | #define MPP48_TSMP12 MPP( 48, 0x1, 1, 1, 0, 0, 0, 1 ) | 291 | #define MPP48_TSMP12 MPP( 48, 0x1, 1, 1, 0, 0, 0, 1 ) |
292 | #define MPP48_TDM_DTX MPP( 48. 0x2, 0, 1, 0, 0, 0, 1 ) | 292 | #define MPP48_TDM_DTX MPP( 48, 0x2, 0, 1, 0, 0, 0, 1 ) |
293 | 293 | ||
294 | #define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1 ) | 294 | #define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1 ) |
295 | #define MPP49_TSMP9 MPP( 49, 0x1, 1, 1, 0, 0, 0, 1 ) | 295 | #define MPP49_TSMP9 MPP( 49, 0x1, 1, 1, 0, 0, 0, 1 ) |
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 17a21a291e2f..851f2458bf65 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig | |||
@@ -36,6 +36,14 @@ config MACH_PCM037 | |||
36 | Include support for Phytec pcm037 platform. This includes | 36 | Include support for Phytec pcm037 platform. This includes |
37 | specific configurations for the board and its peripherals. | 37 | specific configurations for the board and its peripherals. |
38 | 38 | ||
39 | config MACH_PCM037_EET | ||
40 | bool "Support pcm037 EET board extensions" | ||
41 | depends on MACH_PCM037 | ||
42 | help | ||
43 | Add support for PCM037 EET baseboard extensions. If you are using the | ||
44 | OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel | ||
45 | command-line parameter. | ||
46 | |||
39 | config MACH_MX31LITE | 47 | config MACH_MX31LITE |
40 | bool "Support MX31 LITEKIT (LogicPD)" | 48 | bool "Support MX31 LITEKIT (LogicPD)" |
41 | select ARCH_MX31 | 49 | select ARCH_MX31 |
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 0322696bd11a..6b9775471be6 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o | |||
11 | obj-$(CONFIG_MACH_MX31LILLY) += mx31lilly.o mx31lilly-db.o | 11 | obj-$(CONFIG_MACH_MX31LILLY) += mx31lilly.o mx31lilly-db.o |
12 | obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o | 12 | obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o |
13 | obj-$(CONFIG_MACH_PCM037) += pcm037.o | 13 | obj-$(CONFIG_MACH_PCM037) += pcm037.o |
14 | obj-$(CONFIG_MACH_PCM037_EET) += pcm037_eet.o | ||
14 | obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o | 15 | obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o |
15 | obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ | 16 | obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ |
16 | mx31moboard-marxbot.o | 17 | mx31moboard-marxbot.o |
diff --git a/arch/arm/mach-mx3/armadillo5x0.c b/arch/arm/mach-mx3/armadillo5x0.c index 541181090b37..ee331fd6b1bd 100644 --- a/arch/arm/mach-mx3/armadillo5x0.c +++ b/arch/arm/mach-mx3/armadillo5x0.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/smsc911x.h> | 31 | #include <linux/smsc911x.h> |
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
34 | #include <linux/mtd/physmap.h> | ||
35 | #include <linux/io.h> | ||
34 | 36 | ||
35 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
36 | #include <asm/mach-types.h> | 38 | #include <asm/mach-types.h> |
@@ -46,8 +48,10 @@ | |||
46 | #include <mach/mmc.h> | 48 | #include <mach/mmc.h> |
47 | #include <mach/ipu.h> | 49 | #include <mach/ipu.h> |
48 | #include <mach/mx3fb.h> | 50 | #include <mach/mx3fb.h> |
51 | #include <mach/mxc_nand.h> | ||
49 | 52 | ||
50 | #include "devices.h" | 53 | #include "devices.h" |
54 | #include "crm_regs.h" | ||
51 | 55 | ||
52 | static int armadillo5x0_pins[] = { | 56 | static int armadillo5x0_pins[] = { |
53 | /* UART1 */ | 57 | /* UART1 */ |
@@ -93,7 +97,56 @@ static int armadillo5x0_pins[] = { | |||
93 | MX31_PIN_FPSHIFT__FPSHIFT, | 97 | MX31_PIN_FPSHIFT__FPSHIFT, |
94 | MX31_PIN_DRDY0__DRDY0, | 98 | MX31_PIN_DRDY0__DRDY0, |
95 | IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/ | 99 | IOMUX_MODE(MX31_PIN_LCS1, IOMUX_CONFIG_GPIO), /*ADV7125_PSAVE*/ |
100 | }; | ||
96 | 101 | ||
102 | /* | ||
103 | * NAND Flash | ||
104 | */ | ||
105 | static struct mxc_nand_platform_data armadillo5x0_nand_flash_pdata = { | ||
106 | .width = 1, | ||
107 | .hw_ecc = 1, | ||
108 | }; | ||
109 | |||
110 | /* | ||
111 | * MTD NOR Flash | ||
112 | */ | ||
113 | static struct mtd_partition armadillo5x0_nor_flash_partitions[] = { | ||
114 | { | ||
115 | .name = "nor.bootloader", | ||
116 | .offset = 0x00000000, | ||
117 | .size = 4*32*1024, | ||
118 | }, { | ||
119 | .name = "nor.kernel", | ||
120 | .offset = MTDPART_OFS_APPEND, | ||
121 | .size = 16*128*1024, | ||
122 | }, { | ||
123 | .name = "nor.userland", | ||
124 | .offset = MTDPART_OFS_APPEND, | ||
125 | .size = 110*128*1024, | ||
126 | }, { | ||
127 | .name = "nor.config", | ||
128 | .offset = MTDPART_OFS_APPEND, | ||
129 | .size = 1*128*1024, | ||
130 | }, | ||
131 | }; | ||
132 | |||
133 | static struct physmap_flash_data armadillo5x0_nor_flash_pdata = { | ||
134 | .width = 2, | ||
135 | .parts = armadillo5x0_nor_flash_partitions, | ||
136 | .nr_parts = ARRAY_SIZE(armadillo5x0_nor_flash_partitions), | ||
137 | }; | ||
138 | |||
139 | static struct resource armadillo5x0_nor_flash_resource = { | ||
140 | .flags = IORESOURCE_MEM, | ||
141 | .start = CS0_BASE_ADDR, | ||
142 | .end = CS0_BASE_ADDR + SZ_64M - 1, | ||
143 | }; | ||
144 | |||
145 | static struct platform_device armadillo5x0_nor_flash = { | ||
146 | .name = "physmap-flash", | ||
147 | .id = -1, | ||
148 | .num_resources = 1, | ||
149 | .resource = &armadillo5x0_nor_flash_resource, | ||
97 | }; | 150 | }; |
98 | 151 | ||
99 | /* | 152 | /* |
@@ -272,6 +325,16 @@ static void __init armadillo5x0_init(void) | |||
272 | /* Register FB */ | 325 | /* Register FB */ |
273 | mxc_register_device(&mx3_ipu, &mx3_ipu_data); | 326 | mxc_register_device(&mx3_ipu, &mx3_ipu_data); |
274 | mxc_register_device(&mx3_fb, &mx3fb_pdata); | 327 | mxc_register_device(&mx3_fb, &mx3fb_pdata); |
328 | |||
329 | /* Register NOR Flash */ | ||
330 | mxc_register_device(&armadillo5x0_nor_flash, | ||
331 | &armadillo5x0_nor_flash_pdata); | ||
332 | |||
333 | /* Register NAND Flash */ | ||
334 | mxc_register_device(&mxc_nand_device, &armadillo5x0_nand_flash_pdata); | ||
335 | |||
336 | /* set NAND page size to 2k if not configured via boot mode pins */ | ||
337 | __raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR); | ||
275 | } | 338 | } |
276 | 339 | ||
277 | static void __init armadillo5x0_timer_init(void) | 340 | static void __init armadillo5x0_timer_init(void) |
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index d927eddcad46..9e87e08fb121 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/serial.h> | 23 | #include <linux/serial.h> |
24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/dma-mapping.h> | ||
26 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
27 | #include <mach/irqs.h> | 26 | #include <mach/irqs.h> |
28 | #include <mach/common.h> | 27 | #include <mach/common.h> |
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index c6f61a1f06c8..840cfda341d0 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | 21 | #include <linux/dma-mapping.h> | |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/mtd/physmap.h> | 23 | #include <linux/mtd/physmap.h> |
24 | #include <linux/mtd/plat-ram.h> | 24 | #include <linux/mtd/plat-ram.h> |
@@ -33,29 +33,67 @@ | |||
33 | #include <linux/irq.h> | 33 | #include <linux/irq.h> |
34 | #include <linux/fsl_devices.h> | 34 | #include <linux/fsl_devices.h> |
35 | 35 | ||
36 | #include <mach/hardware.h> | 36 | #include <media/soc_camera.h> |
37 | |||
37 | #include <asm/mach-types.h> | 38 | #include <asm/mach-types.h> |
38 | #include <asm/mach/arch.h> | 39 | #include <asm/mach/arch.h> |
39 | #include <asm/mach/time.h> | 40 | #include <asm/mach/time.h> |
40 | #include <asm/mach/map.h> | 41 | #include <asm/mach/map.h> |
42 | #include <mach/board-pcm037.h> | ||
41 | #include <mach/common.h> | 43 | #include <mach/common.h> |
44 | #include <mach/hardware.h> | ||
45 | #include <mach/i2c.h> | ||
42 | #include <mach/imx-uart.h> | 46 | #include <mach/imx-uart.h> |
43 | #include <mach/iomux-mx3.h> | 47 | #include <mach/iomux-mx3.h> |
44 | #include <mach/ipu.h> | 48 | #include <mach/ipu.h> |
45 | #include <mach/board-pcm037.h> | 49 | #include <mach/mmc.h> |
50 | #include <mach/mx3_camera.h> | ||
46 | #include <mach/mx3fb.h> | 51 | #include <mach/mx3fb.h> |
47 | #include <mach/mxc_nand.h> | 52 | #include <mach/mxc_nand.h> |
48 | #include <mach/mmc.h> | ||
49 | #ifdef CONFIG_I2C_IMX | ||
50 | #include <mach/i2c.h> | ||
51 | #endif | ||
52 | 53 | ||
53 | #include "devices.h" | 54 | #include "devices.h" |
55 | #include "pcm037.h" | ||
56 | |||
57 | static enum pcm037_board_variant pcm037_instance = PCM037_PCM970; | ||
58 | |||
59 | static int __init pcm037_variant_setup(char *str) | ||
60 | { | ||
61 | if (!strcmp("eet", str)) | ||
62 | pcm037_instance = PCM037_EET; | ||
63 | else if (strcmp("pcm970", str)) | ||
64 | pr_warning("Unknown pcm037 baseboard variant %s\n", str); | ||
65 | |||
66 | return 1; | ||
67 | } | ||
68 | |||
69 | /* Supported values: "pcm970" (default) and "eet" */ | ||
70 | __setup("pcm037_variant=", pcm037_variant_setup); | ||
71 | |||
72 | enum pcm037_board_variant pcm037_variant(void) | ||
73 | { | ||
74 | return pcm037_instance; | ||
75 | } | ||
76 | |||
77 | /* UART1 with RTS/CTS handshake signals */ | ||
78 | static unsigned int pcm037_uart1_handshake_pins[] = { | ||
79 | MX31_PIN_CTS1__CTS1, | ||
80 | MX31_PIN_RTS1__RTS1, | ||
81 | MX31_PIN_TXD1__TXD1, | ||
82 | MX31_PIN_RXD1__RXD1, | ||
83 | }; | ||
84 | |||
85 | /* UART1 without RTS/CTS handshake signals */ | ||
86 | static unsigned int pcm037_uart1_pins[] = { | ||
87 | MX31_PIN_TXD1__TXD1, | ||
88 | MX31_PIN_RXD1__RXD1, | ||
89 | }; | ||
54 | 90 | ||
55 | static unsigned int pcm037_pins[] = { | 91 | static unsigned int pcm037_pins[] = { |
56 | /* I2C */ | 92 | /* I2C */ |
57 | MX31_PIN_CSPI2_MOSI__SCL, | 93 | MX31_PIN_CSPI2_MOSI__SCL, |
58 | MX31_PIN_CSPI2_MISO__SDA, | 94 | MX31_PIN_CSPI2_MISO__SDA, |
95 | MX31_PIN_CSPI2_SS2__I2C3_SDA, | ||
96 | MX31_PIN_CSPI2_SCLK__I2C3_SCL, | ||
59 | /* SDHC1 */ | 97 | /* SDHC1 */ |
60 | MX31_PIN_SD1_DATA3__SD1_DATA3, | 98 | MX31_PIN_SD1_DATA3__SD1_DATA3, |
61 | MX31_PIN_SD1_DATA2__SD1_DATA2, | 99 | MX31_PIN_SD1_DATA2__SD1_DATA2, |
@@ -73,11 +111,6 @@ static unsigned int pcm037_pins[] = { | |||
73 | MX31_PIN_CSPI1_SS0__SS0, | 111 | MX31_PIN_CSPI1_SS0__SS0, |
74 | MX31_PIN_CSPI1_SS1__SS1, | 112 | MX31_PIN_CSPI1_SS1__SS1, |
75 | MX31_PIN_CSPI1_SS2__SS2, | 113 | MX31_PIN_CSPI1_SS2__SS2, |
76 | /* UART1 */ | ||
77 | MX31_PIN_CTS1__CTS1, | ||
78 | MX31_PIN_RTS1__RTS1, | ||
79 | MX31_PIN_TXD1__TXD1, | ||
80 | MX31_PIN_RXD1__RXD1, | ||
81 | /* UART2 */ | 114 | /* UART2 */ |
82 | MX31_PIN_TXD2__TXD2, | 115 | MX31_PIN_TXD2__TXD2, |
83 | MX31_PIN_RXD2__RXD2, | 116 | MX31_PIN_RXD2__RXD2, |
@@ -120,6 +153,22 @@ static unsigned int pcm037_pins[] = { | |||
120 | MX31_PIN_D3_SPL__D3_SPL, | 153 | MX31_PIN_D3_SPL__D3_SPL, |
121 | MX31_PIN_D3_CLS__D3_CLS, | 154 | MX31_PIN_D3_CLS__D3_CLS, |
122 | MX31_PIN_LCS0__GPI03_23, | 155 | MX31_PIN_LCS0__GPI03_23, |
156 | /* CSI */ | ||
157 | IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_GPIO), | ||
158 | MX31_PIN_CSI_D6__CSI_D6, | ||
159 | MX31_PIN_CSI_D7__CSI_D7, | ||
160 | MX31_PIN_CSI_D8__CSI_D8, | ||
161 | MX31_PIN_CSI_D9__CSI_D9, | ||
162 | MX31_PIN_CSI_D10__CSI_D10, | ||
163 | MX31_PIN_CSI_D11__CSI_D11, | ||
164 | MX31_PIN_CSI_D12__CSI_D12, | ||
165 | MX31_PIN_CSI_D13__CSI_D13, | ||
166 | MX31_PIN_CSI_D14__CSI_D14, | ||
167 | MX31_PIN_CSI_D15__CSI_D15, | ||
168 | MX31_PIN_CSI_HSYNC__CSI_HSYNC, | ||
169 | MX31_PIN_CSI_MCLK__CSI_MCLK, | ||
170 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, | ||
171 | MX31_PIN_CSI_VSYNC__CSI_VSYNC, | ||
123 | }; | 172 | }; |
124 | 173 | ||
125 | static struct physmap_flash_data pcm037_flash_data = { | 174 | static struct physmap_flash_data pcm037_flash_data = { |
@@ -250,19 +299,43 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = { | |||
250 | .hw_ecc = 1, | 299 | .hw_ecc = 1, |
251 | }; | 300 | }; |
252 | 301 | ||
253 | #ifdef CONFIG_I2C_IMX | ||
254 | static struct imxi2c_platform_data pcm037_i2c_1_data = { | 302 | static struct imxi2c_platform_data pcm037_i2c_1_data = { |
255 | .bitrate = 100000, | 303 | .bitrate = 100000, |
256 | }; | 304 | }; |
257 | 305 | ||
306 | static struct imxi2c_platform_data pcm037_i2c_2_data = { | ||
307 | .bitrate = 20000, | ||
308 | }; | ||
309 | |||
258 | static struct at24_platform_data board_eeprom = { | 310 | static struct at24_platform_data board_eeprom = { |
259 | .byte_len = 4096, | 311 | .byte_len = 4096, |
260 | .page_size = 32, | 312 | .page_size = 32, |
261 | .flags = AT24_FLAG_ADDR16, | 313 | .flags = AT24_FLAG_ADDR16, |
262 | }; | 314 | }; |
263 | 315 | ||
316 | static int pcm037_camera_power(struct device *dev, int on) | ||
317 | { | ||
318 | /* disable or enable the camera in X7 or X8 PCM970 connector */ | ||
319 | gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), !on); | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static struct i2c_board_info pcm037_i2c_2_devices[] = { | ||
324 | { | ||
325 | I2C_BOARD_INFO("mt9t031", 0x5d), | ||
326 | }, | ||
327 | }; | ||
328 | |||
329 | static struct soc_camera_link iclink = { | ||
330 | .bus_id = 0, /* Must match with the camera ID */ | ||
331 | .power = pcm037_camera_power, | ||
332 | .board_info = &pcm037_i2c_2_devices[0], | ||
333 | .i2c_adapter_id = 2, | ||
334 | .module_name = "mt9t031", | ||
335 | }; | ||
336 | |||
264 | static struct i2c_board_info pcm037_i2c_devices[] = { | 337 | static struct i2c_board_info pcm037_i2c_devices[] = { |
265 | { | 338 | { |
266 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | 339 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ |
267 | .platform_data = &board_eeprom, | 340 | .platform_data = &board_eeprom, |
268 | }, { | 341 | }, { |
@@ -270,7 +343,14 @@ static struct i2c_board_info pcm037_i2c_devices[] = { | |||
270 | .type = "pcf8563", | 343 | .type = "pcf8563", |
271 | } | 344 | } |
272 | }; | 345 | }; |
273 | #endif | 346 | |
347 | static struct platform_device pcm037_camera = { | ||
348 | .name = "soc-camera-pdrv", | ||
349 | .id = 0, | ||
350 | .dev = { | ||
351 | .platform_data = &iclink, | ||
352 | }, | ||
353 | }; | ||
274 | 354 | ||
275 | /* Not connected by default */ | 355 | /* Not connected by default */ |
276 | #ifdef PCM970_SDHC_RW_SWITCH | 356 | #ifdef PCM970_SDHC_RW_SWITCH |
@@ -334,9 +414,41 @@ static struct imxmmc_platform_data sdhc_pdata = { | |||
334 | .exit = pcm970_sdhc1_exit, | 414 | .exit = pcm970_sdhc1_exit, |
335 | }; | 415 | }; |
336 | 416 | ||
417 | struct mx3_camera_pdata camera_pdata = { | ||
418 | .dma_dev = &mx3_ipu.dev, | ||
419 | .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, | ||
420 | .mclk_10khz = 2000, | ||
421 | }; | ||
422 | |||
423 | static int __init pcm037_camera_alloc_dma(const size_t buf_size) | ||
424 | { | ||
425 | dma_addr_t dma_handle; | ||
426 | void *buf; | ||
427 | int dma; | ||
428 | |||
429 | if (buf_size < 2 * 1024 * 1024) | ||
430 | return -EINVAL; | ||
431 | |||
432 | buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL); | ||
433 | if (!buf) { | ||
434 | pr_err("%s: cannot allocate camera buffer-memory\n", __func__); | ||
435 | return -ENOMEM; | ||
436 | } | ||
437 | |||
438 | memset(buf, 0, buf_size); | ||
439 | |||
440 | dma = dma_declare_coherent_memory(&mx3_camera.dev, | ||
441 | dma_handle, dma_handle, buf_size, | ||
442 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); | ||
443 | |||
444 | /* The way we call dma_declare_coherent_memory only a malloc can fail */ | ||
445 | return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM; | ||
446 | } | ||
447 | |||
337 | static struct platform_device *devices[] __initdata = { | 448 | static struct platform_device *devices[] __initdata = { |
338 | &pcm037_flash, | 449 | &pcm037_flash, |
339 | &pcm037_sram_device, | 450 | &pcm037_sram_device, |
451 | &pcm037_camera, | ||
340 | }; | 452 | }; |
341 | 453 | ||
342 | static struct ipu_platform_data mx3_ipu_data = { | 454 | static struct ipu_platform_data mx3_ipu_data = { |
@@ -377,6 +489,22 @@ static const struct fb_videomode fb_modedb[] = { | |||
377 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, | 489 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, |
378 | .vmode = FB_VMODE_NONINTERLACED, | 490 | .vmode = FB_VMODE_NONINTERLACED, |
379 | .flag = 0, | 491 | .flag = 0, |
492 | }, { | ||
493 | /* 240x320 @ 60 Hz */ | ||
494 | .name = "CMEL-OLED", | ||
495 | .refresh = 60, | ||
496 | .xres = 240, | ||
497 | .yres = 320, | ||
498 | .pixclock = 185925, | ||
499 | .left_margin = 9, | ||
500 | .right_margin = 16, | ||
501 | .upper_margin = 7, | ||
502 | .lower_margin = 9, | ||
503 | .hsync_len = 1, | ||
504 | .vsync_len = 1, | ||
505 | .sync = FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT, | ||
506 | .vmode = FB_VMODE_NONINTERLACED, | ||
507 | .flag = 0, | ||
380 | }, | 508 | }, |
381 | }; | 509 | }; |
382 | 510 | ||
@@ -397,6 +525,14 @@ static void __init mxc_board_init(void) | |||
397 | mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), | 525 | mxc_iomux_setup_multiple_pins(pcm037_pins, ARRAY_SIZE(pcm037_pins), |
398 | "pcm037"); | 526 | "pcm037"); |
399 | 527 | ||
528 | if (pcm037_variant() == PCM037_EET) | ||
529 | mxc_iomux_setup_multiple_pins(pcm037_uart1_pins, | ||
530 | ARRAY_SIZE(pcm037_uart1_pins), "pcm037_uart1"); | ||
531 | else | ||
532 | mxc_iomux_setup_multiple_pins(pcm037_uart1_handshake_pins, | ||
533 | ARRAY_SIZE(pcm037_uart1_handshake_pins), | ||
534 | "pcm037_uart1"); | ||
535 | |||
400 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 536 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
401 | 537 | ||
402 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | 538 | mxc_register_device(&mxc_uart_device0, &uart_pdata); |
@@ -415,18 +551,30 @@ static void __init mxc_board_init(void) | |||
415 | } | 551 | } |
416 | 552 | ||
417 | 553 | ||
418 | #ifdef CONFIG_I2C_IMX | 554 | /* I2C adapters and devices */ |
419 | i2c_register_board_info(1, pcm037_i2c_devices, | 555 | i2c_register_board_info(1, pcm037_i2c_devices, |
420 | ARRAY_SIZE(pcm037_i2c_devices)); | 556 | ARRAY_SIZE(pcm037_i2c_devices)); |
421 | 557 | ||
422 | mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data); | 558 | mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data); |
423 | #endif | 559 | mxc_register_device(&mxc_i2c_device2, &pcm037_i2c_2_data); |
560 | |||
424 | mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info); | 561 | mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info); |
425 | mxc_register_device(&mxcsdhc_device0, &sdhc_pdata); | 562 | mxc_register_device(&mxcsdhc_device0, &sdhc_pdata); |
426 | mxc_register_device(&mx3_ipu, &mx3_ipu_data); | 563 | mxc_register_device(&mx3_ipu, &mx3_ipu_data); |
427 | mxc_register_device(&mx3_fb, &mx3fb_pdata); | 564 | mxc_register_device(&mx3_fb, &mx3fb_pdata); |
428 | if (!gpio_usbotg_hs_activate()) | 565 | if (!gpio_usbotg_hs_activate()) |
429 | mxc_register_device(&mxc_otg_udc_device, &usb_pdata); | 566 | mxc_register_device(&mxc_otg_udc_device, &usb_pdata); |
567 | |||
568 | /* CSI */ | ||
569 | /* Camera power: default - off */ | ||
570 | ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), "mt9t031-power"); | ||
571 | if (!ret) | ||
572 | gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CSI_D5), 1); | ||
573 | else | ||
574 | iclink.power = NULL; | ||
575 | |||
576 | if (!pcm037_camera_alloc_dma(4 * 1024 * 1024)) | ||
577 | mxc_register_device(&mx3_camera, &camera_pdata); | ||
430 | } | 578 | } |
431 | 579 | ||
432 | static void __init pcm037_timer_init(void) | 580 | static void __init pcm037_timer_init(void) |
@@ -448,4 +596,3 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037") | |||
448 | .init_machine = mxc_board_init, | 596 | .init_machine = mxc_board_init, |
449 | .timer = &pcm037_timer, | 597 | .timer = &pcm037_timer, |
450 | MACHINE_END | 598 | MACHINE_END |
451 | |||
diff --git a/arch/arm/mach-mx3/pcm037.h b/arch/arm/mach-mx3/pcm037.h new file mode 100644 index 000000000000..d6929721a5fd --- /dev/null +++ b/arch/arm/mach-mx3/pcm037.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef __PCM037_H__ | ||
2 | #define __PCM037_H__ | ||
3 | |||
4 | enum pcm037_board_variant { | ||
5 | PCM037_PCM970, | ||
6 | PCM037_EET, | ||
7 | }; | ||
8 | |||
9 | extern enum pcm037_board_variant pcm037_variant(void); | ||
10 | |||
11 | #endif | ||
diff --git a/arch/arm/mach-mx3/pcm037_eet.c b/arch/arm/mach-mx3/pcm037_eet.c new file mode 100644 index 000000000000..fe52fb1bb8b7 --- /dev/null +++ b/arch/arm/mach-mx3/pcm037_eet.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 | ||
3 | * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | #include <linux/gpio.h> | ||
10 | #include <linux/gpio_keys.h> | ||
11 | #include <linux/input.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/spi/spi.h> | ||
14 | |||
15 | #include <mach/common.h> | ||
16 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
17 | #include <mach/spi.h> | ||
18 | #endif | ||
19 | #include <mach/iomux-mx3.h> | ||
20 | |||
21 | #include <asm/mach-types.h> | ||
22 | |||
23 | #include "pcm037.h" | ||
24 | #include "devices.h" | ||
25 | |||
26 | static unsigned int pcm037_eet_pins[] = { | ||
27 | /* SPI #1 */ | ||
28 | MX31_PIN_CSPI1_MISO__MISO, | ||
29 | MX31_PIN_CSPI1_MOSI__MOSI, | ||
30 | MX31_PIN_CSPI1_SCLK__SCLK, | ||
31 | MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, | ||
32 | MX31_PIN_CSPI1_SS0__SS0, | ||
33 | MX31_PIN_CSPI1_SS1__SS1, | ||
34 | MX31_PIN_CSPI1_SS2__SS2, | ||
35 | |||
36 | /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */ | ||
37 | IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO), | ||
38 | /* GPIO keys */ | ||
39 | IOMUX_MODE(MX31_PIN_GPIO1_0, IOMUX_CONFIG_GPIO), /* 0 */ | ||
40 | IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO), /* 1 */ | ||
41 | IOMUX_MODE(MX31_PIN_GPIO1_2, IOMUX_CONFIG_GPIO), /* 2 */ | ||
42 | IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), /* 3 */ | ||
43 | IOMUX_MODE(MX31_PIN_SVEN0, IOMUX_CONFIG_GPIO), /* 32 */ | ||
44 | IOMUX_MODE(MX31_PIN_STX0, IOMUX_CONFIG_GPIO), /* 33 */ | ||
45 | IOMUX_MODE(MX31_PIN_SRX0, IOMUX_CONFIG_GPIO), /* 34 */ | ||
46 | IOMUX_MODE(MX31_PIN_SIMPD0, IOMUX_CONFIG_GPIO), /* 35 */ | ||
47 | IOMUX_MODE(MX31_PIN_RTS1, IOMUX_CONFIG_GPIO), /* 38 */ | ||
48 | IOMUX_MODE(MX31_PIN_CTS1, IOMUX_CONFIG_GPIO), /* 39 */ | ||
49 | IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_GPIO), /* 50 */ | ||
50 | IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_GPIO), /* 51 */ | ||
51 | IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_GPIO), /* 52 */ | ||
52 | IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_GPIO), /* 53 */ | ||
53 | |||
54 | /* LEDs */ | ||
55 | IOMUX_MODE(MX31_PIN_DTR_DTE1, IOMUX_CONFIG_GPIO), /* 44 */ | ||
56 | IOMUX_MODE(MX31_PIN_DSR_DTE1, IOMUX_CONFIG_GPIO), /* 45 */ | ||
57 | IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_GPIO), /* 55 */ | ||
58 | IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_GPIO), /* 56 */ | ||
59 | }; | ||
60 | |||
61 | /* SPI */ | ||
62 | static struct spi_board_info pcm037_spi_dev[] = { | ||
63 | { | ||
64 | .modalias = "dac124s085", | ||
65 | .max_speed_hz = 400000, | ||
66 | .bus_num = 0, | ||
67 | .chip_select = 0, /* Index in pcm037_spi1_cs[] */ | ||
68 | .mode = SPI_CPHA, | ||
69 | }, | ||
70 | }; | ||
71 | |||
72 | /* Platform Data for MXC CSPI */ | ||
73 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
74 | static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)}; | ||
75 | |||
76 | struct spi_imx_master pcm037_spi1_master = { | ||
77 | .chipselect = pcm037_spi1_cs, | ||
78 | .num_chipselect = ARRAY_SIZE(pcm037_spi1_cs), | ||
79 | }; | ||
80 | #endif | ||
81 | |||
82 | /* GPIO-keys input device */ | ||
83 | static struct gpio_keys_button pcm037_gpio_keys[] = { | ||
84 | { | ||
85 | .type = EV_KEY, | ||
86 | .code = KEY_L, | ||
87 | .gpio = 0, | ||
88 | .desc = "Wheel Manual", | ||
89 | .wakeup = 0, | ||
90 | }, { | ||
91 | .type = EV_KEY, | ||
92 | .code = KEY_A, | ||
93 | .gpio = 1, | ||
94 | .desc = "Wheel AF", | ||
95 | .wakeup = 0, | ||
96 | }, { | ||
97 | .type = EV_KEY, | ||
98 | .code = KEY_V, | ||
99 | .gpio = 2, | ||
100 | .desc = "Wheel View", | ||
101 | .wakeup = 0, | ||
102 | }, { | ||
103 | .type = EV_KEY, | ||
104 | .code = KEY_M, | ||
105 | .gpio = 3, | ||
106 | .desc = "Wheel Menu", | ||
107 | .wakeup = 0, | ||
108 | }, { | ||
109 | .type = EV_KEY, | ||
110 | .code = KEY_UP, | ||
111 | .gpio = 32, | ||
112 | .desc = "Nav Pad Up", | ||
113 | .wakeup = 0, | ||
114 | }, { | ||
115 | .type = EV_KEY, | ||
116 | .code = KEY_RIGHT, | ||
117 | .gpio = 33, | ||
118 | .desc = "Nav Pad Right", | ||
119 | .wakeup = 0, | ||
120 | }, { | ||
121 | .type = EV_KEY, | ||
122 | .code = KEY_DOWN, | ||
123 | .gpio = 34, | ||
124 | .desc = "Nav Pad Down", | ||
125 | .wakeup = 0, | ||
126 | }, { | ||
127 | .type = EV_KEY, | ||
128 | .code = KEY_LEFT, | ||
129 | .gpio = 35, | ||
130 | .desc = "Nav Pad Left", | ||
131 | .wakeup = 0, | ||
132 | }, { | ||
133 | .type = EV_KEY, | ||
134 | .code = KEY_ENTER, | ||
135 | .gpio = 38, | ||
136 | .desc = "Nav Pad Ok", | ||
137 | .wakeup = 0, | ||
138 | }, { | ||
139 | .type = EV_KEY, | ||
140 | .code = KEY_O, | ||
141 | .gpio = 39, | ||
142 | .desc = "Wheel Off", | ||
143 | .wakeup = 0, | ||
144 | }, { | ||
145 | .type = EV_KEY, | ||
146 | .code = BTN_FORWARD, | ||
147 | .gpio = 50, | ||
148 | .desc = "Focus Forward", | ||
149 | .wakeup = 0, | ||
150 | }, { | ||
151 | .type = EV_KEY, | ||
152 | .code = BTN_BACK, | ||
153 | .gpio = 51, | ||
154 | .desc = "Focus Backward", | ||
155 | .wakeup = 0, | ||
156 | }, { | ||
157 | .type = EV_KEY, | ||
158 | .code = BTN_MIDDLE, | ||
159 | .gpio = 52, | ||
160 | .desc = "Release Half", | ||
161 | .wakeup = 0, | ||
162 | }, { | ||
163 | .type = EV_KEY, | ||
164 | .code = BTN_EXTRA, | ||
165 | .gpio = 53, | ||
166 | .desc = "Release Full", | ||
167 | .wakeup = 0, | ||
168 | }, | ||
169 | }; | ||
170 | |||
171 | static struct gpio_keys_platform_data pcm037_gpio_keys_platform_data = { | ||
172 | .buttons = pcm037_gpio_keys, | ||
173 | .nbuttons = ARRAY_SIZE(pcm037_gpio_keys), | ||
174 | .rep = 0, /* No auto-repeat */ | ||
175 | }; | ||
176 | |||
177 | static struct platform_device pcm037_gpio_keys_device = { | ||
178 | .name = "gpio-keys", | ||
179 | .id = -1, | ||
180 | .dev = { | ||
181 | .platform_data = &pcm037_gpio_keys_platform_data, | ||
182 | }, | ||
183 | }; | ||
184 | |||
185 | static int eet_init_devices(void) | ||
186 | { | ||
187 | if (!machine_is_pcm037() || pcm037_variant() != PCM037_EET) | ||
188 | return 0; | ||
189 | |||
190 | mxc_iomux_setup_multiple_pins(pcm037_eet_pins, | ||
191 | ARRAY_SIZE(pcm037_eet_pins), "pcm037_eet"); | ||
192 | |||
193 | /* SPI */ | ||
194 | spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev)); | ||
195 | #if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE) | ||
196 | mxc_register_device(&mxc_spi_device0, &pcm037_spi1_master); | ||
197 | #endif | ||
198 | |||
199 | platform_device_register(&pcm037_gpio_keys_device); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | late_initcall(eet_init_devices); | ||
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h index ae8441192ef0..7139e0dc26d1 100644 --- a/arch/arm/mach-pxa/include/mach/mfp-pxa300.h +++ b/arch/arm/mach-pxa/include/mach/mfp-pxa300.h | |||
@@ -567,9 +567,9 @@ | |||
567 | #define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3) | 567 | #define GPIO37_ULPI_DATA_OUT_7 MFP_CFG(GPIO37, AF3) |
568 | #define GPIO33_ULPI_OTG_INTR MFP_CFG(GPIO33, AF1) | 568 | #define GPIO33_ULPI_OTG_INTR MFP_CFG(GPIO33, AF1) |
569 | 569 | ||
570 | #define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, MFP_AF0, MFP_DS01X) | 570 | #define ULPI_DIR MFP_CFG_DRV(ULPI_DIR, AF0, DS01X) |
571 | #define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, MFP_AF0, MFP_DS01X) | 571 | #define ULPI_NXT MFP_CFG_DRV(ULPI_NXT, AF0, DS01X) |
572 | #define ULPI_STP MFP_CFG_DRV(ULPI_STP, MFP_AF0, MFP_DS01X) | 572 | #define ULPI_STP MFP_CFG_DRV(ULPI_STP, AF0, DS01X) |
573 | #endif /* CONFIG_CPU_PXA310 */ | 573 | #endif /* CONFIG_CPU_PXA310 */ |
574 | 574 | ||
575 | #endif /* __ASM_ARCH_MFP_PXA300_H */ | 575 | #endif /* __ASM_ARCH_MFP_PXA300_H */ |
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 6f678d93bf4e..09b7b1a10cad 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c | |||
@@ -250,7 +250,7 @@ static DEFINE_PXA3_CKEN(pxa3xx_mmc2, MMC2, 19500000, 0); | |||
250 | static struct clk_lookup pxa3xx_clkregs[] = { | 250 | static struct clk_lookup pxa3xx_clkregs[] = { |
251 | INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), | 251 | INIT_CLKREG(&clk_pxa3xx_pout, NULL, "CLK_POUT"), |
252 | /* Power I2C clock is always on */ | 252 | /* Power I2C clock is always on */ |
253 | INIT_CLKREG(&clk_dummy, "pxa2xx-i2c.1", NULL), | 253 | INIT_CLKREG(&clk_dummy, "pxa3xx-pwri2c.1", NULL), |
254 | INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), | 254 | INIT_CLKREG(&clk_pxa3xx_lcd, "pxa2xx-fb", NULL), |
255 | INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), | 255 | INIT_CLKREG(&clk_pxa3xx_camera, NULL, "CAMCLK"), |
256 | INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), | 256 | INIT_CLKREG(&clk_pxa3xx_ac97, NULL, "AC97CLK"), |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 9ea9c05093cd..facbd49eec67 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -208,8 +208,7 @@ struct platform_device realview_i2c_device = { | |||
208 | 208 | ||
209 | static struct i2c_board_info realview_i2c_board_info[] = { | 209 | static struct i2c_board_info realview_i2c_board_info[] = { |
210 | { | 210 | { |
211 | I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1), | 211 | I2C_BOARD_INFO("ds1338", 0xd0 >> 1), |
212 | .type = "ds1338", | ||
213 | }, | 212 | }, |
214 | }; | 213 | }; |
215 | 214 | ||
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 89b3ccf35e1b..7936085dd758 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
@@ -455,8 +455,8 @@ void __init u300_init_irq(void) | |||
455 | for (i = 0; i < NR_IRQS; i++) | 455 | for (i = 0; i < NR_IRQS; i++) |
456 | set_bit(i, (unsigned long *) &mask[0]); | 456 | set_bit(i, (unsigned long *) &mask[0]); |
457 | u300_enable_intcon_clock(); | 457 | u300_enable_intcon_clock(); |
458 | vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], 0); | 458 | vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]); |
459 | vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], 0); | 459 | vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]); |
460 | } | 460 | } |
461 | 461 | ||
462 | 462 | ||
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 69214fc8bd19..31093af7d052 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -342,8 +342,7 @@ static struct platform_device versatile_i2c_device = { | |||
342 | 342 | ||
343 | static struct i2c_board_info versatile_i2c_board_info[] = { | 343 | static struct i2c_board_info versatile_i2c_board_info[] = { |
344 | { | 344 | { |
345 | I2C_BOARD_INFO("rtc-ds1307", 0xd0 >> 1), | 345 | I2C_BOARD_INFO("ds1338", 0xd0 >> 1), |
346 | .type = "ds1338", | ||
347 | }, | 346 | }, |
348 | }; | 347 | }; |
349 | 348 | ||
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index 27f8d1b2bc6b..2eb182f73876 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h | |||
@@ -602,6 +602,8 @@ enum iomux_pins { | |||
602 | #define MX31_PIN_I2C_DAT__SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) | 602 | #define MX31_PIN_I2C_DAT__SDA IOMUX_MODE(MX31_PIN_I2C_DAT, IOMUX_CONFIG_FUNC) |
603 | #define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2) | 603 | #define MX31_PIN_DCD_DTE1__I2C2_SDA IOMUX_MODE(MX31_PIN_DCD_DTE1, IOMUX_CONFIG_ALT2) |
604 | #define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2) | 604 | #define MX31_PIN_RI_DTE1__I2C2_SCL IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_ALT2) |
605 | #define MX31_PIN_CSPI2_SS2__I2C3_SDA IOMUX_MODE(MX31_PIN_CSPI2_SS2, IOMUX_CONFIG_ALT1) | ||
606 | #define MX31_PIN_CSPI2_SCLK__I2C3_SCL IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_ALT1) | ||
605 | #define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC) | 607 | #define MX31_PIN_CSI_D4__CSI_D4 IOMUX_MODE(MX31_PIN_CSI_D4, IOMUX_CONFIG_FUNC) |
606 | #define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC) | 608 | #define MX31_PIN_CSI_D5__CSI_D5 IOMUX_MODE(MX31_PIN_CSI_D5, IOMUX_CONFIG_FUNC) |
607 | #define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC) | 609 | #define MX31_PIN_CSI_D6__CSI_D6 IOMUX_MODE(MX31_PIN_CSI_D6, IOMUX_CONFIG_FUNC) |
diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c index abc79d44acaa..98548c6903a0 100644 --- a/arch/arm/plat-pxa/gpio.c +++ b/arch/arm/plat-pxa/gpio.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/sysdev.h> | 18 | #include <linux/sysdev.h> |
19 | #include <linux/bootmem.h> | 19 | #include <linux/slab.h> |
20 | 20 | ||
21 | #include <mach/gpio.h> | 21 | #include <mach/gpio.h> |
22 | 22 | ||
@@ -112,17 +112,12 @@ static int __init pxa_init_gpio_chip(int gpio_end) | |||
112 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; | 112 | int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; |
113 | struct pxa_gpio_chip *chips; | 113 | struct pxa_gpio_chip *chips; |
114 | 114 | ||
115 | /* this is early, we have to use bootmem allocator, and we really | 115 | chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL); |
116 | * want this to be allocated dynamically for different 'gpio_end' | ||
117 | */ | ||
118 | chips = alloc_bootmem_low(nbanks * sizeof(struct pxa_gpio_chip)); | ||
119 | if (chips == NULL) { | 116 | if (chips == NULL) { |
120 | pr_err("%s: failed to allocate GPIO chips\n", __func__); | 117 | pr_err("%s: failed to allocate GPIO chips\n", __func__); |
121 | return -ENOMEM; | 118 | return -ENOMEM; |
122 | } | 119 | } |
123 | 120 | ||
124 | memset(chips, 0, nbanks * sizeof(struct pxa_gpio_chip)); | ||
125 | |||
126 | for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { | 121 | for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32) { |
127 | struct gpio_chip *c = &chips[i].chip; | 122 | struct gpio_chip *c = &chips[i].chip; |
128 | 123 | ||
diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h index 4442f8d2d423..fc42de5ca209 100644 --- a/arch/avr32/include/asm/thread_info.h +++ b/arch/avr32/include/asm/thread_info.h | |||
@@ -40,7 +40,7 @@ struct thread_info { | |||
40 | .exec_domain = &default_exec_domain, \ | 40 | .exec_domain = &default_exec_domain, \ |
41 | .flags = 0, \ | 41 | .flags = 0, \ |
42 | .cpu = 0, \ | 42 | .cpu = 0, \ |
43 | .preempt_count = 1, \ | 43 | .preempt_count = INIT_PREEMPT_COUNT, \ |
44 | .restart_block = { \ | 44 | .restart_block = { \ |
45 | .fn = do_no_restart_syscall \ | 45 | .fn = do_no_restart_syscall \ |
46 | } \ | 46 | } \ |
diff --git a/arch/blackfin/include/asm/context.S b/arch/blackfin/include/asm/context.S index 16561ab18b38..f8a664f022b1 100644 --- a/arch/blackfin/include/asm/context.S +++ b/arch/blackfin/include/asm/context.S | |||
@@ -223,9 +223,10 @@ | |||
223 | [--sp] = RETN; | 223 | [--sp] = RETN; |
224 | [--sp] = RETE; | 224 | [--sp] = RETE; |
225 | [--sp] = SEQSTAT; | 225 | [--sp] = SEQSTAT; |
226 | #ifdef CONFIG_KGDB | 226 | #ifdef CONFIG_DEBUG_KERNEL |
227 | r1.l = lo(IPEND); | 227 | p1.l = lo(IPEND); |
228 | r1.h = hi(IPEND); | 228 | p1.h = hi(IPEND); |
229 | r1 = [p1]; | ||
229 | [--sp] = r1; | 230 | [--sp] = r1; |
230 | #else | 231 | #else |
231 | [--sp] = r0; /* Skip IPEND as well. */ | 232 | [--sp] = r0; /* Skip IPEND as well. */ |
diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h index 565b8136855e..fadfa82f93b2 100644 --- a/arch/blackfin/include/asm/cpu.h +++ b/arch/blackfin/include/asm/cpu.h | |||
@@ -32,7 +32,6 @@ struct blackfin_cpudata { | |||
32 | struct task_struct *idle; | 32 | struct task_struct *idle; |
33 | unsigned int imemctl; | 33 | unsigned int imemctl; |
34 | unsigned int dmemctl; | 34 | unsigned int dmemctl; |
35 | unsigned long loops_per_jiffy; | ||
36 | unsigned long dcache_invld_count; | 35 | unsigned long dcache_invld_count; |
37 | unsigned long icache_invld_count; | 36 | unsigned long icache_invld_count; |
38 | }; | 37 | }; |
diff --git a/arch/blackfin/include/asm/hardirq.h b/arch/blackfin/include/asm/hardirq.h index cbd52f86bb9f..0b78b873df51 100644 --- a/arch/blackfin/include/asm/hardirq.h +++ b/arch/blackfin/include/asm/hardirq.h | |||
@@ -6,6 +6,9 @@ | |||
6 | extern void ack_bad_irq(unsigned int irq); | 6 | extern void ack_bad_irq(unsigned int irq); |
7 | #define ack_bad_irq ack_bad_irq | 7 | #define ack_bad_irq ack_bad_irq |
8 | 8 | ||
9 | /* Define until common code gets sane defaults */ | ||
10 | #define HARDIRQ_BITS 9 | ||
11 | |||
9 | #include <asm-generic/hardirq.h> | 12 | #include <asm-generic/hardirq.h> |
10 | 13 | ||
11 | #endif | 14 | #endif |
diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h index d0be99be8308..a36ad8dac068 100644 --- a/arch/blackfin/include/asm/processor.h +++ b/arch/blackfin/include/asm/processor.h | |||
@@ -105,23 +105,16 @@ static inline uint32_t __pure bfin_revid(void) | |||
105 | /* Always use CHIPID, to work around ANOMALY_05000234 */ | 105 | /* Always use CHIPID, to work around ANOMALY_05000234 */ |
106 | uint32_t revid = (bfin_read_CHIPID() & CHIPID_VERSION) >> 28; | 106 | uint32_t revid = (bfin_read_CHIPID() & CHIPID_VERSION) >> 28; |
107 | 107 | ||
108 | #ifdef CONFIG_BF52x | 108 | #ifdef _BOOTROM_GET_DXE_ADDRESS_TWI |
109 | /* ANOMALY_05000357 | 109 | /* |
110 | * ANOMALY_05000364 | ||
110 | * Incorrect Revision Number in DSPID Register | 111 | * Incorrect Revision Number in DSPID Register |
111 | */ | 112 | */ |
112 | if (revid == 0) | 113 | if (ANOMALY_05000364 && |
113 | switch (bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI)) { | 114 | bfin_read16(_BOOTROM_GET_DXE_ADDRESS_TWI) == 0x2796) |
114 | case 0x0010: | 115 | revid = 1; |
115 | revid = 0; | ||
116 | break; | ||
117 | case 0x2796: | ||
118 | revid = 1; | ||
119 | break; | ||
120 | default: | ||
121 | revid = 0xFFFF; | ||
122 | break; | ||
123 | } | ||
124 | #endif | 116 | #endif |
117 | |||
125 | return revid; | 118 | return revid; |
126 | } | 119 | } |
127 | 120 | ||
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h index 2920087516f2..2bbfdd950afc 100644 --- a/arch/blackfin/include/asm/thread_info.h +++ b/arch/blackfin/include/asm/thread_info.h | |||
@@ -77,7 +77,7 @@ struct thread_info { | |||
77 | .exec_domain = &default_exec_domain, \ | 77 | .exec_domain = &default_exec_domain, \ |
78 | .flags = 0, \ | 78 | .flags = 0, \ |
79 | .cpu = 0, \ | 79 | .cpu = 0, \ |
80 | .preempt_count = 1, \ | 80 | .preempt_count = INIT_PREEMPT_COUNT, \ |
81 | .restart_block = { \ | 81 | .restart_block = { \ |
82 | .fn = do_no_restart_syscall, \ | 82 | .fn = do_no_restart_syscall, \ |
83 | }, \ | 83 | }, \ |
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index e0bf8cc06907..9f9b82816652 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c | |||
@@ -253,32 +253,31 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size) | |||
253 | BUG_ON(src % 4); | 253 | BUG_ON(src % 4); |
254 | BUG_ON(size % 4); | 254 | BUG_ON(size % 4); |
255 | 255 | ||
256 | /* Force a sync in case a previous config reset on this channel | ||
257 | * occurred. This is needed so subsequent writes to DMA registers | ||
258 | * are not spuriously lost/corrupted. | ||
259 | */ | ||
260 | __builtin_bfin_ssync(); | ||
261 | |||
262 | src_ch = 0; | 256 | src_ch = 0; |
263 | /* Find an avalible memDMA channel */ | 257 | /* Find an avalible memDMA channel */ |
264 | while (1) { | 258 | while (1) { |
265 | if (!src_ch || src_ch == (struct dma_register *)MDMA_S1_NEXT_DESC_PTR) { | 259 | if (src_ch == (struct dma_register *)MDMA_S0_NEXT_DESC_PTR) { |
266 | dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR; | ||
267 | src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR; | ||
268 | } else { | ||
269 | dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR; | 260 | dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR; |
270 | src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR; | 261 | src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR; |
262 | } else { | ||
263 | dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR; | ||
264 | src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR; | ||
271 | } | 265 | } |
272 | 266 | ||
273 | if (!bfin_read16(&src_ch->cfg)) { | 267 | if (!bfin_read16(&src_ch->cfg)) |
268 | break; | ||
269 | else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) { | ||
270 | bfin_write16(&src_ch->cfg, 0); | ||
274 | break; | 271 | break; |
275 | } else { | ||
276 | if (bfin_read16(&src_ch->irq_status) & DMA_DONE) | ||
277 | bfin_write16(&src_ch->cfg, 0); | ||
278 | } | 272 | } |
279 | |||
280 | } | 273 | } |
281 | 274 | ||
275 | /* Force a sync in case a previous config reset on this channel | ||
276 | * occurred. This is needed so subsequent writes to DMA registers | ||
277 | * are not spuriously lost/corrupted. | ||
278 | */ | ||
279 | __builtin_bfin_ssync(); | ||
280 | |||
282 | /* Destination */ | 281 | /* Destination */ |
283 | bfin_write32(&dst_ch->start_addr, dst); | 282 | bfin_write32(&dst_ch->start_addr, dst); |
284 | bfin_write16(&dst_ch->x_count, size >> 2); | 283 | bfin_write16(&dst_ch->x_count, size >> 2); |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index beffa00a93c3..6b9446271371 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -686,14 +686,12 @@ void bfin_gpio_pm_hibernate_restore(void) | |||
686 | *port_fer[bank] = gpio_bank_saved[bank].fer; | 686 | *port_fer[bank] = gpio_bank_saved[bank].fer; |
687 | #endif | 687 | #endif |
688 | gpio_array[bank]->inen = gpio_bank_saved[bank].inen; | 688 | gpio_array[bank]->inen = gpio_bank_saved[bank].inen; |
689 | gpio_array[bank]->data_set = gpio_bank_saved[bank].data | ||
690 | & gpio_bank_saved[bank].dir; | ||
689 | gpio_array[bank]->dir = gpio_bank_saved[bank].dir; | 691 | gpio_array[bank]->dir = gpio_bank_saved[bank].dir; |
690 | gpio_array[bank]->polar = gpio_bank_saved[bank].polar; | 692 | gpio_array[bank]->polar = gpio_bank_saved[bank].polar; |
691 | gpio_array[bank]->edge = gpio_bank_saved[bank].edge; | 693 | gpio_array[bank]->edge = gpio_bank_saved[bank].edge; |
692 | gpio_array[bank]->both = gpio_bank_saved[bank].both; | 694 | gpio_array[bank]->both = gpio_bank_saved[bank].both; |
693 | |||
694 | gpio_array[bank]->data_set = gpio_bank_saved[bank].data | ||
695 | | gpio_bank_saved[bank].dir; | ||
696 | |||
697 | gpio_array[bank]->maska = gpio_bank_saved[bank].maska; | 695 | gpio_array[bank]->maska = gpio_bank_saved[bank].maska; |
698 | } | 696 | } |
699 | AWA_DUMMY_READ(maska); | 697 | AWA_DUMMY_READ(maska); |
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index d6c067782e63..685f160a5a36 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c | |||
@@ -72,13 +72,24 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | /* Cover L1 memory. One 4M area for code and data each is enough. */ | 74 | /* Cover L1 memory. One 4M area for code and data each is enough. */ |
75 | if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { | 75 | if (cpu == 0) { |
76 | d_tbl[i_d].addr = L1_DATA_A_START; | 76 | if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { |
77 | d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; | 77 | d_tbl[i_d].addr = L1_DATA_A_START; |
78 | d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; | ||
79 | } | ||
80 | i_tbl[i_i].addr = L1_CODE_START; | ||
81 | i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; | ||
78 | } | 82 | } |
79 | i_tbl[i_i].addr = L1_CODE_START; | 83 | #ifdef CONFIG_SMP |
80 | i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; | 84 | else { |
81 | 85 | if (L1_DATA_A_LENGTH || L1_DATA_B_LENGTH) { | |
86 | d_tbl[i_d].addr = COREB_L1_DATA_A_START; | ||
87 | d_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; | ||
88 | } | ||
89 | i_tbl[i_i].addr = COREB_L1_CODE_START; | ||
90 | i_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; | ||
91 | } | ||
92 | #endif | ||
82 | first_switched_dcplb = i_d; | 93 | first_switched_dcplb = i_d; |
83 | first_switched_icplb = i_i; | 94 | first_switched_icplb = i_i; |
84 | 95 | ||
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 79cad0ac5892..9da36bab7ccb 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -361,7 +361,7 @@ static inline | |||
361 | int in_mem_const(unsigned long addr, unsigned long size, | 361 | int in_mem_const(unsigned long addr, unsigned long size, |
362 | unsigned long const_addr, unsigned long const_size) | 362 | unsigned long const_addr, unsigned long const_size) |
363 | { | 363 | { |
364 | return in_mem_const_off(addr, 0, size, const_addr, const_size); | 364 | return in_mem_const_off(addr, size, 0, const_addr, const_size); |
365 | } | 365 | } |
366 | #define IN_ASYNC(bnum, bctlnum) \ | 366 | #define IN_ASYNC(bnum, bctlnum) \ |
367 | ({ \ | 367 | ({ \ |
@@ -390,13 +390,13 @@ int bfin_mem_access_type(unsigned long addr, unsigned long size) | |||
390 | if (in_mem_const(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH)) | 390 | if (in_mem_const(addr, size, L1_DATA_B_START, L1_DATA_B_LENGTH)) |
391 | return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; | 391 | return cpu == 0 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; |
392 | #ifdef COREB_L1_CODE_START | 392 | #ifdef COREB_L1_CODE_START |
393 | if (in_mem_const(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH)) | 393 | if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) |
394 | return cpu == 1 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA; | 394 | return cpu == 1 ? BFIN_MEM_ACCESS_ITEST : BFIN_MEM_ACCESS_IDMA; |
395 | if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) | 395 | if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) |
396 | return cpu == 1 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT; | 396 | return cpu == 1 ? BFIN_MEM_ACCESS_CORE_ONLY : -EFAULT; |
397 | if (in_mem_const(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH)) | 397 | if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) |
398 | return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; | 398 | return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; |
399 | if (in_mem_const(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH)) | 399 | if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) |
400 | return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; | 400 | return cpu == 1 ? BFIN_MEM_ACCESS_CORE : BFIN_MEM_ACCESS_IDMA; |
401 | #endif | 401 | #endif |
402 | if (in_mem_const(addr, size, L2_START, L2_LENGTH)) | 402 | if (in_mem_const(addr, size, L2_START, L2_LENGTH)) |
@@ -472,13 +472,13 @@ int _access_ok(unsigned long addr, unsigned long size) | |||
472 | if (in_mem_const_off(addr, size, _ebss_b_l1 - _sdata_b_l1, L1_DATA_B_START, L1_DATA_B_LENGTH)) | 472 | if (in_mem_const_off(addr, size, _ebss_b_l1 - _sdata_b_l1, L1_DATA_B_START, L1_DATA_B_LENGTH)) |
473 | return 1; | 473 | return 1; |
474 | #ifdef COREB_L1_CODE_START | 474 | #ifdef COREB_L1_CODE_START |
475 | if (in_mem_const(addr, size, COREB_L1_CODE_START, L1_CODE_LENGTH)) | 475 | if (in_mem_const(addr, size, COREB_L1_CODE_START, COREB_L1_CODE_LENGTH)) |
476 | return 1; | 476 | return 1; |
477 | if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) | 477 | if (in_mem_const(addr, size, COREB_L1_SCRATCH_START, L1_SCRATCH_LENGTH)) |
478 | return 1; | 478 | return 1; |
479 | if (in_mem_const(addr, size, COREB_L1_DATA_A_START, L1_DATA_A_LENGTH)) | 479 | if (in_mem_const(addr, size, COREB_L1_DATA_A_START, COREB_L1_DATA_A_LENGTH)) |
480 | return 1; | 480 | return 1; |
481 | if (in_mem_const(addr, size, COREB_L1_DATA_B_START, L1_DATA_B_LENGTH)) | 481 | if (in_mem_const(addr, size, COREB_L1_DATA_B_START, COREB_L1_DATA_B_LENGTH)) |
482 | return 1; | 482 | return 1; |
483 | #endif | 483 | #endif |
484 | if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH)) | 484 | if (in_mem_const_off(addr, size, _ebss_l2 - _stext_l2, L2_START, L2_LENGTH)) |
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index d76618db50df..6a387eec6b65 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
32 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
33 | #include <linux/smp.h> | 33 | #include <linux/smp.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
36 | #include <linux/ptrace.h> | 35 | #include <linux/ptrace.h> |
37 | #include <linux/user.h> | 36 | #include <linux/user.h> |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 6136c33e919f..6225edae488e 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -168,7 +168,6 @@ void __cpuinit bfin_setup_cpudata(unsigned int cpu) | |||
168 | struct blackfin_cpudata *cpudata = &per_cpu(cpu_data, cpu); | 168 | struct blackfin_cpudata *cpudata = &per_cpu(cpu_data, cpu); |
169 | 169 | ||
170 | cpudata->idle = current; | 170 | cpudata->idle = current; |
171 | cpudata->loops_per_jiffy = loops_per_jiffy; | ||
172 | cpudata->imemctl = bfin_read_IMEM_CONTROL(); | 171 | cpudata->imemctl = bfin_read_IMEM_CONTROL(); |
173 | cpudata->dmemctl = bfin_read_DMEM_CONTROL(); | 172 | cpudata->dmemctl = bfin_read_DMEM_CONTROL(); |
174 | } | 173 | } |
@@ -568,17 +567,23 @@ static __init void memory_setup(void) | |||
568 | # endif /* ANOMALY_05000263 */ | 567 | # endif /* ANOMALY_05000263 */ |
569 | # endif /* CONFIG_ROMFS_FS */ | 568 | # endif /* CONFIG_ROMFS_FS */ |
570 | 569 | ||
571 | memory_end -= mtd_size; | 570 | /* Since the default MTD_UCLINUX has no magic number, we just blindly |
572 | 571 | * read 8 past the end of the kernel's image, and look at it. | |
573 | if (mtd_size == 0) { | 572 | * When no image is attached, mtd_size is set to a random number |
574 | console_init(); | 573 | * Do some basic sanity checks before operating on things |
575 | panic("Don't boot kernel without rootfs attached."); | 574 | */ |
575 | if (mtd_size == 0 || memory_end <= mtd_size) { | ||
576 | pr_emerg("Could not find valid ram mtd attached.\n"); | ||
577 | } else { | ||
578 | memory_end -= mtd_size; | ||
579 | |||
580 | /* Relocate MTD image to the top of memory after the uncached memory area */ | ||
581 | uclinux_ram_map.phys = memory_mtd_start = memory_end; | ||
582 | uclinux_ram_map.size = mtd_size; | ||
583 | pr_info("Found mtd parition at 0x%p, (len=0x%lx), moving to 0x%p\n", | ||
584 | _end, mtd_size, (void *)memory_mtd_start); | ||
585 | dma_memcpy((void *)uclinux_ram_map.phys, _end, uclinux_ram_map.size); | ||
576 | } | 586 | } |
577 | |||
578 | /* Relocate MTD image to the top of memory after the uncached memory area */ | ||
579 | uclinux_ram_map.phys = memory_mtd_start = memory_end; | ||
580 | uclinux_ram_map.size = mtd_size; | ||
581 | dma_memcpy((void *)uclinux_ram_map.phys, _end, uclinux_ram_map.size); | ||
582 | #endif /* CONFIG_MTD_UCLINUX */ | 587 | #endif /* CONFIG_MTD_UCLINUX */ |
583 | 588 | ||
584 | #if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263) | 589 | #if (defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) && ANOMALY_05000263) |
@@ -868,13 +873,6 @@ void __init setup_arch(char **cmdline_p) | |||
868 | else | 873 | else |
869 | printk(KERN_CONT "and Disabled\n"); | 874 | printk(KERN_CONT "and Disabled\n"); |
870 | 875 | ||
871 | #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) | ||
872 | /* we need to initialize the Flashrom device here since we might | ||
873 | * do things with flash early on in the boot | ||
874 | */ | ||
875 | flash_probe(); | ||
876 | #endif | ||
877 | |||
878 | printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); | 876 | printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); |
879 | 877 | ||
880 | /* Newer parts mirror SWRST bits in SYSCR */ | 878 | /* Newer parts mirror SWRST bits in SYSCR */ |
@@ -938,10 +936,6 @@ void __init setup_arch(char **cmdline_p) | |||
938 | CPU, bfin_revid()); | 936 | CPU, bfin_revid()); |
939 | } | 937 | } |
940 | 938 | ||
941 | /* We can't run on BF548-0.1 due to ANOMALY 05000448 */ | ||
942 | if (bfin_cpuid() == 0x27de && bfin_revid() == 1) | ||
943 | panic("You can't run on this processor due to 05000448"); | ||
944 | |||
945 | printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); | 939 | printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); |
946 | 940 | ||
947 | printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", | 941 | printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", |
@@ -1164,9 +1158,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1164 | sclk/1000000, sclk%1000000); | 1158 | sclk/1000000, sclk%1000000); |
1165 | seq_printf(m, "bogomips\t: %lu.%02lu\n" | 1159 | seq_printf(m, "bogomips\t: %lu.%02lu\n" |
1166 | "Calibration\t: %lu loops\n", | 1160 | "Calibration\t: %lu loops\n", |
1167 | (cpudata->loops_per_jiffy * HZ) / 500000, | 1161 | (loops_per_jiffy * HZ) / 500000, |
1168 | ((cpudata->loops_per_jiffy * HZ) / 5000) % 100, | 1162 | ((loops_per_jiffy * HZ) / 5000) % 100, |
1169 | (cpudata->loops_per_jiffy * HZ)); | 1163 | (loops_per_jiffy * HZ)); |
1170 | 1164 | ||
1171 | /* Check Cache configutation */ | 1165 | /* Check Cache configutation */ |
1172 | switch (cpudata->dmemctl & (1 << DMC0_P | 1 << DMC1_P)) { | 1166 | switch (cpudata->dmemctl & (1 << DMC0_P | 1 << DMC1_P)) { |
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index a8f1329c15a4..3da60fb13ce4 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c | |||
@@ -29,7 +29,6 @@ | |||
29 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 29 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
34 | #include <linux/sem.h> | 33 | #include <linux/sem.h> |
35 | #include <linux/msg.h> | 34 | #include <linux/msg.h> |
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 8a1caf2bb5b9..bf2b2d1f8ae5 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -570,11 +570,12 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
570 | if (kernel_mode_regs(fp) || (current && !current->mm)) { | 570 | if (kernel_mode_regs(fp) || (current && !current->mm)) { |
571 | console_verbose(); | 571 | console_verbose(); |
572 | oops_in_progress = 1; | 572 | oops_in_progress = 1; |
573 | if (strerror) | ||
574 | verbose_printk(strerror); | ||
575 | } | 573 | } |
576 | 574 | ||
577 | if (sig != SIGTRAP) { | 575 | if (sig != SIGTRAP) { |
576 | if (strerror) | ||
577 | verbose_printk(strerror); | ||
578 | |||
578 | dump_bfin_process(fp); | 579 | dump_bfin_process(fp); |
579 | dump_bfin_mem(fp); | 580 | dump_bfin_mem(fp); |
580 | show_regs(fp); | 581 | show_regs(fp); |
@@ -619,7 +620,9 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
619 | force_sig_info(sig, &info, current); | 620 | force_sig_info(sig, &info, current); |
620 | } | 621 | } |
621 | 622 | ||
622 | if (ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) | 623 | if ((ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) || |
624 | (ANOMALY_05000281 && trapnr == VEC_HWERR) || | ||
625 | (ANOMALY_05000189 && (trapnr == VEC_CPLB_I_VL || trapnr == VEC_CPLB_VL))) | ||
623 | fp->pc = SAFE_USER_INSTRUCTION; | 626 | fp->pc = SAFE_USER_INSTRUCTION; |
624 | 627 | ||
625 | traps_done: | 628 | traps_done: |
diff --git a/arch/blackfin/lib/lshrdi3.c b/arch/blackfin/lib/lshrdi3.c index 84b9c5592220..e57bf6fbdf3f 100644 --- a/arch/blackfin/lib/lshrdi3.c +++ b/arch/blackfin/lib/lshrdi3.c | |||
@@ -27,21 +27,7 @@ | |||
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #define BITS_PER_UNIT 8 | 30 | #include "gcclib.h" |
31 | |||
32 | typedef int SItype __attribute__ ((mode(SI))); | ||
33 | typedef unsigned int USItype __attribute__ ((mode(SI))); | ||
34 | typedef int DItype __attribute__ ((mode(DI))); | ||
35 | typedef int word_type __attribute__ ((mode(__word__))); | ||
36 | |||
37 | struct DIstruct { | ||
38 | SItype high, low; | ||
39 | }; | ||
40 | |||
41 | typedef union { | ||
42 | struct DIstruct s; | ||
43 | DItype ll; | ||
44 | } DIunion; | ||
45 | 31 | ||
46 | #ifdef CONFIG_ARITHMETIC_OPS_L1 | 32 | #ifdef CONFIG_ARITHMETIC_OPS_L1 |
47 | DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text)); | 33 | DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text)); |
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c index d9791106be9f..809be268e42d 100644 --- a/arch/blackfin/mach-bf518/boards/ezbrd.c +++ b/arch/blackfin/mach-bf518/boards/ezbrd.c | |||
@@ -534,7 +534,7 @@ static struct platform_device i2c_bfin_twi_device = { | |||
534 | #endif | 534 | #endif |
535 | 535 | ||
536 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { | 536 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { |
537 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) | 537 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) |
538 | { | 538 | { |
539 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), | 539 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), |
540 | }, | 540 | }, |
diff --git a/arch/blackfin/mach-bf518/include/mach/anomaly.h b/arch/blackfin/mach-bf518/include/mach/anomaly.h index 426e064062a0..753ed810e1c6 100644 --- a/arch/blackfin/mach-bf518/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf518/include/mach/anomaly.h | |||
@@ -82,6 +82,7 @@ | |||
82 | #define ANOMALY_05000179 (0) | 82 | #define ANOMALY_05000179 (0) |
83 | #define ANOMALY_05000182 (0) | 83 | #define ANOMALY_05000182 (0) |
84 | #define ANOMALY_05000183 (0) | 84 | #define ANOMALY_05000183 (0) |
85 | #define ANOMALY_05000189 (0) | ||
85 | #define ANOMALY_05000198 (0) | 86 | #define ANOMALY_05000198 (0) |
86 | #define ANOMALY_05000202 (0) | 87 | #define ANOMALY_05000202 (0) |
87 | #define ANOMALY_05000215 (0) | 88 | #define ANOMALY_05000215 (0) |
@@ -117,6 +118,7 @@ | |||
117 | #define ANOMALY_05000357 (0) | 118 | #define ANOMALY_05000357 (0) |
118 | #define ANOMALY_05000362 (1) | 119 | #define ANOMALY_05000362 (1) |
119 | #define ANOMALY_05000363 (0) | 120 | #define ANOMALY_05000363 (0) |
121 | #define ANOMALY_05000364 (0) | ||
120 | #define ANOMALY_05000371 (0) | 122 | #define ANOMALY_05000371 (0) |
121 | #define ANOMALY_05000380 (0) | 123 | #define ANOMALY_05000380 (0) |
122 | #define ANOMALY_05000386 (0) | 124 | #define ANOMALY_05000386 (0) |
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h index 0fb2ce5d840e..dbade93395eb 100644 --- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) | 53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) |
54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) | 54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) |
55 | 55 | ||
56 | #define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) | 56 | #define UART_GET_CTS(x) gpio_get_value(x->cts_pin) |
57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | 57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) |
58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | 58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) |
59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) | 59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) |
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c index f4867ce0c618..b09484f538f4 100644 --- a/arch/blackfin/mach-bf527/boards/cm_bf527.c +++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c | |||
@@ -793,7 +793,7 @@ static struct platform_device i2c_bfin_twi_device = { | |||
793 | #endif | 793 | #endif |
794 | 794 | ||
795 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { | 795 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { |
796 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) | 796 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) |
797 | { | 797 | { |
798 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), | 798 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), |
799 | .type = "pcf8574_lcd", | 799 | .type = "pcf8574_lcd", |
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index b2f30f06b73e..2ad68cd10ae6 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c | |||
@@ -591,7 +591,7 @@ static struct platform_device i2c_bfin_twi_device = { | |||
591 | #endif | 591 | #endif |
592 | 592 | ||
593 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { | 593 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { |
594 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) | 594 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) |
595 | { | 595 | { |
596 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), | 596 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), |
597 | }, | 597 | }, |
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index 799a1d1fa890..75e563d3f9d4 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c | |||
@@ -858,7 +858,7 @@ static struct platform_device i2c_bfin_twi_device = { | |||
858 | #endif | 858 | #endif |
859 | 859 | ||
860 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { | 860 | static struct i2c_board_info __initdata bfin_i2c_board_info[] = { |
861 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) | 861 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) |
862 | { | 862 | { |
863 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), | 863 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), |
864 | }, | 864 | }, |
diff --git a/arch/blackfin/mach-bf527/include/mach/anomaly.h b/arch/blackfin/mach-bf527/include/mach/anomaly.h index 0d63f7406168..c438ca89d8c9 100644 --- a/arch/blackfin/mach-bf527/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf527/include/mach/anomaly.h | |||
@@ -176,6 +176,8 @@ | |||
176 | #define ANOMALY_05000443 (1) | 176 | #define ANOMALY_05000443 (1) |
177 | /* The WURESET Bit in the SYSCR Register is not Functional */ | 177 | /* The WURESET Bit in the SYSCR Register is not Functional */ |
178 | #define ANOMALY_05000445 (1) | 178 | #define ANOMALY_05000445 (1) |
179 | /* USB DMA Short Packet Data Corruption */ | ||
180 | #define ANOMALY_05000450 (1) | ||
179 | /* BCODE_QUICKBOOT, BCODE_ALLBOOT, and BCODE_FULLBOOT Settings in SYSCR Register Not Functional */ | 181 | /* BCODE_QUICKBOOT, BCODE_ALLBOOT, and BCODE_FULLBOOT Settings in SYSCR Register Not Functional */ |
180 | #define ANOMALY_05000451 (1) | 182 | #define ANOMALY_05000451 (1) |
181 | /* Incorrect Default Hysteresis Setting for RESET, NMI, and BMODE Signals */ | 183 | /* Incorrect Default Hysteresis Setting for RESET, NMI, and BMODE Signals */ |
@@ -201,6 +203,7 @@ | |||
201 | #define ANOMALY_05000179 (0) | 203 | #define ANOMALY_05000179 (0) |
202 | #define ANOMALY_05000182 (0) | 204 | #define ANOMALY_05000182 (0) |
203 | #define ANOMALY_05000183 (0) | 205 | #define ANOMALY_05000183 (0) |
206 | #define ANOMALY_05000189 (0) | ||
204 | #define ANOMALY_05000198 (0) | 207 | #define ANOMALY_05000198 (0) |
205 | #define ANOMALY_05000202 (0) | 208 | #define ANOMALY_05000202 (0) |
206 | #define ANOMALY_05000215 (0) | 209 | #define ANOMALY_05000215 (0) |
@@ -238,6 +241,5 @@ | |||
238 | #define ANOMALY_05000412 (0) | 241 | #define ANOMALY_05000412 (0) |
239 | #define ANOMALY_05000447 (0) | 242 | #define ANOMALY_05000447 (0) |
240 | #define ANOMALY_05000448 (0) | 243 | #define ANOMALY_05000448 (0) |
241 | #define ANOMALY_05000450 (0) | ||
242 | 244 | ||
243 | #endif | 245 | #endif |
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h index a625659dd67f..ebd6cebc1fbc 100644 --- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) | 53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) |
54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) | 54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) |
55 | 55 | ||
56 | #define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) | 56 | #define UART_GET_CTS(x) gpio_get_value(x->cts_pin) |
57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | 57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) |
58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | 58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) |
59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) | 59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) |
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c index a68ade8a3ca2..3d743ccaff6a 100644 --- a/arch/blackfin/mach-bf533/boards/stamp.c +++ b/arch/blackfin/mach-bf533/boards/stamp.c | |||
@@ -453,7 +453,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { | |||
453 | .irq = 39, | 453 | .irq = 39, |
454 | }, | 454 | }, |
455 | #endif | 455 | #endif |
456 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) | 456 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) |
457 | { | 457 | { |
458 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), | 458 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), |
459 | }, | 459 | }, |
diff --git a/arch/blackfin/mach-bf533/include/mach/anomaly.h b/arch/blackfin/mach-bf533/include/mach/anomaly.h index 70a0ad69c610..cd83db2fb1a1 100644 --- a/arch/blackfin/mach-bf533/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf533/include/mach/anomaly.h | |||
@@ -335,6 +335,7 @@ | |||
335 | #define ANOMALY_05000323 (0) | 335 | #define ANOMALY_05000323 (0) |
336 | #define ANOMALY_05000353 (1) | 336 | #define ANOMALY_05000353 (1) |
337 | #define ANOMALY_05000362 (1) | 337 | #define ANOMALY_05000362 (1) |
338 | #define ANOMALY_05000364 (0) | ||
338 | #define ANOMALY_05000380 (0) | 339 | #define ANOMALY_05000380 (0) |
339 | #define ANOMALY_05000386 (1) | 340 | #define ANOMALY_05000386 (1) |
340 | #define ANOMALY_05000389 (0) | 341 | #define ANOMALY_05000389 (0) |
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h index a3789d7ccf8c..4062e24e759b 100644 --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) | 53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) |
54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) | 54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) |
55 | 55 | ||
56 | #define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) | 56 | #define UART_GET_CTS(x) gpio_get_value(x->cts_pin) |
57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | 57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) |
58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | 58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) |
59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) | 59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) |
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index c1f76dd2c4ed..bd656907b8c0 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c | |||
@@ -1313,10 +1313,10 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = { | |||
1313 | #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) | 1313 | #if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE) |
1314 | { | 1314 | { |
1315 | I2C_BOARD_INFO("ad7142_joystick", 0x2C), | 1315 | I2C_BOARD_INFO("ad7142_joystick", 0x2C), |
1316 | .irq = IRQ_PF5, | 1316 | .irq = IRQ_PG5, |
1317 | }, | 1317 | }, |
1318 | #endif | 1318 | #endif |
1319 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) | 1319 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) |
1320 | { | 1320 | { |
1321 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), | 1321 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), |
1322 | }, | 1322 | }, |
diff --git a/arch/blackfin/mach-bf537/include/mach/anomaly.h b/arch/blackfin/mach-bf537/include/mach/anomaly.h index 57c128cc3b64..e66aa131f517 100644 --- a/arch/blackfin/mach-bf537/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf537/include/mach/anomaly.h | |||
@@ -167,6 +167,7 @@ | |||
167 | #define ANOMALY_05000179 (0) | 167 | #define ANOMALY_05000179 (0) |
168 | #define ANOMALY_05000182 (0) | 168 | #define ANOMALY_05000182 (0) |
169 | #define ANOMALY_05000183 (0) | 169 | #define ANOMALY_05000183 (0) |
170 | #define ANOMALY_05000189 (0) | ||
170 | #define ANOMALY_05000198 (0) | 171 | #define ANOMALY_05000198 (0) |
171 | #define ANOMALY_05000202 (0) | 172 | #define ANOMALY_05000202 (0) |
172 | #define ANOMALY_05000215 (0) | 173 | #define ANOMALY_05000215 (0) |
@@ -186,6 +187,7 @@ | |||
186 | #define ANOMALY_05000353 (1) | 187 | #define ANOMALY_05000353 (1) |
187 | #define ANOMALY_05000362 (1) | 188 | #define ANOMALY_05000362 (1) |
188 | #define ANOMALY_05000363 (0) | 189 | #define ANOMALY_05000363 (0) |
190 | #define ANOMALY_05000364 (0) | ||
189 | #define ANOMALY_05000380 (0) | 191 | #define ANOMALY_05000380 (0) |
190 | #define ANOMALY_05000386 (1) | 192 | #define ANOMALY_05000386 (1) |
191 | #define ANOMALY_05000389 (0) | 193 | #define ANOMALY_05000389 (0) |
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h index b86662fb9de7..e95d54f9af6c 100644 --- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) | 53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) |
54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) | 54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) |
55 | 55 | ||
56 | #define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) | 56 | #define UART_GET_CTS(x) gpio_get_value(x->cts_pin) |
57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | 57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) |
58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | 58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) |
59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) | 59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) |
diff --git a/arch/blackfin/mach-bf538/include/mach/anomaly.h b/arch/blackfin/mach-bf538/include/mach/anomaly.h index c97acdf85cd3..451cf8a82a42 100644 --- a/arch/blackfin/mach-bf538/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf538/include/mach/anomaly.h | |||
@@ -137,6 +137,7 @@ | |||
137 | #define ANOMALY_05000158 (0) | 137 | #define ANOMALY_05000158 (0) |
138 | #define ANOMALY_05000171 (0) | 138 | #define ANOMALY_05000171 (0) |
139 | #define ANOMALY_05000182 (0) | 139 | #define ANOMALY_05000182 (0) |
140 | #define ANOMALY_05000189 (0) | ||
140 | #define ANOMALY_05000198 (0) | 141 | #define ANOMALY_05000198 (0) |
141 | #define ANOMALY_05000202 (0) | 142 | #define ANOMALY_05000202 (0) |
142 | #define ANOMALY_05000215 (0) | 143 | #define ANOMALY_05000215 (0) |
@@ -160,6 +161,7 @@ | |||
160 | #define ANOMALY_05000353 (1) | 161 | #define ANOMALY_05000353 (1) |
161 | #define ANOMALY_05000362 (1) | 162 | #define ANOMALY_05000362 (1) |
162 | #define ANOMALY_05000363 (0) | 163 | #define ANOMALY_05000363 (0) |
164 | #define ANOMALY_05000364 (0) | ||
163 | #define ANOMALY_05000380 (0) | 165 | #define ANOMALY_05000380 (0) |
164 | #define ANOMALY_05000386 (1) | 166 | #define ANOMALY_05000386 (1) |
165 | #define ANOMALY_05000389 (0) | 167 | #define ANOMALY_05000389 (0) |
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h index c536551eb4b8..999f239fe1a6 100644 --- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) | 53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) |
54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) | 54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) |
55 | 55 | ||
56 | #define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) | 56 | #define UART_GET_CTS(x) gpio_get_value(x->cts_pin) |
57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | 57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) |
58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | 58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) |
59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) | 59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) |
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c index 81f5b95cc361..dc0dd9b2bcef 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c | |||
@@ -864,7 +864,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info0[] = { | |||
864 | 864 | ||
865 | #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ | 865 | #if !defined(CONFIG_BF542) /* The BF542 only has 1 TWI */ |
866 | static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { | 866 | static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { |
867 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE) | 867 | #if defined(CONFIG_BFIN_TWI_LCD) || defined(CONFIG_BFIN_TWI_LCD_MODULE) |
868 | { | 868 | { |
869 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), | 869 | I2C_BOARD_INFO("pcf8574_lcd", 0x22), |
870 | }, | 870 | }, |
diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h index 18a4cd24f673..cd040fe0bc5c 100644 --- a/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h | |||
@@ -195,6 +195,7 @@ | |||
195 | #define ANOMALY_05000179 (0) | 195 | #define ANOMALY_05000179 (0) |
196 | #define ANOMALY_05000182 (0) | 196 | #define ANOMALY_05000182 (0) |
197 | #define ANOMALY_05000183 (0) | 197 | #define ANOMALY_05000183 (0) |
198 | #define ANOMALY_05000189 (0) | ||
198 | #define ANOMALY_05000198 (0) | 199 | #define ANOMALY_05000198 (0) |
199 | #define ANOMALY_05000202 (0) | 200 | #define ANOMALY_05000202 (0) |
200 | #define ANOMALY_05000215 (0) | 201 | #define ANOMALY_05000215 (0) |
@@ -226,6 +227,7 @@ | |||
226 | #define ANOMALY_05000323 (0) | 227 | #define ANOMALY_05000323 (0) |
227 | #define ANOMALY_05000362 (1) | 228 | #define ANOMALY_05000362 (1) |
228 | #define ANOMALY_05000363 (0) | 229 | #define ANOMALY_05000363 (0) |
230 | #define ANOMALY_05000364 (0) | ||
229 | #define ANOMALY_05000380 (0) | 231 | #define ANOMALY_05000380 (0) |
230 | #define ANOMALY_05000400 (0) | 232 | #define ANOMALY_05000400 (0) |
231 | #define ANOMALY_05000412 (0) | 233 | #define ANOMALY_05000412 (0) |
diff --git a/arch/blackfin/mach-bf561/include/mach/anomaly.h b/arch/blackfin/mach-bf561/include/mach/anomaly.h index 94b8e277f09d..a5312b2d267e 100644 --- a/arch/blackfin/mach-bf561/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf561/include/mach/anomaly.h | |||
@@ -288,6 +288,7 @@ | |||
288 | #define ANOMALY_05000273 (0) | 288 | #define ANOMALY_05000273 (0) |
289 | #define ANOMALY_05000311 (0) | 289 | #define ANOMALY_05000311 (0) |
290 | #define ANOMALY_05000353 (1) | 290 | #define ANOMALY_05000353 (1) |
291 | #define ANOMALY_05000364 (0) | ||
291 | #define ANOMALY_05000380 (0) | 292 | #define ANOMALY_05000380 (0) |
292 | #define ANOMALY_05000386 (1) | 293 | #define ANOMALY_05000386 (1) |
293 | #define ANOMALY_05000389 (0) | 294 | #define ANOMALY_05000389 (0) |
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h index a1b50878553f..fd5e8878b8c4 100644 --- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h +++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h | |||
@@ -53,7 +53,7 @@ | |||
53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) | 53 | #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) |
54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) | 54 | #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) |
55 | 55 | ||
56 | #define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin)) | 56 | #define UART_GET_CTS(x) gpio_get_value(x->cts_pin) |
57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) | 57 | #define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1) |
58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) | 58 | #define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0) |
59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) | 59 | #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) |
diff --git a/arch/blackfin/mach-bf561/include/mach/mem_map.h b/arch/blackfin/mach-bf561/include/mach/mem_map.h index a63e15c86d90..5b96ea549a04 100644 --- a/arch/blackfin/mach-bf561/include/mach/mem_map.h +++ b/arch/blackfin/mach-bf561/include/mach/mem_map.h | |||
@@ -37,7 +37,6 @@ | |||
37 | 37 | ||
38 | /* Memory Map for ADSP-BF561 processors */ | 38 | /* Memory Map for ADSP-BF561 processors */ |
39 | 39 | ||
40 | #ifdef CONFIG_BF561 | ||
41 | #define COREA_L1_CODE_START 0xFFA00000 | 40 | #define COREA_L1_CODE_START 0xFFA00000 |
42 | #define COREA_L1_DATA_A_START 0xFF800000 | 41 | #define COREA_L1_DATA_A_START 0xFF800000 |
43 | #define COREA_L1_DATA_B_START 0xFF900000 | 42 | #define COREA_L1_DATA_B_START 0xFF900000 |
@@ -74,6 +73,28 @@ | |||
74 | #define BFIN_DCACHESIZE (0*1024) | 73 | #define BFIN_DCACHESIZE (0*1024) |
75 | #define BFIN_DSUPBANKS 0 | 74 | #define BFIN_DSUPBANKS 0 |
76 | #endif /*CONFIG_BFIN_DCACHE*/ | 75 | #endif /*CONFIG_BFIN_DCACHE*/ |
76 | |||
77 | /* | ||
78 | * If we are in SMP mode, then the cache settings of Core B will match | ||
79 | * the settings of Core A. If we aren't, then we assume Core B is not | ||
80 | * using any cache. This allows the rest of the kernel to work with | ||
81 | * the core in either mode as we are only loading user code into it and | ||
82 | * it is the user's problem to make sure they aren't doing something | ||
83 | * stupid there. | ||
84 | * | ||
85 | * Note that we treat the L1 code region as a contiguous blob to make | ||
86 | * the rest of the kernel simpler. Easier to check one region than a | ||
87 | * bunch of small ones. Again, possible misbehavior here is the fault | ||
88 | * of the user -- don't try to use memory that doesn't exist. | ||
89 | */ | ||
90 | #ifdef CONFIG_SMP | ||
91 | # define COREB_L1_CODE_LENGTH L1_CODE_LENGTH | ||
92 | # define COREB_L1_DATA_A_LENGTH L1_DATA_A_LENGTH | ||
93 | # define COREB_L1_DATA_B_LENGTH L1_DATA_B_LENGTH | ||
94 | #else | ||
95 | # define COREB_L1_CODE_LENGTH 0x14000 | ||
96 | # define COREB_L1_DATA_A_LENGTH 0x8000 | ||
97 | # define COREB_L1_DATA_B_LENGTH 0x8000 | ||
77 | #endif | 98 | #endif |
78 | 99 | ||
79 | /* Level 2 Memory */ | 100 | /* Level 2 Memory */ |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 5a4e7c7fd92c..fb1795d5be2a 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -218,7 +218,7 @@ ENTRY(_ex_single_step) | |||
218 | /* Single stepping only a single instruction, so clear the trace | 218 | /* Single stepping only a single instruction, so clear the trace |
219 | * bit here. */ | 219 | * bit here. */ |
220 | r7 = syscfg; | 220 | r7 = syscfg; |
221 | bitclr (r7, 0); | 221 | bitclr (r7, SYSCFG_SSSTEP_P); |
222 | syscfg = R7; | 222 | syscfg = R7; |
223 | jump _ex_trap_c; | 223 | jump _ex_trap_c; |
224 | 224 | ||
@@ -251,7 +251,7 @@ ENTRY(_ex_single_step) | |||
251 | if !cc jump _bfin_return_from_exception; | 251 | if !cc jump _bfin_return_from_exception; |
252 | 252 | ||
253 | r7 = syscfg; | 253 | r7 = syscfg; |
254 | bitclr (r7, 0); | 254 | bitclr (r7, SYSCFG_SSSTEP_P); /* Turn off single step */ |
255 | syscfg = R7; | 255 | syscfg = R7; |
256 | 256 | ||
257 | /* Fall through to _bfin_return_from_exception. */ | 257 | /* Fall through to _bfin_return_from_exception. */ |
@@ -342,9 +342,11 @@ ENTRY(_ex_trap_c) | |||
342 | r6 = retx; | 342 | r6 = retx; |
343 | [p5 + PDA_RETX] = r6; | 343 | [p5 + PDA_RETX] = r6; |
344 | #endif | 344 | #endif |
345 | /* Save the state of single stepping */ | ||
345 | r6 = SYSCFG; | 346 | r6 = SYSCFG; |
346 | [p5 + PDA_SYSCFG] = r6; | 347 | [p5 + PDA_SYSCFG] = r6; |
347 | BITCLR(r6, 0); | 348 | /* Clear it while we handle the exception in IRQ5 mode */ |
349 | BITCLR(r6, SYSCFG_SSSTEP_P); | ||
348 | SYSCFG = r6; | 350 | SYSCFG = r6; |
349 | 351 | ||
350 | /* Disable all interrupts, but make sure level 5 is enabled so | 352 | /* Disable all interrupts, but make sure level 5 is enabled so |
@@ -367,7 +369,7 @@ ENDPROC(_ex_trap_c) | |||
367 | * exception. This is a unrecoverable event, so crash. | 369 | * exception. This is a unrecoverable event, so crash. |
368 | * Note: this cannot be ENTRY() as we jump here with "if cc jump" ... | 370 | * Note: this cannot be ENTRY() as we jump here with "if cc jump" ... |
369 | */ | 371 | */ |
370 | _double_fault: | 372 | ENTRY(_double_fault) |
371 | /* Turn caches & protection off, to ensure we don't get any more | 373 | /* Turn caches & protection off, to ensure we don't get any more |
372 | * double exceptions | 374 | * double exceptions |
373 | */ | 375 | */ |
@@ -872,7 +874,7 @@ ENTRY(_ret_from_exception) | |||
872 | raise 15; /* raise evt15 to do signal or reschedule */ | 874 | raise 15; /* raise evt15 to do signal or reschedule */ |
873 | 4: | 875 | 4: |
874 | r0 = syscfg; | 876 | r0 = syscfg; |
875 | bitclr(r0, 0); | 877 | bitclr(r0, SYSCFG_SSSTEP_P); /* Turn off single step */ |
876 | syscfg = r0; | 878 | syscfg = r0; |
877 | 5: | 879 | 5: |
878 | rts; | 880 | rts; |
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index 61840059dfac..349ee3f5466a 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
@@ -211,6 +211,8 @@ int smp_call_function(void (*func)(void *info), void *info, int wait) | |||
211 | return 0; | 211 | return 0; |
212 | 212 | ||
213 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); | 213 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); |
214 | if (!msg) | ||
215 | return -ENOMEM; | ||
214 | INIT_LIST_HEAD(&msg->list); | 216 | INIT_LIST_HEAD(&msg->list); |
215 | msg->call_struct.func = func; | 217 | msg->call_struct.func = func; |
216 | msg->call_struct.info = info; | 218 | msg->call_struct.info = info; |
@@ -252,6 +254,8 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, | |||
252 | cpu_set(cpu, callmap); | 254 | cpu_set(cpu, callmap); |
253 | 255 | ||
254 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); | 256 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); |
257 | if (!msg) | ||
258 | return -ENOMEM; | ||
255 | INIT_LIST_HEAD(&msg->list); | 259 | INIT_LIST_HEAD(&msg->list); |
256 | msg->call_struct.func = func; | 260 | msg->call_struct.func = func; |
257 | msg->call_struct.info = info; | 261 | msg->call_struct.info = info; |
@@ -287,6 +291,8 @@ void smp_send_reschedule(int cpu) | |||
287 | return; | 291 | return; |
288 | 292 | ||
289 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); | 293 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); |
294 | if (!msg) | ||
295 | return; | ||
290 | memset(msg, 0, sizeof(msg)); | 296 | memset(msg, 0, sizeof(msg)); |
291 | INIT_LIST_HEAD(&msg->list); | 297 | INIT_LIST_HEAD(&msg->list); |
292 | msg->type = BFIN_IPI_RESCHEDULE; | 298 | msg->type = BFIN_IPI_RESCHEDULE; |
@@ -314,6 +320,8 @@ void smp_send_stop(void) | |||
314 | return; | 320 | return; |
315 | 321 | ||
316 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); | 322 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); |
323 | if (!msg) | ||
324 | return; | ||
317 | memset(msg, 0, sizeof(msg)); | 325 | memset(msg, 0, sizeof(msg)); |
318 | INIT_LIST_HEAD(&msg->list); | 326 | INIT_LIST_HEAD(&msg->list); |
319 | msg->type = BFIN_IPI_CPU_STOP; | 327 | msg->type = BFIN_IPI_CPU_STOP; |
@@ -450,7 +458,7 @@ void __init smp_cpus_done(unsigned int max_cpus) | |||
450 | unsigned int cpu; | 458 | unsigned int cpu; |
451 | 459 | ||
452 | for_each_online_cpu(cpu) | 460 | for_each_online_cpu(cpu) |
453 | bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; | 461 | bogosum += loops_per_jiffy; |
454 | 462 | ||
455 | printk(KERN_INFO "SMP: Total of %d processors activated " | 463 | printk(KERN_INFO "SMP: Total of %d processors activated " |
456 | "(%lu.%02lu BogoMIPS).\n", | 464 | "(%lu.%02lu BogoMIPS).\n", |
diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h index bc5b2935ca53..c3aade36c330 100644 --- a/arch/cris/include/asm/thread_info.h +++ b/arch/cris/include/asm/thread_info.h | |||
@@ -50,8 +50,6 @@ struct thread_info { | |||
50 | 50 | ||
51 | /* | 51 | /* |
52 | * macros/functions for gaining access to the thread information structure | 52 | * macros/functions for gaining access to the thread information structure |
53 | * | ||
54 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
55 | */ | 53 | */ |
56 | #ifndef __ASSEMBLY__ | 54 | #ifndef __ASSEMBLY__ |
57 | #define INIT_THREAD_INFO(tsk) \ | 55 | #define INIT_THREAD_INFO(tsk) \ |
@@ -60,7 +58,7 @@ struct thread_info { | |||
60 | .exec_domain = &default_exec_domain, \ | 58 | .exec_domain = &default_exec_domain, \ |
61 | .flags = 0, \ | 59 | .flags = 0, \ |
62 | .cpu = 0, \ | 60 | .cpu = 0, \ |
63 | .preempt_count = 1, \ | 61 | .preempt_count = INIT_PREEMPT_COUNT, \ |
64 | .addr_limit = KERNEL_DS, \ | 62 | .addr_limit = KERNEL_DS, \ |
65 | .restart_block = { \ | 63 | .restart_block = { \ |
66 | .fn = do_no_restart_syscall, \ | 64 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c index a79fbd87021b..2ad962c7e88e 100644 --- a/arch/cris/kernel/sys_cris.c +++ b/arch/cris/kernel/sys_cris.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/sem.h> | 18 | #include <linux/sem.h> |
20 | #include <linux/msg.h> | 19 | #include <linux/msg.h> |
21 | #include <linux/shm.h> | 20 | #include <linux/shm.h> |
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h index e8a5ed7be021..e608e056bb53 100644 --- a/arch/frv/include/asm/thread_info.h +++ b/arch/frv/include/asm/thread_info.h | |||
@@ -56,8 +56,6 @@ struct thread_info { | |||
56 | 56 | ||
57 | /* | 57 | /* |
58 | * macros/functions for gaining access to the thread information structure | 58 | * macros/functions for gaining access to the thread information structure |
59 | * | ||
60 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
61 | */ | 59 | */ |
62 | #ifndef __ASSEMBLY__ | 60 | #ifndef __ASSEMBLY__ |
63 | 61 | ||
@@ -67,7 +65,7 @@ struct thread_info { | |||
67 | .exec_domain = &default_exec_domain, \ | 65 | .exec_domain = &default_exec_domain, \ |
68 | .flags = 0, \ | 66 | .flags = 0, \ |
69 | .cpu = 0, \ | 67 | .cpu = 0, \ |
70 | .preempt_count = 1, \ | 68 | .preempt_count = INIT_PREEMPT_COUNT, \ |
71 | .addr_limit = KERNEL_DS, \ | 69 | .addr_limit = KERNEL_DS, \ |
72 | .restart_block = { \ | 70 | .restart_block = { \ |
73 | .fn = do_no_restart_syscall, \ | 71 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h index 700014d2155f..8bbc8b0ee45d 100644 --- a/arch/h8300/include/asm/thread_info.h +++ b/arch/h8300/include/asm/thread_info.h | |||
@@ -36,7 +36,7 @@ struct thread_info { | |||
36 | .exec_domain = &default_exec_domain, \ | 36 | .exec_domain = &default_exec_domain, \ |
37 | .flags = 0, \ | 37 | .flags = 0, \ |
38 | .cpu = 0, \ | 38 | .cpu = 0, \ |
39 | .preempt_count = 1, \ | 39 | .preempt_count = INIT_PREEMPT_COUNT, \ |
40 | .restart_block = { \ | 40 | .restart_block = { \ |
41 | .fn = do_no_restart_syscall, \ | 41 | .fn = do_no_restart_syscall, \ |
42 | }, \ | 42 | }, \ |
diff --git a/arch/ia64/include/asm/fpu.h b/arch/ia64/include/asm/fpu.h index 0c26157cffa5..b6395ad1500a 100644 --- a/arch/ia64/include/asm/fpu.h +++ b/arch/ia64/include/asm/fpu.h | |||
@@ -6,6 +6,8 @@ | |||
6 | * David Mosberger-Tang <davidm@hpl.hp.com> | 6 | * David Mosberger-Tang <davidm@hpl.hp.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/types.h> | ||
10 | |||
9 | /* floating point status register: */ | 11 | /* floating point status register: */ |
10 | #define FPSR_TRAP_VD (1 << 0) /* invalid op trap disabled */ | 12 | #define FPSR_TRAP_VD (1 << 0) /* invalid op trap disabled */ |
11 | #define FPSR_TRAP_DD (1 << 1) /* denormal trap disabled */ | 13 | #define FPSR_TRAP_DD (1 << 1) /* denormal trap disabled */ |
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h index ae6922626bf4..8ce2e388e37c 100644 --- a/arch/ia64/include/asm/thread_info.h +++ b/arch/ia64/include/asm/thread_info.h | |||
@@ -48,7 +48,7 @@ struct thread_info { | |||
48 | .flags = 0, \ | 48 | .flags = 0, \ |
49 | .cpu = 0, \ | 49 | .cpu = 0, \ |
50 | .addr_limit = KERNEL_DS, \ | 50 | .addr_limit = KERNEL_DS, \ |
51 | .preempt_count = 0, \ | 51 | .preempt_count = INIT_PREEMPT_COUNT, \ |
52 | .restart_block = { \ | 52 | .restart_block = { \ |
53 | .fn = do_no_restart_syscall, \ | 53 | .fn = do_no_restart_syscall, \ |
54 | }, \ | 54 | }, \ |
diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h index e425227a418e..88afb54501e4 100644 --- a/arch/ia64/include/asm/xen/hypervisor.h +++ b/arch/ia64/include/asm/xen/hypervisor.h | |||
@@ -33,6 +33,7 @@ | |||
33 | #ifndef _ASM_IA64_XEN_HYPERVISOR_H | 33 | #ifndef _ASM_IA64_XEN_HYPERVISOR_H |
34 | #define _ASM_IA64_XEN_HYPERVISOR_H | 34 | #define _ASM_IA64_XEN_HYPERVISOR_H |
35 | 35 | ||
36 | #include <linux/err.h> | ||
36 | #include <xen/interface/xen.h> | 37 | #include <xen/interface/xen.h> |
37 | #include <xen/interface/version.h> /* to compile feature.c */ | 38 | #include <xen/interface/version.h> /* to compile feature.c */ |
38 | #include <xen/features.h> /* to comiple xen-netfront.c */ | 39 | #include <xen/features.h> /* to comiple xen-netfront.c */ |
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c index 086a2aeb0404..39a3cd0a4173 100644 --- a/arch/ia64/kernel/dma-mapping.c +++ b/arch/ia64/kernel/dma-mapping.c | |||
@@ -6,6 +6,14 @@ int iommu_detected __read_mostly; | |||
6 | struct dma_map_ops *dma_ops; | 6 | struct dma_map_ops *dma_ops; |
7 | EXPORT_SYMBOL(dma_ops); | 7 | EXPORT_SYMBOL(dma_ops); |
8 | 8 | ||
9 | #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) | ||
10 | |||
11 | static int __init dma_init(void) | ||
12 | { | ||
13 | dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); | ||
14 | } | ||
15 | fs_initcall(dma_init); | ||
16 | |||
9 | struct dma_map_ops *dma_get_ops(struct device *dev) | 17 | struct dma_map_ops *dma_get_ops(struct device *dev) |
10 | { | 18 | { |
11 | return dma_ops; | 19 | return dma_ops; |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 92c9689b7d97..9daa87fdb018 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/user.h> | 18 | #include <linux/user.h> |
20 | #include <linux/security.h> | 19 | #include <linux/security.h> |
21 | #include <linux/audit.h> | 20 | #include <linux/audit.h> |
diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h index 8589d462df27..07bb5bd00e2a 100644 --- a/arch/m32r/include/asm/thread_info.h +++ b/arch/m32r/include/asm/thread_info.h | |||
@@ -57,8 +57,6 @@ struct thread_info { | |||
57 | 57 | ||
58 | /* | 58 | /* |
59 | * macros/functions for gaining access to the thread information structure | 59 | * macros/functions for gaining access to the thread information structure |
60 | * | ||
61 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
62 | */ | 60 | */ |
63 | #ifndef __ASSEMBLY__ | 61 | #ifndef __ASSEMBLY__ |
64 | 62 | ||
@@ -68,7 +66,7 @@ struct thread_info { | |||
68 | .exec_domain = &default_exec_domain, \ | 66 | .exec_domain = &default_exec_domain, \ |
69 | .flags = 0, \ | 67 | .flags = 0, \ |
70 | .cpu = 0, \ | 68 | .cpu = 0, \ |
71 | .preempt_count = 1, \ | 69 | .preempt_count = INIT_PREEMPT_COUNT, \ |
72 | .addr_limit = KERNEL_DS, \ | 70 | .addr_limit = KERNEL_DS, \ |
73 | .restart_block = { \ | 71 | .restart_block = { \ |
74 | .fn = do_no_restart_syscall, \ | 72 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index bf0abe9e1f73..98b8feb12ed8 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
24 | #include <linux/ptrace.h> | 23 | #include <linux/ptrace.h> |
25 | #include <linux/user.h> | 24 | #include <linux/user.h> |
diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h index af0fda46e94b..6ea5c33b3c56 100644 --- a/arch/m68k/include/asm/thread_info_mm.h +++ b/arch/m68k/include/asm/thread_info_mm.h | |||
@@ -19,6 +19,7 @@ struct thread_info { | |||
19 | { \ | 19 | { \ |
20 | .task = &tsk, \ | 20 | .task = &tsk, \ |
21 | .exec_domain = &default_exec_domain, \ | 21 | .exec_domain = &default_exec_domain, \ |
22 | .preempt_count = INIT_PREEMPT_COUNT, \ | ||
22 | .restart_block = { \ | 23 | .restart_block = { \ |
23 | .fn = do_no_restart_syscall, \ | 24 | .fn = do_no_restart_syscall, \ |
24 | }, \ | 25 | }, \ |
diff --git a/arch/m68k/include/asm/thread_info_no.h b/arch/m68k/include/asm/thread_info_no.h index 82529f424ea3..c2bde5e24b0b 100644 --- a/arch/m68k/include/asm/thread_info_no.h +++ b/arch/m68k/include/asm/thread_info_no.h | |||
@@ -49,6 +49,7 @@ struct thread_info { | |||
49 | .exec_domain = &default_exec_domain, \ | 49 | .exec_domain = &default_exec_domain, \ |
50 | .flags = 0, \ | 50 | .flags = 0, \ |
51 | .cpu = 0, \ | 51 | .cpu = 0, \ |
52 | .preempt_count = INIT_PREEMPT_COUNT, \ | ||
52 | .restart_block = { \ | 53 | .restart_block = { \ |
53 | .fn = do_no_restart_syscall, \ | 54 | .fn = do_no_restart_syscall, \ |
54 | }, \ | 55 | }, \ |
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h index 7fac44498445..6e92885d381a 100644 --- a/arch/microblaze/include/asm/thread_info.h +++ b/arch/microblaze/include/asm/thread_info.h | |||
@@ -75,8 +75,6 @@ struct thread_info { | |||
75 | 75 | ||
76 | /* | 76 | /* |
77 | * macros/functions for gaining access to the thread information structure | 77 | * macros/functions for gaining access to the thread information structure |
78 | * | ||
79 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
80 | */ | 78 | */ |
81 | #define INIT_THREAD_INFO(tsk) \ | 79 | #define INIT_THREAD_INFO(tsk) \ |
82 | { \ | 80 | { \ |
@@ -84,7 +82,7 @@ struct thread_info { | |||
84 | .exec_domain = &default_exec_domain, \ | 82 | .exec_domain = &default_exec_domain, \ |
85 | .flags = 0, \ | 83 | .flags = 0, \ |
86 | .cpu = 0, \ | 84 | .cpu = 0, \ |
87 | .preempt_count = 1, \ | 85 | .preempt_count = INIT_PREEMPT_COUNT, \ |
88 | .addr_limit = KERNEL_DS, \ | 86 | .addr_limit = KERNEL_DS, \ |
89 | .restart_block = { \ | 87 | .restart_block = { \ |
90 | .fn = do_no_restart_syscall, \ | 88 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c index b86aa623e36d..53ff39af6a5c 100644 --- a/arch/microblaze/kernel/ptrace.c +++ b/arch/microblaze/kernel/ptrace.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
32 | #include <linux/signal.h> | 31 | #include <linux/signal.h> |
33 | 32 | ||
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c index 493819c25fba..1c80e4fc40ce 100644 --- a/arch/microblaze/kernel/signal.c +++ b/arch/microblaze/kernel/signal.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
26 | #include <linux/signal.h> | 25 | #include <linux/signal.h> |
27 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index 8c9ebac5da10..e000bce09b2b 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/syscalls.h> | 18 | #include <linux/syscalls.h> |
20 | #include <linux/sem.h> | 19 | #include <linux/sem.h> |
21 | #include <linux/msg.h> | 20 | #include <linux/msg.h> |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 143a48136a4b..f9df720d2e40 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -39,8 +39,6 @@ struct thread_info { | |||
39 | 39 | ||
40 | /* | 40 | /* |
41 | * macros/functions for gaining access to the thread information structure | 41 | * macros/functions for gaining access to the thread information structure |
42 | * | ||
43 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
44 | */ | 42 | */ |
45 | #define INIT_THREAD_INFO(tsk) \ | 43 | #define INIT_THREAD_INFO(tsk) \ |
46 | { \ | 44 | { \ |
@@ -48,7 +46,7 @@ struct thread_info { | |||
48 | .exec_domain = &default_exec_domain, \ | 46 | .exec_domain = &default_exec_domain, \ |
49 | .flags = _TIF_FIXADE, \ | 47 | .flags = _TIF_FIXADE, \ |
50 | .cpu = 0, \ | 48 | .cpu = 0, \ |
51 | .preempt_count = 1, \ | 49 | .preempt_count = INIT_PREEMPT_COUNT, \ |
52 | .addr_limit = KERNEL_DS, \ | 50 | .addr_limit = KERNEL_DS, \ |
53 | .restart_block = { \ | 51 | .restart_block = { \ |
54 | .fn = do_no_restart_syscall, \ | 52 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index c4f9ac17474a..32644b4a0714 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/ptrace.h> | 23 | #include <linux/ptrace.h> |
24 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/user.h> | 25 | #include <linux/user.h> |
27 | #include <linux/security.h> | 26 | #include <linux/security.h> |
28 | 27 | ||
diff --git a/arch/mips/mm/hugetlbpage.c b/arch/mips/mm/hugetlbpage.c index 471c09aa1614..8c2834f5919d 100644 --- a/arch/mips/mm/hugetlbpage.c +++ b/arch/mips/mm/hugetlbpage.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/hugetlb.h> | 17 | #include <linux/hugetlb.h> |
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
21 | #include <linux/err.h> | 20 | #include <linux/err.h> |
22 | #include <linux/sysctl.h> | 21 | #include <linux/sysctl.h> |
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h index 78a3881f3c12..58d64f8b2cc3 100644 --- a/arch/mn10300/include/asm/thread_info.h +++ b/arch/mn10300/include/asm/thread_info.h | |||
@@ -65,8 +65,6 @@ struct thread_info { | |||
65 | 65 | ||
66 | /* | 66 | /* |
67 | * macros/functions for gaining access to the thread information structure | 67 | * macros/functions for gaining access to the thread information structure |
68 | * | ||
69 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
70 | */ | 68 | */ |
71 | #ifndef __ASSEMBLY__ | 69 | #ifndef __ASSEMBLY__ |
72 | 70 | ||
@@ -76,7 +74,7 @@ struct thread_info { | |||
76 | .exec_domain = &default_exec_domain, \ | 74 | .exec_domain = &default_exec_domain, \ |
77 | .flags = 0, \ | 75 | .flags = 0, \ |
78 | .cpu = 0, \ | 76 | .cpu = 0, \ |
79 | .preempt_count = 1, \ | 77 | .preempt_count = INIT_PREEMPT_COUNT, \ |
80 | .addr_limit = KERNEL_DS, \ | 78 | .addr_limit = KERNEL_DS, \ |
81 | .restart_block = { \ | 79 | .restart_block = { \ |
82 | .fn = do_no_restart_syscall, \ | 80 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/mn10300/kernel/ptrace.c b/arch/mn10300/kernel/ptrace.c index e143339ad28e..cf847dabc1bd 100644 --- a/arch/mn10300/kernel/ptrace.c +++ b/arch/mn10300/kernel/ptrace.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
18 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
19 | #include <linux/user.h> | 18 | #include <linux/user.h> |
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index 9f7572a0f578..feb2f2e810db 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
17 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
18 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c index bca5a84dc72c..3e52a1054327 100644 --- a/arch/mn10300/kernel/sys_mn10300.c +++ b/arch/mn10300/kernel/sys_mn10300.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/syscalls.h> | 13 | #include <linux/syscalls.h> |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/sem.h> | 16 | #include <linux/sem.h> |
18 | #include <linux/msg.h> | 17 | #include <linux/msg.h> |
19 | #include <linux/shm.h> | 18 | #include <linux/shm.h> |
@@ -21,7 +20,6 @@ | |||
21 | #include <linux/mman.h> | 20 | #include <linux/mman.h> |
22 | #include <linux/file.h> | 21 | #include <linux/file.h> |
23 | #include <linux/utsname.h> | 22 | #include <linux/utsname.h> |
24 | #include <linux/syscalls.h> | ||
25 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
26 | 24 | ||
27 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c index 0dfdc5001124..91365adba4f5 100644 --- a/arch/mn10300/kernel/traps.c +++ b/arch/mn10300/kernel/traps.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/timer.h> | 17 | #include <linux/timer.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
22 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
23 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S index c96ba3da95ac..f4aa07934654 100644 --- a/arch/mn10300/kernel/vmlinux.lds.S +++ b/arch/mn10300/kernel/vmlinux.lds.S | |||
@@ -107,7 +107,7 @@ SECTIONS | |||
107 | __init_end = .; | 107 | __init_end = .; |
108 | /* freed after init ends here */ | 108 | /* freed after init ends here */ |
109 | 109 | ||
110 | BSS(4) | 110 | BSS_SECTION(0, PAGE_SIZE, 4) |
111 | 111 | ||
112 | _end = . ; | 112 | _end = . ; |
113 | 113 | ||
diff --git a/arch/mn10300/mm/fault.c b/arch/mn10300/mm/fault.c index a62e1e138bc1..53bb17d0f068 100644 --- a/arch/mn10300/mm/fault.c +++ b/arch/mn10300/mm/fault.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/mman.h> | 20 | #include <linux/mman.h> |
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <linux/smp.h> | 22 | #include <linux/smp.h> |
23 | #include <linux/smp_lock.h> | ||
24 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
25 | #include <linux/init.h> | 24 | #include <linux/init.h> |
26 | #include <linux/vt_kern.h> /* For unblank_screen() */ | 25 | #include <linux/vt_kern.h> /* For unblank_screen() */ |
diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c index 94c4a4358065..30016251f658 100644 --- a/arch/mn10300/mm/misalignment.c +++ b/arch/mn10300/mm/misalignment.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/timer.h> | 17 | #include <linux/timer.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/init.h> | 20 | #include <linux/init.h> |
22 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
23 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index 0407959da489..4ce0edfbe969 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h | |||
@@ -23,7 +23,7 @@ struct thread_info { | |||
23 | .flags = 0, \ | 23 | .flags = 0, \ |
24 | .cpu = 0, \ | 24 | .cpu = 0, \ |
25 | .addr_limit = KERNEL_DS, \ | 25 | .addr_limit = KERNEL_DS, \ |
26 | .preempt_count = 1, \ | 26 | .preempt_count = INIT_PREEMPT_COUNT, \ |
27 | .restart_block = { \ | 27 | .restart_block = { \ |
28 | .fn = do_no_restart_syscall \ | 28 | .fn = do_no_restart_syscall \ |
29 | } \ | 29 | } \ |
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h index 9aba5a38a7c4..c8b329255678 100644 --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h | |||
@@ -46,15 +46,13 @@ struct thread_info { | |||
46 | 46 | ||
47 | /* | 47 | /* |
48 | * macros/functions for gaining access to the thread information structure | 48 | * macros/functions for gaining access to the thread information structure |
49 | * | ||
50 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
51 | */ | 49 | */ |
52 | #define INIT_THREAD_INFO(tsk) \ | 50 | #define INIT_THREAD_INFO(tsk) \ |
53 | { \ | 51 | { \ |
54 | .task = &tsk, \ | 52 | .task = &tsk, \ |
55 | .exec_domain = &default_exec_domain, \ | 53 | .exec_domain = &default_exec_domain, \ |
56 | .cpu = 0, \ | 54 | .cpu = 0, \ |
57 | .preempt_count = 1, \ | 55 | .preempt_count = INIT_PREEMPT_COUNT, \ |
58 | .restart_block = { \ | 56 | .restart_block = { \ |
59 | .fn = do_no_restart_syscall, \ | 57 | .fn = do_no_restart_syscall, \ |
60 | }, \ | 58 | }, \ |
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c index 5d755ef7ac8f..5a9f5cbd40a4 100644 --- a/arch/powerpc/kernel/power7-pmu.c +++ b/arch/powerpc/kernel/power7-pmu.c | |||
@@ -358,6 +358,7 @@ static struct power_pmu power7_pmu = { | |||
358 | .get_constraint = power7_get_constraint, | 358 | .get_constraint = power7_get_constraint, |
359 | .get_alternatives = power7_get_alternatives, | 359 | .get_alternatives = power7_get_alternatives, |
360 | .disable_pmc = power7_disable_pmc, | 360 | .disable_pmc = power7_disable_pmc, |
361 | .flags = PPMU_ALT_SIPR, | ||
361 | .n_generic = ARRAY_SIZE(power7_generic_events), | 362 | .n_generic = ARRAY_SIZE(power7_generic_events), |
362 | .generic_events = power7_generic_events, | 363 | .generic_events = power7_generic_events, |
363 | .cache_events = &power7_cache_events, | 364 | .cache_events = &power7_cache_events, |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 9fa2c7dcd05a..ef149880c145 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -736,15 +736,16 @@ void user_disable_single_step(struct task_struct *task) | |||
736 | { | 736 | { |
737 | struct pt_regs *regs = task->thread.regs; | 737 | struct pt_regs *regs = task->thread.regs; |
738 | 738 | ||
739 | |||
740 | #if defined(CONFIG_BOOKE) | ||
741 | /* If DAC then do not single step, skip */ | ||
742 | if (task->thread.dabr) | ||
743 | return; | ||
744 | #endif | ||
745 | |||
746 | if (regs != NULL) { | 739 | if (regs != NULL) { |
747 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | 740 | #if defined(CONFIG_BOOKE) |
741 | /* If DAC don't clear DBCRO_IDM or MSR_DE */ | ||
742 | if (task->thread.dabr) | ||
743 | task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT); | ||
744 | else { | ||
745 | task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM); | ||
746 | regs->msr &= ~MSR_DE; | ||
747 | } | ||
748 | #elif defined(CONFIG_40x) | ||
748 | task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM); | 749 | task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM); |
749 | regs->msr &= ~MSR_DE; | 750 | regs->msr &= ~MSR_DE; |
750 | #else | 751 | #else |
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c index 297632cba047..8a6daf4129f6 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
26 | #include <linux/ptrace.h> | 25 | #include <linux/ptrace.h> |
27 | #include <linux/regset.h> | 26 | #include <linux/regset.h> |
diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index ef36cbbc5882..ea4d64644d02 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S | |||
@@ -80,10 +80,10 @@ _GLOBAL(load_up_altivec) | |||
80 | mtvscr vr0 | 80 | mtvscr vr0 |
81 | REST_32VRS(0,r4,r5) | 81 | REST_32VRS(0,r4,r5) |
82 | #ifndef CONFIG_SMP | 82 | #ifndef CONFIG_SMP |
83 | /* Update last_task_used_math to 'current' */ | 83 | /* Update last_task_used_altivec to 'current' */ |
84 | subi r4,r5,THREAD /* Back to 'current' */ | 84 | subi r4,r5,THREAD /* Back to 'current' */ |
85 | fromreal(r4) | 85 | fromreal(r4) |
86 | PPC_STL r4,ADDROFF(last_task_used_math)(r3) | 86 | PPC_STL r4,ADDROFF(last_task_used_altivec)(r3) |
87 | #endif /* CONFIG_SMP */ | 87 | #endif /* CONFIG_SMP */ |
88 | /* restore registers and return */ | 88 | /* restore registers and return */ |
89 | blr | 89 | blr |
@@ -172,7 +172,7 @@ _GLOBAL(load_up_vsx) | |||
172 | oris r12,r12,MSR_VSX@h | 172 | oris r12,r12,MSR_VSX@h |
173 | std r12,_MSR(r1) | 173 | std r12,_MSR(r1) |
174 | #ifndef CONFIG_SMP | 174 | #ifndef CONFIG_SMP |
175 | /* Update last_task_used_math to 'current' */ | 175 | /* Update last_task_used_vsx to 'current' */ |
176 | ld r4,PACACURRENT(r13) | 176 | ld r4,PACACURRENT(r13) |
177 | std r4,0(r3) | 177 | std r4,0(r3) |
178 | #endif /* CONFIG_SMP */ | 178 | #endif /* CONFIG_SMP */ |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index e577839f3073..2ae5d72f47ed 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -95,6 +95,11 @@ config S390 | |||
95 | select HAVE_ARCH_TRACEHOOK | 95 | select HAVE_ARCH_TRACEHOOK |
96 | select INIT_ALL_POSSIBLE | 96 | select INIT_ALL_POSSIBLE |
97 | select HAVE_PERF_COUNTERS | 97 | select HAVE_PERF_COUNTERS |
98 | select GENERIC_ATOMIC64 if !64BIT | ||
99 | |||
100 | config SCHED_OMIT_FRAME_POINTER | ||
101 | bool | ||
102 | default y | ||
98 | 103 | ||
99 | source "init/Kconfig" | 104 | source "init/Kconfig" |
100 | 105 | ||
@@ -116,6 +121,9 @@ config 32BIT | |||
116 | bool | 121 | bool |
117 | default y if !64BIT | 122 | default y if !64BIT |
118 | 123 | ||
124 | config KTIME_SCALAR | ||
125 | def_bool 32BIT | ||
126 | |||
119 | config SMP | 127 | config SMP |
120 | bool "Symmetric multi-processing support" | 128 | bool "Symmetric multi-processing support" |
121 | ---help--- | 129 | ---help--- |
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index fca9dffcc669..c7d0abfb0f00 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h | |||
@@ -268,7 +268,12 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, | |||
268 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 268 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
269 | 269 | ||
270 | #undef __CSG_LOOP | 270 | #undef __CSG_LOOP |
271 | #endif | 271 | |
272 | #else /* __s390x__ */ | ||
273 | |||
274 | #include <asm-generic/atomic64.h> | ||
275 | |||
276 | #endif /* __s390x__ */ | ||
272 | 277 | ||
273 | #define smp_mb__before_atomic_dec() smp_mb() | 278 | #define smp_mb__before_atomic_dec() smp_mb() |
274 | #define smp_mb__after_atomic_dec() smp_mb() | 279 | #define smp_mb__after_atomic_dec() smp_mb() |
diff --git a/arch/s390/include/asm/perf_counter.h b/arch/s390/include/asm/perf_counter.h index a7205a3828cb..7015188c2cc2 100644 --- a/arch/s390/include/asm/perf_counter.h +++ b/arch/s390/include/asm/perf_counter.h | |||
@@ -6,3 +6,5 @@ | |||
6 | 6 | ||
7 | static inline void set_perf_counter_pending(void) {} | 7 | static inline void set_perf_counter_pending(void) {} |
8 | static inline void clear_perf_counter_pending(void) {} | 8 | static inline void clear_perf_counter_pending(void) {} |
9 | |||
10 | #define PERF_COUNTER_INDEX_OFFSET 0 | ||
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 925bcc649035..ba1cab9fc1f9 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -61,7 +61,7 @@ struct thread_info { | |||
61 | .exec_domain = &default_exec_domain, \ | 61 | .exec_domain = &default_exec_domain, \ |
62 | .flags = 0, \ | 62 | .flags = 0, \ |
63 | .cpu = 0, \ | 63 | .cpu = 0, \ |
64 | .preempt_count = 1, \ | 64 | .preempt_count = INIT_PREEMPT_COUNT, \ |
65 | .restart_block = { \ | 65 | .restart_block = { \ |
66 | .fn = do_no_restart_syscall, \ | 66 | .fn = do_no_restart_syscall, \ |
67 | }, \ | 67 | }, \ |
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index d2f270c995d9..db943a7ec513 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/timer.h> | 15 | #include <linux/timer.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/init.h> | 18 | #include <linux/init.h> |
20 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
21 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index b8bf4b140065..371a2d88f4ac 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -70,6 +70,7 @@ struct shutdown_action { | |||
70 | char *name; | 70 | char *name; |
71 | void (*fn) (struct shutdown_trigger *trigger); | 71 | void (*fn) (struct shutdown_trigger *trigger); |
72 | int (*init) (void); | 72 | int (*init) (void); |
73 | int init_rc; | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | static char *ipl_type_str(enum ipl_type type) | 76 | static char *ipl_type_str(enum ipl_type type) |
@@ -1486,11 +1487,13 @@ static int set_trigger(const char *buf, struct shutdown_trigger *trigger, | |||
1486 | int i; | 1487 | int i; |
1487 | 1488 | ||
1488 | for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { | 1489 | for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { |
1489 | if (!shutdown_actions_list[i]) | ||
1490 | continue; | ||
1491 | if (sysfs_streq(buf, shutdown_actions_list[i]->name)) { | 1490 | if (sysfs_streq(buf, shutdown_actions_list[i]->name)) { |
1492 | trigger->action = shutdown_actions_list[i]; | 1491 | if (shutdown_actions_list[i]->init_rc) { |
1493 | return len; | 1492 | return shutdown_actions_list[i]->init_rc; |
1493 | } else { | ||
1494 | trigger->action = shutdown_actions_list[i]; | ||
1495 | return len; | ||
1496 | } | ||
1494 | } | 1497 | } |
1495 | } | 1498 | } |
1496 | return -EINVAL; | 1499 | return -EINVAL; |
@@ -1640,8 +1643,8 @@ static void __init shutdown_actions_init(void) | |||
1640 | for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { | 1643 | for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) { |
1641 | if (!shutdown_actions_list[i]->init) | 1644 | if (!shutdown_actions_list[i]->init) |
1642 | continue; | 1645 | continue; |
1643 | if (shutdown_actions_list[i]->init()) | 1646 | shutdown_actions_list[i]->init_rc = |
1644 | shutdown_actions_list[i] = NULL; | 1647 | shutdown_actions_list[i]->init(); |
1645 | } | 1648 | } |
1646 | } | 1649 | } |
1647 | 1650 | ||
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 490b39934d65..43acd73105b7 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/smp.h> | 28 | #include <linux/smp.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
31 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
32 | #include <linux/user.h> | 31 | #include <linux/user.h> |
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index ab6735df2d21..97975ec7a274 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y += delay.o string.o uaccess_std.o uaccess_pt.o | 5 | lib-y += delay.o string.o uaccess_std.o uaccess_pt.o |
6 | obj-$(CONFIG_32BIT) += div64.o qrnnd.o | 6 | obj-$(CONFIG_32BIT) += div64.o qrnnd.o ucmpdi2.o |
7 | lib-$(CONFIG_64BIT) += uaccess_mvcos.o | 7 | lib-$(CONFIG_64BIT) += uaccess_mvcos.o |
8 | lib-$(CONFIG_SMP) += spinlock.o | 8 | lib-$(CONFIG_SMP) += spinlock.o |
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 3f5f680726ed..97c1eca83cc2 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
@@ -36,9 +36,11 @@ static void __udelay_disabled(unsigned long usecs) | |||
36 | cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; | 36 | cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; |
37 | __ctl_load(cr0 , 0, 0); | 37 | __ctl_load(cr0 , 0, 0); |
38 | mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; | 38 | mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT; |
39 | lockdep_off(); | ||
39 | trace_hardirqs_on(); | 40 | trace_hardirqs_on(); |
40 | __load_psw_mask(mask); | 41 | __load_psw_mask(mask); |
41 | local_irq_disable(); | 42 | local_irq_disable(); |
43 | lockdep_on(); | ||
42 | __ctl_load(cr0_saved, 0, 0); | 44 | __ctl_load(cr0_saved, 0, 0); |
43 | local_tick_enable(clock_saved); | 45 | local_tick_enable(clock_saved); |
44 | set_clock_comparator(S390_lowcore.clock_comparator); | 46 | set_clock_comparator(S390_lowcore.clock_comparator); |
diff --git a/arch/s390/lib/ucmpdi2.c b/arch/s390/lib/ucmpdi2.c new file mode 100644 index 000000000000..3e05ff532582 --- /dev/null +++ b/arch/s390/lib/ucmpdi2.c | |||
@@ -0,0 +1,26 @@ | |||
1 | #include <linux/module.h> | ||
2 | |||
3 | union ull_union { | ||
4 | unsigned long long ull; | ||
5 | struct { | ||
6 | unsigned int high; | ||
7 | unsigned int low; | ||
8 | } ui; | ||
9 | }; | ||
10 | |||
11 | int __ucmpdi2(unsigned long long a, unsigned long long b) | ||
12 | { | ||
13 | union ull_union au = {.ull = a}; | ||
14 | union ull_union bu = {.ull = b}; | ||
15 | |||
16 | if (au.ui.high < bu.ui.high) | ||
17 | return 0; | ||
18 | else if (au.ui.high > bu.ui.high) | ||
19 | return 2; | ||
20 | if (au.ui.low < bu.ui.low) | ||
21 | return 0; | ||
22 | else if (au.ui.low > bu.ui.low) | ||
23 | return 2; | ||
24 | return 1; | ||
25 | } | ||
26 | EXPORT_SYMBOL(__ucmpdi2); | ||
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 74eb26bf1970..e5e119fe03b2 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/compat.h> | 22 | #include <linux/compat.h> |
23 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
24 | #include <linux/kdebug.h> | 24 | #include <linux/kdebug.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
27 | #include <linux/console.h> | 26 | #include <linux/console.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h index f09ac4806294..d570ac2e5cb9 100644 --- a/arch/sh/include/asm/thread_info.h +++ b/arch/sh/include/asm/thread_info.h | |||
@@ -51,7 +51,7 @@ struct thread_info { | |||
51 | .exec_domain = &default_exec_domain, \ | 51 | .exec_domain = &default_exec_domain, \ |
52 | .flags = 0, \ | 52 | .flags = 0, \ |
53 | .cpu = 0, \ | 53 | .cpu = 0, \ |
54 | .preempt_count = 1, \ | 54 | .preempt_count = INIT_PREEMPT_COUNT, \ |
55 | .addr_limit = KERNEL_DS, \ | 55 | .addr_limit = KERNEL_DS, \ |
56 | .restart_block = { \ | 56 | .restart_block = { \ |
57 | .fn = do_no_restart_syscall, \ | 57 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/sh/mm/tlb-sh3.c b/arch/sh/mm/tlb-sh3.c index 7fbfd5a11ffa..17cb7c3adf22 100644 --- a/arch/sh/mm/tlb-sh3.c +++ b/arch/sh/mm/tlb-sh3.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
23 | 22 | ||
24 | #include <asm/system.h> | 23 | #include <asm/system.h> |
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h index 0f7b0e5fb1c7..844d73a0340c 100644 --- a/arch/sparc/include/asm/thread_info_32.h +++ b/arch/sparc/include/asm/thread_info_32.h | |||
@@ -54,8 +54,6 @@ struct thread_info { | |||
54 | 54 | ||
55 | /* | 55 | /* |
56 | * macros/functions for gaining access to the thread information structure | 56 | * macros/functions for gaining access to the thread information structure |
57 | * | ||
58 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
59 | */ | 57 | */ |
60 | #define INIT_THREAD_INFO(tsk) \ | 58 | #define INIT_THREAD_INFO(tsk) \ |
61 | { \ | 59 | { \ |
@@ -64,7 +62,7 @@ struct thread_info { | |||
64 | .exec_domain = &default_exec_domain, \ | 62 | .exec_domain = &default_exec_domain, \ |
65 | .flags = 0, \ | 63 | .flags = 0, \ |
66 | .cpu = 0, \ | 64 | .cpu = 0, \ |
67 | .preempt_count = 1, \ | 65 | .preempt_count = INIT_PREEMPT_COUNT, \ |
68 | .restart_block = { \ | 66 | .restart_block = { \ |
69 | .fn = do_no_restart_syscall, \ | 67 | .fn = do_no_restart_syscall, \ |
70 | }, \ | 68 | }, \ |
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h index 65865726b283..1b45a7bbe407 100644 --- a/arch/sparc/include/asm/thread_info_64.h +++ b/arch/sparc/include/asm/thread_info_64.h | |||
@@ -125,8 +125,6 @@ struct thread_info { | |||
125 | 125 | ||
126 | /* | 126 | /* |
127 | * macros/functions for gaining access to the thread information structure | 127 | * macros/functions for gaining access to the thread information structure |
128 | * | ||
129 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
130 | */ | 128 | */ |
131 | #ifndef __ASSEMBLY__ | 129 | #ifndef __ASSEMBLY__ |
132 | 130 | ||
@@ -135,7 +133,7 @@ struct thread_info { | |||
135 | .task = &tsk, \ | 133 | .task = &tsk, \ |
136 | .flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \ | 134 | .flags = ((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT, \ |
137 | .exec_domain = &default_exec_domain, \ | 135 | .exec_domain = &default_exec_domain, \ |
138 | .preempt_count = 1, \ | 136 | .preempt_count = INIT_PREEMPT_COUNT, \ |
139 | .restart_block = { \ | 137 | .restart_block = { \ |
140 | .fn = do_no_restart_syscall, \ | 138 | .fn = do_no_restart_syscall, \ |
141 | }, \ | 139 | }, \ |
diff --git a/arch/sparc/kernel/ptrace_32.c b/arch/sparc/kernel/ptrace_32.c index 8ce6285a06d5..7e3dfd9bb97e 100644 --- a/arch/sparc/kernel/ptrace_32.c +++ b/arch/sparc/kernel/ptrace_32.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/ptrace.h> | 16 | #include <linux/ptrace.h> |
17 | #include <linux/user.h> | 17 | #include <linux/user.h> |
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/security.h> | 19 | #include <linux/security.h> |
21 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
22 | #include <linux/regset.h> | 21 | #include <linux/regset.h> |
diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index a941c610e7ce..4ae91dc2feb9 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/user.h> | 18 | #include <linux/user.h> |
19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/security.h> | 20 | #include <linux/security.h> |
22 | #include <linux/seccomp.h> | 21 | #include <linux/seccomp.h> |
23 | #include <linux/audit.h> | 22 | #include <linux/audit.h> |
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 5c12e79b4bdf..da1218e8ee87 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
16 | #include <linux/param.h> | 15 | #include <linux/param.h> |
17 | #include <linux/string.h> | 16 | #include <linux/string.h> |
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c index 358283341b47..c0490c7bbde0 100644 --- a/arch/sparc/kernel/traps_32.c +++ b/arch/sparc/kernel/traps_32.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/signal.h> | 14 | #include <linux/signal.h> |
15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/kdebug.h> | 16 | #include <linux/kdebug.h> |
18 | 17 | ||
19 | #include <asm/delay.h> | 18 | #include <asm/delay.h> |
diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 753d128ed158..c28c71449a6c 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c | |||
@@ -224,7 +224,12 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, | |||
224 | if (!strcmp(type, "domain-services-port")) | 224 | if (!strcmp(type, "domain-services-port")) |
225 | bus_id_name = "ds"; | 225 | bus_id_name = "ds"; |
226 | 226 | ||
227 | if (strlen(bus_id_name) >= BUS_ID_SIZE - 4) { | 227 | /* |
228 | * 20 char is the old driver-core name size limit, which is no more. | ||
229 | * This check can probably be removed after review and possible | ||
230 | * adaption of the vio users name length handling. | ||
231 | */ | ||
232 | if (strlen(bus_id_name) >= 20 - 4) { | ||
228 | printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n", | 233 | printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n", |
229 | bus_id_name); | 234 | bus_id_name); |
230 | return NULL; | 235 | return NULL; |
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index 62274ab9471f..fd911f855367 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h | |||
@@ -32,7 +32,7 @@ struct thread_info { | |||
32 | .exec_domain = &default_exec_domain, \ | 32 | .exec_domain = &default_exec_domain, \ |
33 | .flags = 0, \ | 33 | .flags = 0, \ |
34 | .cpu = 0, \ | 34 | .cpu = 0, \ |
35 | .preempt_count = 1, \ | 35 | .preempt_count = INIT_PREEMPT_COUNT, \ |
36 | .addr_limit = KERNEL_DS, \ | 36 | .addr_limit = KERNEL_DS, \ |
37 | .restart_block = { \ | 37 | .restart_block = { \ |
38 | .fn = do_no_restart_syscall, \ | 38 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h index 2503d4e64c2a..dc5a667ff791 100644 --- a/arch/x86/include/asm/atomic_32.h +++ b/arch/x86/include/asm/atomic_32.h | |||
@@ -19,7 +19,10 @@ | |||
19 | * | 19 | * |
20 | * Atomically reads the value of @v. | 20 | * Atomically reads the value of @v. |
21 | */ | 21 | */ |
22 | #define atomic_read(v) ((v)->counter) | 22 | static inline int atomic_read(const atomic_t *v) |
23 | { | ||
24 | return v->counter; | ||
25 | } | ||
23 | 26 | ||
24 | /** | 27 | /** |
25 | * atomic_set - set atomic variable | 28 | * atomic_set - set atomic variable |
@@ -28,7 +31,10 @@ | |||
28 | * | 31 | * |
29 | * Atomically sets the value of @v to @i. | 32 | * Atomically sets the value of @v to @i. |
30 | */ | 33 | */ |
31 | #define atomic_set(v, i) (((v)->counter) = (i)) | 34 | static inline void atomic_set(atomic_t *v, int i) |
35 | { | ||
36 | v->counter = i; | ||
37 | } | ||
32 | 38 | ||
33 | /** | 39 | /** |
34 | * atomic_add - add integer to atomic variable | 40 | * atomic_add - add integer to atomic variable |
@@ -200,8 +206,15 @@ static inline int atomic_sub_return(int i, atomic_t *v) | |||
200 | return atomic_add_return(-i, v); | 206 | return atomic_add_return(-i, v); |
201 | } | 207 | } |
202 | 208 | ||
203 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) | 209 | static inline int atomic_cmpxchg(atomic_t *v, int old, int new) |
204 | #define atomic_xchg(v, new) (xchg(&((v)->counter), (new))) | 210 | { |
211 | return cmpxchg(&v->counter, old, new); | ||
212 | } | ||
213 | |||
214 | static inline int atomic_xchg(atomic_t *v, int new) | ||
215 | { | ||
216 | return xchg(&v->counter, new); | ||
217 | } | ||
205 | 218 | ||
206 | /** | 219 | /** |
207 | * atomic_add_unless - add unless the number is already a given value | 220 | * atomic_add_unless - add unless the number is already a given value |
@@ -250,45 +263,12 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) | |||
250 | /* An 64bit atomic type */ | 263 | /* An 64bit atomic type */ |
251 | 264 | ||
252 | typedef struct { | 265 | typedef struct { |
253 | unsigned long long counter; | 266 | u64 __aligned(8) counter; |
254 | } atomic64_t; | 267 | } atomic64_t; |
255 | 268 | ||
256 | #define ATOMIC64_INIT(val) { (val) } | 269 | #define ATOMIC64_INIT(val) { (val) } |
257 | 270 | ||
258 | /** | 271 | extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val); |
259 | * atomic64_read - read atomic64 variable | ||
260 | * @ptr: pointer of type atomic64_t | ||
261 | * | ||
262 | * Atomically reads the value of @v. | ||
263 | * Doesn't imply a read memory barrier. | ||
264 | */ | ||
265 | #define __atomic64_read(ptr) ((ptr)->counter) | ||
266 | |||
267 | static inline unsigned long long | ||
268 | cmpxchg8b(unsigned long long *ptr, unsigned long long old, unsigned long long new) | ||
269 | { | ||
270 | asm volatile( | ||
271 | |||
272 | LOCK_PREFIX "cmpxchg8b (%[ptr])\n" | ||
273 | |||
274 | : "=A" (old) | ||
275 | |||
276 | : [ptr] "D" (ptr), | ||
277 | "A" (old), | ||
278 | "b" (ll_low(new)), | ||
279 | "c" (ll_high(new)) | ||
280 | |||
281 | : "memory"); | ||
282 | |||
283 | return old; | ||
284 | } | ||
285 | |||
286 | static inline unsigned long long | ||
287 | atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val, | ||
288 | unsigned long long new_val) | ||
289 | { | ||
290 | return cmpxchg8b(&ptr->counter, old_val, new_val); | ||
291 | } | ||
292 | 272 | ||
293 | /** | 273 | /** |
294 | * atomic64_xchg - xchg atomic64 variable | 274 | * atomic64_xchg - xchg atomic64 variable |
@@ -298,18 +278,7 @@ atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val, | |||
298 | * Atomically xchgs the value of @ptr to @new_val and returns | 278 | * Atomically xchgs the value of @ptr to @new_val and returns |
299 | * the old value. | 279 | * the old value. |
300 | */ | 280 | */ |
301 | 281 | extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val); | |
302 | static inline unsigned long long | ||
303 | atomic64_xchg(atomic64_t *ptr, unsigned long long new_val) | ||
304 | { | ||
305 | unsigned long long old_val; | ||
306 | |||
307 | do { | ||
308 | old_val = atomic_read(ptr); | ||
309 | } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); | ||
310 | |||
311 | return old_val; | ||
312 | } | ||
313 | 282 | ||
314 | /** | 283 | /** |
315 | * atomic64_set - set atomic64 variable | 284 | * atomic64_set - set atomic64 variable |
@@ -318,10 +287,7 @@ atomic64_xchg(atomic64_t *ptr, unsigned long long new_val) | |||
318 | * | 287 | * |
319 | * Atomically sets the value of @ptr to @new_val. | 288 | * Atomically sets the value of @ptr to @new_val. |
320 | */ | 289 | */ |
321 | static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) | 290 | extern void atomic64_set(atomic64_t *ptr, u64 new_val); |
322 | { | ||
323 | atomic64_xchg(ptr, new_val); | ||
324 | } | ||
325 | 291 | ||
326 | /** | 292 | /** |
327 | * atomic64_read - read atomic64 variable | 293 | * atomic64_read - read atomic64 variable |
@@ -329,17 +295,30 @@ static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) | |||
329 | * | 295 | * |
330 | * Atomically reads the value of @ptr and returns it. | 296 | * Atomically reads the value of @ptr and returns it. |
331 | */ | 297 | */ |
332 | static inline unsigned long long atomic64_read(atomic64_t *ptr) | 298 | static inline u64 atomic64_read(atomic64_t *ptr) |
333 | { | 299 | { |
334 | unsigned long long curr_val; | 300 | u64 res; |
335 | 301 | ||
336 | do { | 302 | /* |
337 | curr_val = __atomic64_read(ptr); | 303 | * Note, we inline this atomic64_t primitive because |
338 | } while (atomic64_cmpxchg(ptr, curr_val, curr_val) != curr_val); | 304 | * it only clobbers EAX/EDX and leaves the others |
339 | 305 | * untouched. We also (somewhat subtly) rely on the | |
340 | return curr_val; | 306 | * fact that cmpxchg8b returns the current 64-bit value |
307 | * of the memory location we are touching: | ||
308 | */ | ||
309 | asm volatile( | ||
310 | "mov %%ebx, %%eax\n\t" | ||
311 | "mov %%ecx, %%edx\n\t" | ||
312 | LOCK_PREFIX "cmpxchg8b %1\n" | ||
313 | : "=&A" (res) | ||
314 | : "m" (*ptr) | ||
315 | ); | ||
316 | |||
317 | return res; | ||
341 | } | 318 | } |
342 | 319 | ||
320 | extern u64 atomic64_read(atomic64_t *ptr); | ||
321 | |||
343 | /** | 322 | /** |
344 | * atomic64_add_return - add and return | 323 | * atomic64_add_return - add and return |
345 | * @delta: integer value to add | 324 | * @delta: integer value to add |
@@ -347,34 +326,14 @@ static inline unsigned long long atomic64_read(atomic64_t *ptr) | |||
347 | * | 326 | * |
348 | * Atomically adds @delta to @ptr and returns @delta + *@ptr | 327 | * Atomically adds @delta to @ptr and returns @delta + *@ptr |
349 | */ | 328 | */ |
350 | static inline unsigned long long | 329 | extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr); |
351 | atomic64_add_return(unsigned long long delta, atomic64_t *ptr) | ||
352 | { | ||
353 | unsigned long long old_val, new_val; | ||
354 | |||
355 | do { | ||
356 | old_val = atomic_read(ptr); | ||
357 | new_val = old_val + delta; | ||
358 | |||
359 | } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val); | ||
360 | |||
361 | return new_val; | ||
362 | } | ||
363 | |||
364 | static inline long atomic64_sub_return(unsigned long long delta, atomic64_t *ptr) | ||
365 | { | ||
366 | return atomic64_add_return(-delta, ptr); | ||
367 | } | ||
368 | 330 | ||
369 | static inline long atomic64_inc_return(atomic64_t *ptr) | 331 | /* |
370 | { | 332 | * Other variants with different arithmetic operators: |
371 | return atomic64_add_return(1, ptr); | 333 | */ |
372 | } | 334 | extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr); |
373 | 335 | extern u64 atomic64_inc_return(atomic64_t *ptr); | |
374 | static inline long atomic64_dec_return(atomic64_t *ptr) | 336 | extern u64 atomic64_dec_return(atomic64_t *ptr); |
375 | { | ||
376 | return atomic64_sub_return(1, ptr); | ||
377 | } | ||
378 | 337 | ||
379 | /** | 338 | /** |
380 | * atomic64_add - add integer to atomic64 variable | 339 | * atomic64_add - add integer to atomic64 variable |
@@ -383,10 +342,7 @@ static inline long atomic64_dec_return(atomic64_t *ptr) | |||
383 | * | 342 | * |
384 | * Atomically adds @delta to @ptr. | 343 | * Atomically adds @delta to @ptr. |
385 | */ | 344 | */ |
386 | static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr) | 345 | extern void atomic64_add(u64 delta, atomic64_t *ptr); |
387 | { | ||
388 | atomic64_add_return(delta, ptr); | ||
389 | } | ||
390 | 346 | ||
391 | /** | 347 | /** |
392 | * atomic64_sub - subtract the atomic64 variable | 348 | * atomic64_sub - subtract the atomic64 variable |
@@ -395,10 +351,7 @@ static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr) | |||
395 | * | 351 | * |
396 | * Atomically subtracts @delta from @ptr. | 352 | * Atomically subtracts @delta from @ptr. |
397 | */ | 353 | */ |
398 | static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr) | 354 | extern void atomic64_sub(u64 delta, atomic64_t *ptr); |
399 | { | ||
400 | atomic64_add(-delta, ptr); | ||
401 | } | ||
402 | 355 | ||
403 | /** | 356 | /** |
404 | * atomic64_sub_and_test - subtract value from variable and test result | 357 | * atomic64_sub_and_test - subtract value from variable and test result |
@@ -409,13 +362,7 @@ static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr) | |||
409 | * true if the result is zero, or false for all | 362 | * true if the result is zero, or false for all |
410 | * other cases. | 363 | * other cases. |
411 | */ | 364 | */ |
412 | static inline int | 365 | extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr); |
413 | atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr) | ||
414 | { | ||
415 | unsigned long long old_val = atomic64_sub_return(delta, ptr); | ||
416 | |||
417 | return old_val == 0; | ||
418 | } | ||
419 | 366 | ||
420 | /** | 367 | /** |
421 | * atomic64_inc - increment atomic64 variable | 368 | * atomic64_inc - increment atomic64 variable |
@@ -423,10 +370,7 @@ atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr) | |||
423 | * | 370 | * |
424 | * Atomically increments @ptr by 1. | 371 | * Atomically increments @ptr by 1. |
425 | */ | 372 | */ |
426 | static inline void atomic64_inc(atomic64_t *ptr) | 373 | extern void atomic64_inc(atomic64_t *ptr); |
427 | { | ||
428 | atomic64_add(1, ptr); | ||
429 | } | ||
430 | 374 | ||
431 | /** | 375 | /** |
432 | * atomic64_dec - decrement atomic64 variable | 376 | * atomic64_dec - decrement atomic64 variable |
@@ -434,10 +378,7 @@ static inline void atomic64_inc(atomic64_t *ptr) | |||
434 | * | 378 | * |
435 | * Atomically decrements @ptr by 1. | 379 | * Atomically decrements @ptr by 1. |
436 | */ | 380 | */ |
437 | static inline void atomic64_dec(atomic64_t *ptr) | 381 | extern void atomic64_dec(atomic64_t *ptr); |
438 | { | ||
439 | atomic64_sub(1, ptr); | ||
440 | } | ||
441 | 382 | ||
442 | /** | 383 | /** |
443 | * atomic64_dec_and_test - decrement and test | 384 | * atomic64_dec_and_test - decrement and test |
@@ -447,10 +388,7 @@ static inline void atomic64_dec(atomic64_t *ptr) | |||
447 | * returns true if the result is 0, or false for all other | 388 | * returns true if the result is 0, or false for all other |
448 | * cases. | 389 | * cases. |
449 | */ | 390 | */ |
450 | static inline int atomic64_dec_and_test(atomic64_t *ptr) | 391 | extern int atomic64_dec_and_test(atomic64_t *ptr); |
451 | { | ||
452 | return atomic64_sub_and_test(1, ptr); | ||
453 | } | ||
454 | 392 | ||
455 | /** | 393 | /** |
456 | * atomic64_inc_and_test - increment and test | 394 | * atomic64_inc_and_test - increment and test |
@@ -460,10 +398,7 @@ static inline int atomic64_dec_and_test(atomic64_t *ptr) | |||
460 | * and returns true if the result is zero, or false for all | 398 | * and returns true if the result is zero, or false for all |
461 | * other cases. | 399 | * other cases. |
462 | */ | 400 | */ |
463 | static inline int atomic64_inc_and_test(atomic64_t *ptr) | 401 | extern int atomic64_inc_and_test(atomic64_t *ptr); |
464 | { | ||
465 | return atomic64_sub_and_test(-1, ptr); | ||
466 | } | ||
467 | 402 | ||
468 | /** | 403 | /** |
469 | * atomic64_add_negative - add and test if negative | 404 | * atomic64_add_negative - add and test if negative |
@@ -474,13 +409,7 @@ static inline int atomic64_inc_and_test(atomic64_t *ptr) | |||
474 | * if the result is negative, or false when | 409 | * if the result is negative, or false when |
475 | * result is greater than or equal to zero. | 410 | * result is greater than or equal to zero. |
476 | */ | 411 | */ |
477 | static inline int | 412 | extern int atomic64_add_negative(u64 delta, atomic64_t *ptr); |
478 | atomic64_add_negative(unsigned long long delta, atomic64_t *ptr) | ||
479 | { | ||
480 | long long old_val = atomic64_add_return(delta, ptr); | ||
481 | |||
482 | return old_val < 0; | ||
483 | } | ||
484 | 413 | ||
485 | #include <asm-generic/atomic-long.h> | 414 | #include <asm-generic/atomic-long.h> |
486 | #endif /* _ASM_X86_ATOMIC_32_H */ | 415 | #endif /* _ASM_X86_ATOMIC_32_H */ |
diff --git a/arch/x86/include/asm/atomic_64.h b/arch/x86/include/asm/atomic_64.h index 0d6360220007..d605dc268e79 100644 --- a/arch/x86/include/asm/atomic_64.h +++ b/arch/x86/include/asm/atomic_64.h | |||
@@ -18,7 +18,10 @@ | |||
18 | * | 18 | * |
19 | * Atomically reads the value of @v. | 19 | * Atomically reads the value of @v. |
20 | */ | 20 | */ |
21 | #define atomic_read(v) ((v)->counter) | 21 | static inline int atomic_read(const atomic_t *v) |
22 | { | ||
23 | return v->counter; | ||
24 | } | ||
22 | 25 | ||
23 | /** | 26 | /** |
24 | * atomic_set - set atomic variable | 27 | * atomic_set - set atomic variable |
@@ -27,7 +30,10 @@ | |||
27 | * | 30 | * |
28 | * Atomically sets the value of @v to @i. | 31 | * Atomically sets the value of @v to @i. |
29 | */ | 32 | */ |
30 | #define atomic_set(v, i) (((v)->counter) = (i)) | 33 | static inline void atomic_set(atomic_t *v, int i) |
34 | { | ||
35 | v->counter = i; | ||
36 | } | ||
31 | 37 | ||
32 | /** | 38 | /** |
33 | * atomic_add - add integer to atomic variable | 39 | * atomic_add - add integer to atomic variable |
@@ -192,7 +198,10 @@ static inline int atomic_sub_return(int i, atomic_t *v) | |||
192 | * Atomically reads the value of @v. | 198 | * Atomically reads the value of @v. |
193 | * Doesn't imply a read memory barrier. | 199 | * Doesn't imply a read memory barrier. |
194 | */ | 200 | */ |
195 | #define atomic64_read(v) ((v)->counter) | 201 | static inline long atomic64_read(const atomic64_t *v) |
202 | { | ||
203 | return v->counter; | ||
204 | } | ||
196 | 205 | ||
197 | /** | 206 | /** |
198 | * atomic64_set - set atomic64 variable | 207 | * atomic64_set - set atomic64 variable |
@@ -201,7 +210,10 @@ static inline int atomic_sub_return(int i, atomic_t *v) | |||
201 | * | 210 | * |
202 | * Atomically sets the value of @v to @i. | 211 | * Atomically sets the value of @v to @i. |
203 | */ | 212 | */ |
204 | #define atomic64_set(v, i) (((v)->counter) = (i)) | 213 | static inline void atomic64_set(atomic64_t *v, long i) |
214 | { | ||
215 | v->counter = i; | ||
216 | } | ||
205 | 217 | ||
206 | /** | 218 | /** |
207 | * atomic64_add - add integer to atomic64 variable | 219 | * atomic64_add - add integer to atomic64 variable |
@@ -355,11 +367,25 @@ static inline long atomic64_sub_return(long i, atomic64_t *v) | |||
355 | #define atomic64_inc_return(v) (atomic64_add_return(1, (v))) | 367 | #define atomic64_inc_return(v) (atomic64_add_return(1, (v))) |
356 | #define atomic64_dec_return(v) (atomic64_sub_return(1, (v))) | 368 | #define atomic64_dec_return(v) (atomic64_sub_return(1, (v))) |
357 | 369 | ||
358 | #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) | 370 | static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new) |
359 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 371 | { |
372 | return cmpxchg(&v->counter, old, new); | ||
373 | } | ||
374 | |||
375 | static inline long atomic64_xchg(atomic64_t *v, long new) | ||
376 | { | ||
377 | return xchg(&v->counter, new); | ||
378 | } | ||
360 | 379 | ||
361 | #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), (old), (new))) | 380 | static inline long atomic_cmpxchg(atomic_t *v, int old, int new) |
362 | #define atomic_xchg(v, new) (xchg(&((v)->counter), (new))) | 381 | { |
382 | return cmpxchg(&v->counter, old, new); | ||
383 | } | ||
384 | |||
385 | static inline long atomic_xchg(atomic_t *v, int new) | ||
386 | { | ||
387 | return xchg(&v->counter, new); | ||
388 | } | ||
363 | 389 | ||
364 | /** | 390 | /** |
365 | * atomic_add_unless - add unless the number is a given value | 391 | * atomic_add_unless - add unless the number is a given value |
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index daf866ed0612..330ee807f89e 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h | |||
@@ -161,6 +161,7 @@ extern int io_apic_set_pci_routing(struct device *dev, int irq, | |||
161 | struct io_apic_irq_attr *irq_attr); | 161 | struct io_apic_irq_attr *irq_attr); |
162 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); | 162 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); |
163 | extern void ioapic_init_mappings(void); | 163 | extern void ioapic_init_mappings(void); |
164 | extern void ioapic_insert_resources(void); | ||
164 | 165 | ||
165 | extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); | 166 | extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); |
166 | extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); | 167 | extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); |
@@ -180,6 +181,7 @@ extern void ioapic_write_entry(int apic, int pin, | |||
180 | #define io_apic_assign_pci_irqs 0 | 181 | #define io_apic_assign_pci_irqs 0 |
181 | static const int timer_through_8259 = 0; | 182 | static const int timer_through_8259 = 0; |
182 | static inline void ioapic_init_mappings(void) { } | 183 | static inline void ioapic_init_mappings(void) { } |
184 | static inline void ioapic_insert_resources(void) { } | ||
183 | 185 | ||
184 | static inline void probe_nr_irqs_gsi(void) { } | 186 | static inline void probe_nr_irqs_gsi(void) { } |
185 | #endif | 187 | #endif |
diff --git a/arch/x86/include/asm/lguest_hcall.h b/arch/x86/include/asm/lguest_hcall.h index d31c4a684078..33600a66755f 100644 --- a/arch/x86/include/asm/lguest_hcall.h +++ b/arch/x86/include/asm/lguest_hcall.h | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <asm/hw_irq.h> | 30 | #include <asm/hw_irq.h> |
31 | #include <asm/kvm_para.h> | 31 | #include <asm/kvm_para.h> |
32 | 32 | ||
33 | /*G:031 But first, how does our Guest contact the Host to ask for privileged | 33 | /*G:030 But first, how does our Guest contact the Host to ask for privileged |
34 | * operations? There are two ways: the direct way is to make a "hypercall", | 34 | * operations? There are two ways: the direct way is to make a "hypercall", |
35 | * to make requests of the Host Itself. | 35 | * to make requests of the Host Itself. |
36 | * | 36 | * |
diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index f517944b2b17..cf86a5e73815 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | extern int kstack_depth_to_print; | 4 | extern int kstack_depth_to_print; |
5 | 5 | ||
6 | int x86_is_stack_id(int id, char *name); | ||
7 | |||
6 | /* Generic stack tracer with callbacks */ | 8 | /* Generic stack tracer with callbacks */ |
7 | 9 | ||
8 | struct stacktrace_ops { | 10 | struct stacktrace_ops { |
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index b0783520988b..fad7d40b75f8 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
@@ -49,7 +49,7 @@ struct thread_info { | |||
49 | .exec_domain = &default_exec_domain, \ | 49 | .exec_domain = &default_exec_domain, \ |
50 | .flags = 0, \ | 50 | .flags = 0, \ |
51 | .cpu = 0, \ | 51 | .cpu = 0, \ |
52 | .preempt_count = 1, \ | 52 | .preempt_count = INIT_PREEMPT_COUNT, \ |
53 | .addr_limit = KERNEL_DS, \ | 53 | .addr_limit = KERNEL_DS, \ |
54 | .restart_block = { \ | 54 | .restart_block = { \ |
55 | .fn = do_no_restart_syscall, \ | 55 | .fn = do_no_restart_syscall, \ |
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c index 69328ac8de9c..8952a5890281 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c | |||
@@ -652,7 +652,8 @@ static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem, | |||
652 | return ret && es7000_apic_is_cluster(); | 652 | return ret && es7000_apic_is_cluster(); |
653 | } | 653 | } |
654 | 654 | ||
655 | struct apic apic_es7000_cluster = { | 655 | /* We've been warned by a false positive warning.Use __refdata to keep calm. */ |
656 | struct apic __refdata apic_es7000_cluster = { | ||
656 | 657 | ||
657 | .name = "es7000", | 658 | .name = "es7000", |
658 | .probe = probe_es7000, | 659 | .probe = probe_es7000, |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 90b5e6efa938..2284a4812b68 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -4181,28 +4181,20 @@ fake_ioapic_page: | |||
4181 | } | 4181 | } |
4182 | } | 4182 | } |
4183 | 4183 | ||
4184 | static int __init ioapic_insert_resources(void) | 4184 | void __init ioapic_insert_resources(void) |
4185 | { | 4185 | { |
4186 | int i; | 4186 | int i; |
4187 | struct resource *r = ioapic_resources; | 4187 | struct resource *r = ioapic_resources; |
4188 | 4188 | ||
4189 | if (!r) { | 4189 | if (!r) { |
4190 | if (nr_ioapics > 0) { | 4190 | if (nr_ioapics > 0) |
4191 | printk(KERN_ERR | 4191 | printk(KERN_ERR |
4192 | "IO APIC resources couldn't be allocated.\n"); | 4192 | "IO APIC resources couldn't be allocated.\n"); |
4193 | return -1; | 4193 | return; |
4194 | } | ||
4195 | return 0; | ||
4196 | } | 4194 | } |
4197 | 4195 | ||
4198 | for (i = 0; i < nr_ioapics; i++) { | 4196 | for (i = 0; i < nr_ioapics; i++) { |
4199 | insert_resource(&iomem_resource, r); | 4197 | insert_resource(&iomem_resource, r); |
4200 | r++; | 4198 | r++; |
4201 | } | 4199 | } |
4202 | |||
4203 | return 0; | ||
4204 | } | 4200 | } |
4205 | |||
4206 | /* Insert the IO APIC resources after PCI initialization has occured to handle | ||
4207 | * IO APICS that are mapped in on a BAR in PCI space. */ | ||
4208 | late_initcall(ioapic_insert_resources); | ||
diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index 533e59c6fc82..ca96e68f0d23 100644 --- a/arch/x86/kernel/apic/numaq_32.c +++ b/arch/x86/kernel/apic/numaq_32.c | |||
@@ -493,7 +493,8 @@ static void numaq_setup_portio_remap(void) | |||
493 | (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD); | 493 | (u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD); |
494 | } | 494 | } |
495 | 495 | ||
496 | struct apic apic_numaq = { | 496 | /* Use __refdata to keep false positive warning calm. */ |
497 | struct apic __refdata apic_numaq = { | ||
497 | 498 | ||
498 | .name = "NUMAQ", | 499 | .name = "NUMAQ", |
499 | .probe = probe_numaq, | 500 | .probe = probe_numaq, |
diff --git a/arch/x86/kernel/cpu/perf_counter.c b/arch/x86/kernel/cpu/perf_counter.c index d4cf4ce19aac..36c3dc7b8991 100644 --- a/arch/x86/kernel/cpu/perf_counter.c +++ b/arch/x86/kernel/cpu/perf_counter.c | |||
@@ -1561,6 +1561,7 @@ void callchain_store(struct perf_callchain_entry *entry, u64 ip) | |||
1561 | 1561 | ||
1562 | static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry); | 1562 | static DEFINE_PER_CPU(struct perf_callchain_entry, irq_entry); |
1563 | static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry); | 1563 | static DEFINE_PER_CPU(struct perf_callchain_entry, nmi_entry); |
1564 | static DEFINE_PER_CPU(int, in_nmi_frame); | ||
1564 | 1565 | ||
1565 | 1566 | ||
1566 | static void | 1567 | static void |
@@ -1576,7 +1577,9 @@ static void backtrace_warning(void *data, char *msg) | |||
1576 | 1577 | ||
1577 | static int backtrace_stack(void *data, char *name) | 1578 | static int backtrace_stack(void *data, char *name) |
1578 | { | 1579 | { |
1579 | /* Process all stacks: */ | 1580 | per_cpu(in_nmi_frame, smp_processor_id()) = |
1581 | x86_is_stack_id(NMI_STACK, name); | ||
1582 | |||
1580 | return 0; | 1583 | return 0; |
1581 | } | 1584 | } |
1582 | 1585 | ||
@@ -1584,6 +1587,9 @@ static void backtrace_address(void *data, unsigned long addr, int reliable) | |||
1584 | { | 1587 | { |
1585 | struct perf_callchain_entry *entry = data; | 1588 | struct perf_callchain_entry *entry = data; |
1586 | 1589 | ||
1590 | if (per_cpu(in_nmi_frame, smp_processor_id())) | ||
1591 | return; | ||
1592 | |||
1587 | if (reliable) | 1593 | if (reliable) |
1588 | callchain_store(entry, addr); | 1594 | callchain_store(entry, addr); |
1589 | } | 1595 | } |
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index d593cd1f58dc..bca5fba91c9e 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
@@ -19,6 +19,12 @@ | |||
19 | 19 | ||
20 | #include "dumpstack.h" | 20 | #include "dumpstack.h" |
21 | 21 | ||
22 | /* Just a stub for now */ | ||
23 | int x86_is_stack_id(int id, char *name) | ||
24 | { | ||
25 | return 0; | ||
26 | } | ||
27 | |||
22 | void dump_trace(struct task_struct *task, struct pt_regs *regs, | 28 | void dump_trace(struct task_struct *task, struct pt_regs *regs, |
23 | unsigned long *stack, unsigned long bp, | 29 | unsigned long *stack, unsigned long bp, |
24 | const struct stacktrace_ops *ops, void *data) | 30 | const struct stacktrace_ops *ops, void *data) |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index d35db5993fd6..54b0a3276766 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -19,10 +19,8 @@ | |||
19 | 19 | ||
20 | #include "dumpstack.h" | 20 | #include "dumpstack.h" |
21 | 21 | ||
22 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | 22 | |
23 | unsigned *usedp, char **idp) | 23 | static char x86_stack_ids[][8] = { |
24 | { | ||
25 | static char ids[][8] = { | ||
26 | [DEBUG_STACK - 1] = "#DB", | 24 | [DEBUG_STACK - 1] = "#DB", |
27 | [NMI_STACK - 1] = "NMI", | 25 | [NMI_STACK - 1] = "NMI", |
28 | [DOUBLEFAULT_STACK - 1] = "#DF", | 26 | [DOUBLEFAULT_STACK - 1] = "#DF", |
@@ -33,6 +31,15 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
33 | N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" | 31 | N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]" |
34 | #endif | 32 | #endif |
35 | }; | 33 | }; |
34 | |||
35 | int x86_is_stack_id(int id, char *name) | ||
36 | { | ||
37 | return x86_stack_ids[id - 1] == name; | ||
38 | } | ||
39 | |||
40 | static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | ||
41 | unsigned *usedp, char **idp) | ||
42 | { | ||
36 | unsigned k; | 43 | unsigned k; |
37 | 44 | ||
38 | /* | 45 | /* |
@@ -61,7 +68,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
61 | if (*usedp & (1U << k)) | 68 | if (*usedp & (1U << k)) |
62 | break; | 69 | break; |
63 | *usedp |= 1U << k; | 70 | *usedp |= 1U << k; |
64 | *idp = ids[k]; | 71 | *idp = x86_stack_ids[k]; |
65 | return (unsigned long *)end; | 72 | return (unsigned long *)end; |
66 | } | 73 | } |
67 | /* | 74 | /* |
@@ -81,12 +88,13 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, | |||
81 | do { | 88 | do { |
82 | ++j; | 89 | ++j; |
83 | end -= EXCEPTION_STKSZ; | 90 | end -= EXCEPTION_STKSZ; |
84 | ids[j][4] = '1' + (j - N_EXCEPTION_STACKS); | 91 | x86_stack_ids[j][4] = '1' + |
92 | (j - N_EXCEPTION_STACKS); | ||
85 | } while (stack < end - EXCEPTION_STKSZ); | 93 | } while (stack < end - EXCEPTION_STKSZ); |
86 | if (*usedp & (1U << j)) | 94 | if (*usedp & (1U << j)) |
87 | break; | 95 | break; |
88 | *usedp |= 1U << j; | 96 | *usedp |= 1U << j; |
89 | *idp = ids[j]; | 97 | *idp = x86_stack_ids[j]; |
90 | return (unsigned long *)end; | 98 | return (unsigned long *)end; |
91 | } | 99 | } |
92 | #endif | 100 | #endif |
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 4f9c55f3a7c0..03801f2f761f 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c | |||
@@ -60,7 +60,7 @@ static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift) | |||
60 | "adc %5,%%edx ; " | 60 | "adc %5,%%edx ; " |
61 | : "=A" (product), "=r" (tmp1), "=r" (tmp2) | 61 | : "=A" (product), "=r" (tmp1), "=r" (tmp2) |
62 | : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); | 62 | : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); |
63 | #elif __x86_64__ | 63 | #elif defined(__x86_64__) |
64 | __asm__ ( | 64 | __asm__ ( |
65 | "mul %%rdx ; shrd $32,%%rdx,%%rax" | 65 | "mul %%rdx ; shrd $32,%%rdx,%%rax" |
66 | : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); | 66 | : "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 7bc65f0f62c4..f2bf1f73d468 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -379,6 +379,11 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, | |||
379 | 379 | ||
380 | native_cpuid(ax, bx, cx, dx); | 380 | native_cpuid(ax, bx, cx, dx); |
381 | switch (function) { | 381 | switch (function) { |
382 | case 0: /* ID and highest CPUID. Futureproof a little by sticking to | ||
383 | * older ones. */ | ||
384 | if (*ax > 5) | ||
385 | *ax = 5; | ||
386 | break; | ||
382 | case 1: /* Basic feature request. */ | 387 | case 1: /* Basic feature request. */ |
383 | /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ | 388 | /* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */ |
384 | *cx &= 0x00002201; | 389 | *cx &= 0x00002201; |
@@ -1079,7 +1084,7 @@ static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf, | |||
1079 | return insn_len; | 1084 | return insn_len; |
1080 | } | 1085 | } |
1081 | 1086 | ||
1082 | /*G:030 Once we get to lguest_init(), we know we're a Guest. The various | 1087 | /*G:029 Once we get to lguest_init(), we know we're a Guest. The various |
1083 | * pv_ops structures in the kernel provide points for (almost) every routine we | 1088 | * pv_ops structures in the kernel provide points for (almost) every routine we |
1084 | * have to override to avoid privileged instructions. */ | 1089 | * have to override to avoid privileged instructions. */ |
1085 | __init void lguest_init(void) | 1090 | __init void lguest_init(void) |
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index f9d35632666b..07c31899c9c2 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile | |||
@@ -10,6 +10,7 @@ lib-y += usercopy_$(BITS).o getuser.o putuser.o | |||
10 | lib-y += memcpy_$(BITS).o | 10 | lib-y += memcpy_$(BITS).o |
11 | 11 | ||
12 | ifeq ($(CONFIG_X86_32),y) | 12 | ifeq ($(CONFIG_X86_32),y) |
13 | obj-y += atomic64_32.o | ||
13 | lib-y += checksum_32.o | 14 | lib-y += checksum_32.o |
14 | lib-y += strstr_32.o | 15 | lib-y += strstr_32.o |
15 | lib-y += semaphore_32.o string_32.o | 16 | lib-y += semaphore_32.o string_32.o |
diff --git a/arch/x86/lib/atomic64_32.c b/arch/x86/lib/atomic64_32.c new file mode 100644 index 000000000000..824fa0be55a3 --- /dev/null +++ b/arch/x86/lib/atomic64_32.c | |||
@@ -0,0 +1,230 @@ | |||
1 | #include <linux/compiler.h> | ||
2 | #include <linux/module.h> | ||
3 | #include <linux/types.h> | ||
4 | |||
5 | #include <asm/processor.h> | ||
6 | #include <asm/cmpxchg.h> | ||
7 | #include <asm/atomic.h> | ||
8 | |||
9 | static noinline u64 cmpxchg8b(u64 *ptr, u64 old, u64 new) | ||
10 | { | ||
11 | u32 low = new; | ||
12 | u32 high = new >> 32; | ||
13 | |||
14 | asm volatile( | ||
15 | LOCK_PREFIX "cmpxchg8b %1\n" | ||
16 | : "+A" (old), "+m" (*ptr) | ||
17 | : "b" (low), "c" (high) | ||
18 | ); | ||
19 | return old; | ||
20 | } | ||
21 | |||
22 | u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val) | ||
23 | { | ||
24 | return cmpxchg8b(&ptr->counter, old_val, new_val); | ||
25 | } | ||
26 | EXPORT_SYMBOL(atomic64_cmpxchg); | ||
27 | |||
28 | /** | ||
29 | * atomic64_xchg - xchg atomic64 variable | ||
30 | * @ptr: pointer to type atomic64_t | ||
31 | * @new_val: value to assign | ||
32 | * | ||
33 | * Atomically xchgs the value of @ptr to @new_val and returns | ||
34 | * the old value. | ||
35 | */ | ||
36 | u64 atomic64_xchg(atomic64_t *ptr, u64 new_val) | ||
37 | { | ||
38 | /* | ||
39 | * Try first with a (possibly incorrect) assumption about | ||
40 | * what we have there. We'll do two loops most likely, | ||
41 | * but we'll get an ownership MESI transaction straight away | ||
42 | * instead of a read transaction followed by a | ||
43 | * flush-for-ownership transaction: | ||
44 | */ | ||
45 | u64 old_val, real_val = 0; | ||
46 | |||
47 | do { | ||
48 | old_val = real_val; | ||
49 | |||
50 | real_val = atomic64_cmpxchg(ptr, old_val, new_val); | ||
51 | |||
52 | } while (real_val != old_val); | ||
53 | |||
54 | return old_val; | ||
55 | } | ||
56 | EXPORT_SYMBOL(atomic64_xchg); | ||
57 | |||
58 | /** | ||
59 | * atomic64_set - set atomic64 variable | ||
60 | * @ptr: pointer to type atomic64_t | ||
61 | * @new_val: value to assign | ||
62 | * | ||
63 | * Atomically sets the value of @ptr to @new_val. | ||
64 | */ | ||
65 | void atomic64_set(atomic64_t *ptr, u64 new_val) | ||
66 | { | ||
67 | atomic64_xchg(ptr, new_val); | ||
68 | } | ||
69 | EXPORT_SYMBOL(atomic64_set); | ||
70 | |||
71 | /** | ||
72 | EXPORT_SYMBOL(atomic64_read); | ||
73 | * atomic64_add_return - add and return | ||
74 | * @delta: integer value to add | ||
75 | * @ptr: pointer to type atomic64_t | ||
76 | * | ||
77 | * Atomically adds @delta to @ptr and returns @delta + *@ptr | ||
78 | */ | ||
79 | noinline u64 atomic64_add_return(u64 delta, atomic64_t *ptr) | ||
80 | { | ||
81 | /* | ||
82 | * Try first with a (possibly incorrect) assumption about | ||
83 | * what we have there. We'll do two loops most likely, | ||
84 | * but we'll get an ownership MESI transaction straight away | ||
85 | * instead of a read transaction followed by a | ||
86 | * flush-for-ownership transaction: | ||
87 | */ | ||
88 | u64 old_val, new_val, real_val = 0; | ||
89 | |||
90 | do { | ||
91 | old_val = real_val; | ||
92 | new_val = old_val + delta; | ||
93 | |||
94 | real_val = atomic64_cmpxchg(ptr, old_val, new_val); | ||
95 | |||
96 | } while (real_val != old_val); | ||
97 | |||
98 | return new_val; | ||
99 | } | ||
100 | EXPORT_SYMBOL(atomic64_add_return); | ||
101 | |||
102 | u64 atomic64_sub_return(u64 delta, atomic64_t *ptr) | ||
103 | { | ||
104 | return atomic64_add_return(-delta, ptr); | ||
105 | } | ||
106 | EXPORT_SYMBOL(atomic64_sub_return); | ||
107 | |||
108 | u64 atomic64_inc_return(atomic64_t *ptr) | ||
109 | { | ||
110 | return atomic64_add_return(1, ptr); | ||
111 | } | ||
112 | EXPORT_SYMBOL(atomic64_inc_return); | ||
113 | |||
114 | u64 atomic64_dec_return(atomic64_t *ptr) | ||
115 | { | ||
116 | return atomic64_sub_return(1, ptr); | ||
117 | } | ||
118 | EXPORT_SYMBOL(atomic64_dec_return); | ||
119 | |||
120 | /** | ||
121 | * atomic64_add - add integer to atomic64 variable | ||
122 | * @delta: integer value to add | ||
123 | * @ptr: pointer to type atomic64_t | ||
124 | * | ||
125 | * Atomically adds @delta to @ptr. | ||
126 | */ | ||
127 | void atomic64_add(u64 delta, atomic64_t *ptr) | ||
128 | { | ||
129 | atomic64_add_return(delta, ptr); | ||
130 | } | ||
131 | EXPORT_SYMBOL(atomic64_add); | ||
132 | |||
133 | /** | ||
134 | * atomic64_sub - subtract the atomic64 variable | ||
135 | * @delta: integer value to subtract | ||
136 | * @ptr: pointer to type atomic64_t | ||
137 | * | ||
138 | * Atomically subtracts @delta from @ptr. | ||
139 | */ | ||
140 | void atomic64_sub(u64 delta, atomic64_t *ptr) | ||
141 | { | ||
142 | atomic64_add(-delta, ptr); | ||
143 | } | ||
144 | EXPORT_SYMBOL(atomic64_sub); | ||
145 | |||
146 | /** | ||
147 | * atomic64_sub_and_test - subtract value from variable and test result | ||
148 | * @delta: integer value to subtract | ||
149 | * @ptr: pointer to type atomic64_t | ||
150 | * | ||
151 | * Atomically subtracts @delta from @ptr and returns | ||
152 | * true if the result is zero, or false for all | ||
153 | * other cases. | ||
154 | */ | ||
155 | int atomic64_sub_and_test(u64 delta, atomic64_t *ptr) | ||
156 | { | ||
157 | u64 new_val = atomic64_sub_return(delta, ptr); | ||
158 | |||
159 | return new_val == 0; | ||
160 | } | ||
161 | EXPORT_SYMBOL(atomic64_sub_and_test); | ||
162 | |||
163 | /** | ||
164 | * atomic64_inc - increment atomic64 variable | ||
165 | * @ptr: pointer to type atomic64_t | ||
166 | * | ||
167 | * Atomically increments @ptr by 1. | ||
168 | */ | ||
169 | void atomic64_inc(atomic64_t *ptr) | ||
170 | { | ||
171 | atomic64_add(1, ptr); | ||
172 | } | ||
173 | EXPORT_SYMBOL(atomic64_inc); | ||
174 | |||
175 | /** | ||
176 | * atomic64_dec - decrement atomic64 variable | ||
177 | * @ptr: pointer to type atomic64_t | ||
178 | * | ||
179 | * Atomically decrements @ptr by 1. | ||
180 | */ | ||
181 | void atomic64_dec(atomic64_t *ptr) | ||
182 | { | ||
183 | atomic64_sub(1, ptr); | ||
184 | } | ||
185 | EXPORT_SYMBOL(atomic64_dec); | ||
186 | |||
187 | /** | ||
188 | * atomic64_dec_and_test - decrement and test | ||
189 | * @ptr: pointer to type atomic64_t | ||
190 | * | ||
191 | * Atomically decrements @ptr by 1 and | ||
192 | * returns true if the result is 0, or false for all other | ||
193 | * cases. | ||
194 | */ | ||
195 | int atomic64_dec_and_test(atomic64_t *ptr) | ||
196 | { | ||
197 | return atomic64_sub_and_test(1, ptr); | ||
198 | } | ||
199 | EXPORT_SYMBOL(atomic64_dec_and_test); | ||
200 | |||
201 | /** | ||
202 | * atomic64_inc_and_test - increment and test | ||
203 | * @ptr: pointer to type atomic64_t | ||
204 | * | ||
205 | * Atomically increments @ptr by 1 | ||
206 | * and returns true if the result is zero, or false for all | ||
207 | * other cases. | ||
208 | */ | ||
209 | int atomic64_inc_and_test(atomic64_t *ptr) | ||
210 | { | ||
211 | return atomic64_sub_and_test(-1, ptr); | ||
212 | } | ||
213 | EXPORT_SYMBOL(atomic64_inc_and_test); | ||
214 | |||
215 | /** | ||
216 | * atomic64_add_negative - add and test if negative | ||
217 | * @delta: integer value to add | ||
218 | * @ptr: pointer to type atomic64_t | ||
219 | * | ||
220 | * Atomically adds @delta to @ptr and returns true | ||
221 | * if the result is negative, or false when | ||
222 | * result is greater than or equal to zero. | ||
223 | */ | ||
224 | int atomic64_add_negative(u64 delta, atomic64_t *ptr) | ||
225 | { | ||
226 | s64 new_val = atomic64_add_return(delta, ptr); | ||
227 | |||
228 | return new_val < 0; | ||
229 | } | ||
230 | EXPORT_SYMBOL(atomic64_add_negative); | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 85307cc6e45f..bfae139182ff 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -697,7 +697,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, | |||
697 | if (!printk_ratelimit()) | 697 | if (!printk_ratelimit()) |
698 | return; | 698 | return; |
699 | 699 | ||
700 | printk(KERN_CONT "%s%s[%d]: segfault at %lx ip %p sp %p error %lx", | 700 | printk("%s%s[%d]: segfault at %lx ip %p sp %p error %lx", |
701 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, | 701 | task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, |
702 | tsk->comm, task_pid_nr(tsk), address, | 702 | tsk->comm, task_pid_nr(tsk), address, |
703 | (void *)regs->ip, (void *)regs->sp, error_code); | 703 | (void *)regs->ip, (void *)regs->sp, error_code); |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index b07dd8d0b321..89b9a5cd63da 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -390,7 +390,7 @@ static int __init p4_init(char **cpu_type) | |||
390 | static int force_arch_perfmon; | 390 | static int force_arch_perfmon; |
391 | static int force_cpu_type(const char *str, struct kernel_param *kp) | 391 | static int force_cpu_type(const char *str, struct kernel_param *kp) |
392 | { | 392 | { |
393 | if (!strcmp(str, "archperfmon")) { | 393 | if (!strcmp(str, "arch_perfmon")) { |
394 | force_arch_perfmon = 1; | 394 | force_arch_perfmon = 1; |
395 | printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); | 395 | printk(KERN_INFO "oprofile: forcing architectural perfmon\n"); |
396 | } | 396 | } |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 0fb56db16d18..52e62e57fedd 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/pat.h> | 35 | #include <asm/pat.h> |
36 | #include <asm/e820.h> | 36 | #include <asm/e820.h> |
37 | #include <asm/pci_x86.h> | 37 | #include <asm/pci_x86.h> |
38 | #include <asm/io_apic.h> | ||
38 | 39 | ||
39 | 40 | ||
40 | static int | 41 | static int |
@@ -227,6 +228,12 @@ void __init pcibios_resource_survey(void) | |||
227 | pcibios_allocate_resources(1); | 228 | pcibios_allocate_resources(1); |
228 | 229 | ||
229 | e820_reserve_resources_late(); | 230 | e820_reserve_resources_late(); |
231 | /* | ||
232 | * Insert the IO APIC resources after PCI initialization has | ||
233 | * occured to handle IO APICS that are mapped in on a BAR in | ||
234 | * PCI space, but before trying to assign unassigned pci res. | ||
235 | */ | ||
236 | ioapic_insert_resources(); | ||
230 | } | 237 | } |
231 | 238 | ||
232 | /** | 239 | /** |
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h index 0f4fe1faf9ba..13165641cc51 100644 --- a/arch/xtensa/include/asm/thread_info.h +++ b/arch/xtensa/include/asm/thread_info.h | |||
@@ -80,8 +80,6 @@ struct thread_info { | |||
80 | 80 | ||
81 | /* | 81 | /* |
82 | * macros/functions for gaining access to the thread information structure | 82 | * macros/functions for gaining access to the thread information structure |
83 | * | ||
84 | * preempt_count needs to be 1 initially, until the scheduler is functional. | ||
85 | */ | 83 | */ |
86 | 84 | ||
87 | #ifndef __ASSEMBLY__ | 85 | #ifndef __ASSEMBLY__ |
@@ -92,7 +90,7 @@ struct thread_info { | |||
92 | .exec_domain = &default_exec_domain, \ | 90 | .exec_domain = &default_exec_domain, \ |
93 | .flags = 0, \ | 91 | .flags = 0, \ |
94 | .cpu = 0, \ | 92 | .cpu = 0, \ |
95 | .preempt_count = 1, \ | 93 | .preempt_count = INIT_PREEMPT_COUNT, \ |
96 | .addr_limit = KERNEL_DS, \ | 94 | .addr_limit = KERNEL_DS, \ |
97 | .restart_block = { \ | 95 | .restart_block = { \ |
98 | .fn = do_no_restart_syscall, \ | 96 | .fn = do_no_restart_syscall, \ |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 15a23031833f..336eb1ed73cc 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -513,6 +513,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
513 | { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */ | 513 | { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */ |
514 | { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */ | 514 | { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */ |
515 | { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ | 515 | { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ |
516 | { PCI_VDEVICE(INTEL, 0x3a22), board_ahci }, /* ICH10 */ | ||
516 | { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */ | 517 | { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */ |
517 | { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ | 518 | { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ |
518 | { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ | 519 | { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 045a486a09ea..2c6aedaef718 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -3392,17 +3392,27 @@ int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel) | |||
3392 | 3392 | ||
3393 | static int ata_dev_set_mode(struct ata_device *dev) | 3393 | static int ata_dev_set_mode(struct ata_device *dev) |
3394 | { | 3394 | { |
3395 | struct ata_port *ap = dev->link->ap; | ||
3395 | struct ata_eh_context *ehc = &dev->link->eh_context; | 3396 | struct ata_eh_context *ehc = &dev->link->eh_context; |
3397 | const bool nosetxfer = dev->horkage & ATA_HORKAGE_NOSETXFER; | ||
3396 | const char *dev_err_whine = ""; | 3398 | const char *dev_err_whine = ""; |
3397 | int ign_dev_err = 0; | 3399 | int ign_dev_err = 0; |
3398 | unsigned int err_mask; | 3400 | unsigned int err_mask = 0; |
3399 | int rc; | 3401 | int rc; |
3400 | 3402 | ||
3401 | dev->flags &= ~ATA_DFLAG_PIO; | 3403 | dev->flags &= ~ATA_DFLAG_PIO; |
3402 | if (dev->xfer_shift == ATA_SHIFT_PIO) | 3404 | if (dev->xfer_shift == ATA_SHIFT_PIO) |
3403 | dev->flags |= ATA_DFLAG_PIO; | 3405 | dev->flags |= ATA_DFLAG_PIO; |
3404 | 3406 | ||
3405 | err_mask = ata_dev_set_xfermode(dev); | 3407 | if (nosetxfer && ap->flags & ATA_FLAG_SATA && ata_id_is_sata(dev->id)) |
3408 | dev_err_whine = " (SET_XFERMODE skipped)"; | ||
3409 | else { | ||
3410 | if (nosetxfer) | ||
3411 | ata_dev_printk(dev, KERN_WARNING, | ||
3412 | "NOSETXFER but PATA detected - can't " | ||
3413 | "skip SETXFER, might malfunction\n"); | ||
3414 | err_mask = ata_dev_set_xfermode(dev); | ||
3415 | } | ||
3406 | 3416 | ||
3407 | if (err_mask & ~AC_ERR_DEV) | 3417 | if (err_mask & ~AC_ERR_DEV) |
3408 | goto fail; | 3418 | goto fail; |
@@ -4297,6 +4307,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4297 | /* Devices which aren't very happy with higher link speeds */ | 4307 | /* Devices which aren't very happy with higher link speeds */ |
4298 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, | 4308 | { "WD My Book", NULL, ATA_HORKAGE_1_5_GBPS, }, |
4299 | 4309 | ||
4310 | /* | ||
4311 | * Devices which choke on SETXFER. Applies only if both the | ||
4312 | * device and controller are SATA. | ||
4313 | */ | ||
4314 | { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, | ||
4315 | |||
4300 | /* End Marker */ | 4316 | /* End Marker */ |
4301 | { } | 4317 | { } |
4302 | }; | 4318 | }; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index fa22f94ca415..1a07c061f644 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -2517,6 +2517,10 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2517 | 2517 | ||
2518 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | 2518 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
2519 | rc = ata_do_reset(link, reset, classes, deadline, true); | 2519 | rc = ata_do_reset(link, reset, classes, deadline, true); |
2520 | if (rc) { | ||
2521 | failed_link = link; | ||
2522 | goto fail; | ||
2523 | } | ||
2520 | } | 2524 | } |
2521 | } else { | 2525 | } else { |
2522 | if (verbose) | 2526 | if (verbose) |
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 4b27617be26d..8561a9f195c1 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c | |||
@@ -312,11 +312,12 @@ err_ide_ioremap: | |||
312 | static int __devexit pata_at91_remove(struct platform_device *pdev) | 312 | static int __devexit pata_at91_remove(struct platform_device *pdev) |
313 | { | 313 | { |
314 | struct ata_host *host = dev_get_drvdata(&pdev->dev); | 314 | struct ata_host *host = dev_get_drvdata(&pdev->dev); |
315 | struct at91_ide_info *info = host->private_data; | 315 | struct at91_ide_info *info; |
316 | struct device *dev = &pdev->dev; | 316 | struct device *dev = &pdev->dev; |
317 | 317 | ||
318 | if (!host) | 318 | if (!host) |
319 | return 0; | 319 | return 0; |
320 | info = host->private_data; | ||
320 | 321 | ||
321 | ata_host_detach(host); | 322 | ata_host_detach(host); |
322 | 323 | ||
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index e8beb8e5b626..05dd307e8f02 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -428,6 +428,9 @@ int devres_release_all(struct device *dev) | |||
428 | { | 428 | { |
429 | unsigned long flags; | 429 | unsigned long flags; |
430 | 430 | ||
431 | /* Looks like an uninitialized device structure */ | ||
432 | if (WARN_ON(dev->devres_head.next == NULL)) | ||
433 | return -ENODEV; | ||
431 | spin_lock_irqsave(&dev->devres_lock, flags); | 434 | spin_lock_irqsave(&dev->devres_lock, flags); |
432 | return release_nodes(dev, dev->devres_head.next, &dev->devres_head, | 435 | return release_nodes(dev, dev->devres_head.next, &dev->devres_head, |
433 | flags); | 436 | flags); |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index fc466531260e..f285f441fab9 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -217,8 +217,10 @@ firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
217 | ret_count = -ENODEV; | 217 | ret_count = -ENODEV; |
218 | goto out; | 218 | goto out; |
219 | } | 219 | } |
220 | if (offset > fw->size) | 220 | if (offset > fw->size) { |
221 | return 0; | 221 | ret_count = 0; |
222 | goto out; | ||
223 | } | ||
222 | if (count > fw->size - offset) | 224 | if (count > fw->size - offset) |
223 | count = fw->size - offset; | 225 | count = fw->size - offset; |
224 | 226 | ||
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 668dc234b8e2..1e6b7c14f697 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/ioport.h> | 36 | #include <linux/ioport.h> |
37 | #include <linux/mm.h> | 37 | #include <linux/mm.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/smp_lock.h> | ||
39 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
40 | #include <linux/reboot.h> | 41 | #include <linux/reboot.h> |
41 | #include <linux/spinlock.h> | 42 | #include <linux/spinlock.h> |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index bb72ada9f074..1d886e079c58 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -298,6 +298,22 @@ config BLK_DEV_NBD | |||
298 | 298 | ||
299 | If unsure, say N. | 299 | If unsure, say N. |
300 | 300 | ||
301 | config BLK_DEV_OSD | ||
302 | tristate "OSD object-as-blkdev support" | ||
303 | depends on SCSI_OSD_ULD | ||
304 | ---help--- | ||
305 | Saying Y or M here will allow the exporting of a single SCSI | ||
306 | OSD (object-based storage) object as a Linux block device. | ||
307 | |||
308 | For example, if you create a 2G object on an OSD device, | ||
309 | you can then use this module to present that 2G object as | ||
310 | a Linux block device. | ||
311 | |||
312 | To compile this driver as a module, choose M here: the | ||
313 | module will be called osdblk. | ||
314 | |||
315 | If unsure, say N. | ||
316 | |||
301 | config BLK_DEV_SX8 | 317 | config BLK_DEV_SX8 |
302 | tristate "Promise SATA SX8 support" | 318 | tristate "Promise SATA SX8 support" |
303 | depends on PCI | 319 | depends on PCI |
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 7755a5e2a85e..cdaa3f8fddf0 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_XILINX_SYSACE) += xsysace.o | |||
23 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o | 23 | obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o |
24 | obj-$(CONFIG_MG_DISK) += mg_disk.o | 24 | obj-$(CONFIG_MG_DISK) += mg_disk.o |
25 | obj-$(CONFIG_SUNVDC) += sunvdc.o | 25 | obj-$(CONFIG_SUNVDC) += sunvdc.o |
26 | obj-$(CONFIG_BLK_DEV_OSD) += osdblk.o | ||
26 | 27 | ||
27 | obj-$(CONFIG_BLK_DEV_UMEM) += umem.o | 28 | obj-$(CONFIG_BLK_DEV_UMEM) += umem.o |
28 | obj-$(CONFIG_BLK_DEV_NBD) += nbd.o | 29 | obj-$(CONFIG_BLK_DEV_NBD) += nbd.o |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 65a0655e7fc8..a52cc7fe45ea 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | #include <linux/major.h> | 31 | #include <linux/major.h> |
31 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 801f4ab83302..5757188cd1fb 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -61,7 +61,6 @@ | |||
61 | #include <linux/blkdev.h> | 61 | #include <linux/blkdev.h> |
62 | #include <linux/blkpg.h> | 62 | #include <linux/blkpg.h> |
63 | #include <linux/init.h> | 63 | #include <linux/init.h> |
64 | #include <linux/smp_lock.h> | ||
65 | #include <linux/swap.h> | 64 | #include <linux/swap.h> |
66 | #include <linux/slab.h> | 65 | #include <linux/slab.h> |
67 | #include <linux/loop.h> | 66 | #include <linux/loop.h> |
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c new file mode 100644 index 000000000000..13c1aee6aa3f --- /dev/null +++ b/drivers/block/osdblk.c | |||
@@ -0,0 +1,701 @@ | |||
1 | |||
2 | /* | ||
3 | osdblk.c -- Export a single SCSI OSD object as a Linux block device | ||
4 | |||
5 | |||
6 | Copyright 2009 Red Hat, Inc. | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; see the file COPYING. If not, write to | ||
19 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | |||
22 | Instructions for use | ||
23 | -------------------- | ||
24 | |||
25 | 1) Map a Linux block device to an existing OSD object. | ||
26 | |||
27 | In this example, we will use partition id 1234, object id 5678, | ||
28 | OSD device /dev/osd1. | ||
29 | |||
30 | $ echo "1234 5678 /dev/osd1" > /sys/class/osdblk/add | ||
31 | |||
32 | |||
33 | 2) List all active blkdev<->object mappings. | ||
34 | |||
35 | In this example, we have performed step #1 twice, creating two blkdevs, | ||
36 | mapped to two separate OSD objects. | ||
37 | |||
38 | $ cat /sys/class/osdblk/list | ||
39 | 0 174 1234 5678 /dev/osd1 | ||
40 | 1 179 1994 897123 /dev/osd0 | ||
41 | |||
42 | The columns, in order, are: | ||
43 | - blkdev unique id | ||
44 | - blkdev assigned major | ||
45 | - OSD object partition id | ||
46 | - OSD object id | ||
47 | - OSD device | ||
48 | |||
49 | |||
50 | 3) Remove an active blkdev<->object mapping. | ||
51 | |||
52 | In this example, we remove the mapping with blkdev unique id 1. | ||
53 | |||
54 | $ echo 1 > /sys/class/osdblk/remove | ||
55 | |||
56 | |||
57 | NOTE: The actual creation and deletion of OSD objects is outside the scope | ||
58 | of this driver. | ||
59 | |||
60 | */ | ||
61 | |||
62 | #include <linux/kernel.h> | ||
63 | #include <linux/device.h> | ||
64 | #include <linux/module.h> | ||
65 | #include <linux/fs.h> | ||
66 | #include <scsi/osd_initiator.h> | ||
67 | #include <scsi/osd_attributes.h> | ||
68 | #include <scsi/osd_sec.h> | ||
69 | #include <scsi/scsi_device.h> | ||
70 | |||
71 | #define DRV_NAME "osdblk" | ||
72 | #define PFX DRV_NAME ": " | ||
73 | |||
74 | /* #define _OSDBLK_DEBUG */ | ||
75 | #ifdef _OSDBLK_DEBUG | ||
76 | #define OSDBLK_DEBUG(fmt, a...) \ | ||
77 | printk(KERN_NOTICE "osdblk @%s:%d: " fmt, __func__, __LINE__, ##a) | ||
78 | #else | ||
79 | #define OSDBLK_DEBUG(fmt, a...) \ | ||
80 | do { if (0) printk(fmt, ##a); } while (0) | ||
81 | #endif | ||
82 | |||
83 | MODULE_AUTHOR("Jeff Garzik <jeff@garzik.org>"); | ||
84 | MODULE_DESCRIPTION("block device inside an OSD object osdblk.ko"); | ||
85 | MODULE_LICENSE("GPL"); | ||
86 | |||
87 | struct osdblk_device; | ||
88 | |||
89 | enum { | ||
90 | OSDBLK_MINORS_PER_MAJOR = 256, /* max minors per blkdev */ | ||
91 | OSDBLK_MAX_REQ = 32, /* max parallel requests */ | ||
92 | OSDBLK_OP_TIMEOUT = 4 * 60, /* sync OSD req timeout */ | ||
93 | }; | ||
94 | |||
95 | struct osdblk_request { | ||
96 | struct request *rq; /* blk layer request */ | ||
97 | struct bio *bio; /* cloned bio */ | ||
98 | struct osdblk_device *osdev; /* associated blkdev */ | ||
99 | }; | ||
100 | |||
101 | struct osdblk_device { | ||
102 | int id; /* blkdev unique id */ | ||
103 | |||
104 | int major; /* blkdev assigned major */ | ||
105 | struct gendisk *disk; /* blkdev's gendisk and rq */ | ||
106 | struct request_queue *q; | ||
107 | |||
108 | struct osd_dev *osd; /* associated OSD */ | ||
109 | |||
110 | char name[32]; /* blkdev name, e.g. osdblk34 */ | ||
111 | |||
112 | spinlock_t lock; /* queue lock */ | ||
113 | |||
114 | struct osd_obj_id obj; /* OSD partition, obj id */ | ||
115 | uint8_t obj_cred[OSD_CAP_LEN]; /* OSD cred */ | ||
116 | |||
117 | struct osdblk_request req[OSDBLK_MAX_REQ]; /* request table */ | ||
118 | |||
119 | struct list_head node; | ||
120 | |||
121 | char osd_path[0]; /* OSD device path */ | ||
122 | }; | ||
123 | |||
124 | static struct class *class_osdblk; /* /sys/class/osdblk */ | ||
125 | static DEFINE_MUTEX(ctl_mutex); /* Serialize open/close/setup/teardown */ | ||
126 | static LIST_HEAD(osdblkdev_list); | ||
127 | |||
128 | static struct block_device_operations osdblk_bd_ops = { | ||
129 | .owner = THIS_MODULE, | ||
130 | }; | ||
131 | |||
132 | static const struct osd_attr g_attr_logical_length = ATTR_DEF( | ||
133 | OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); | ||
134 | |||
135 | static void osdblk_make_credential(u8 cred_a[OSD_CAP_LEN], | ||
136 | const struct osd_obj_id *obj) | ||
137 | { | ||
138 | osd_sec_init_nosec_doall_caps(cred_a, obj, false, true); | ||
139 | } | ||
140 | |||
141 | /* copied from exofs; move to libosd? */ | ||
142 | /* | ||
143 | * Perform a synchronous OSD operation. copied from exofs; move to libosd? | ||
144 | */ | ||
145 | static int osd_sync_op(struct osd_request *or, int timeout, uint8_t *credential) | ||
146 | { | ||
147 | int ret; | ||
148 | |||
149 | or->timeout = timeout; | ||
150 | ret = osd_finalize_request(or, 0, credential, NULL); | ||
151 | if (ret) | ||
152 | return ret; | ||
153 | |||
154 | ret = osd_execute_request(or); | ||
155 | |||
156 | /* osd_req_decode_sense(or, ret); */ | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Perform an asynchronous OSD operation. copied from exofs; move to libosd? | ||
162 | */ | ||
163 | static int osd_async_op(struct osd_request *or, osd_req_done_fn *async_done, | ||
164 | void *caller_context, u8 *cred) | ||
165 | { | ||
166 | int ret; | ||
167 | |||
168 | ret = osd_finalize_request(or, 0, cred, NULL); | ||
169 | if (ret) | ||
170 | return ret; | ||
171 | |||
172 | ret = osd_execute_request_async(or, async_done, caller_context); | ||
173 | |||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | /* copied from exofs; move to libosd? */ | ||
178 | static int extract_attr_from_req(struct osd_request *or, struct osd_attr *attr) | ||
179 | { | ||
180 | struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */ | ||
181 | void *iter = NULL; | ||
182 | int nelem; | ||
183 | |||
184 | do { | ||
185 | nelem = 1; | ||
186 | osd_req_decode_get_attr_list(or, &cur_attr, &nelem, &iter); | ||
187 | if ((cur_attr.attr_page == attr->attr_page) && | ||
188 | (cur_attr.attr_id == attr->attr_id)) { | ||
189 | attr->len = cur_attr.len; | ||
190 | attr->val_ptr = cur_attr.val_ptr; | ||
191 | return 0; | ||
192 | } | ||
193 | } while (iter); | ||
194 | |||
195 | return -EIO; | ||
196 | } | ||
197 | |||
198 | static int osdblk_get_obj_size(struct osdblk_device *osdev, u64 *size_out) | ||
199 | { | ||
200 | struct osd_request *or; | ||
201 | struct osd_attr attr; | ||
202 | int ret; | ||
203 | |||
204 | /* start request */ | ||
205 | or = osd_start_request(osdev->osd, GFP_KERNEL); | ||
206 | if (!or) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | /* create a get-attributes(length) request */ | ||
210 | osd_req_get_attributes(or, &osdev->obj); | ||
211 | |||
212 | osd_req_add_get_attr_list(or, &g_attr_logical_length, 1); | ||
213 | |||
214 | /* execute op synchronously */ | ||
215 | ret = osd_sync_op(or, OSDBLK_OP_TIMEOUT, osdev->obj_cred); | ||
216 | if (ret) | ||
217 | goto out; | ||
218 | |||
219 | /* extract length from returned attribute info */ | ||
220 | attr = g_attr_logical_length; | ||
221 | ret = extract_attr_from_req(or, &attr); | ||
222 | if (ret) | ||
223 | goto out; | ||
224 | |||
225 | *size_out = get_unaligned_be64(attr.val_ptr); | ||
226 | |||
227 | out: | ||
228 | osd_end_request(or); | ||
229 | return ret; | ||
230 | |||
231 | } | ||
232 | |||
233 | static void osdblk_osd_complete(struct osd_request *or, void *private) | ||
234 | { | ||
235 | struct osdblk_request *orq = private; | ||
236 | struct osd_sense_info osi; | ||
237 | int ret = osd_req_decode_sense(or, &osi); | ||
238 | |||
239 | if (ret) { | ||
240 | ret = -EIO; | ||
241 | OSDBLK_DEBUG("osdblk_osd_complete with err=%d\n", ret); | ||
242 | } | ||
243 | |||
244 | /* complete OSD request */ | ||
245 | osd_end_request(or); | ||
246 | |||
247 | /* complete request passed to osdblk by block layer */ | ||
248 | __blk_end_request_all(orq->rq, ret); | ||
249 | } | ||
250 | |||
251 | static void bio_chain_put(struct bio *chain) | ||
252 | { | ||
253 | struct bio *tmp; | ||
254 | |||
255 | while (chain) { | ||
256 | tmp = chain; | ||
257 | chain = chain->bi_next; | ||
258 | |||
259 | bio_put(tmp); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | static struct bio *bio_chain_clone(struct bio *old_chain, gfp_t gfpmask) | ||
264 | { | ||
265 | struct bio *tmp, *new_chain = NULL, *tail = NULL; | ||
266 | |||
267 | while (old_chain) { | ||
268 | tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs); | ||
269 | if (!tmp) | ||
270 | goto err_out; | ||
271 | |||
272 | __bio_clone(tmp, old_chain); | ||
273 | tmp->bi_bdev = NULL; | ||
274 | gfpmask &= ~__GFP_WAIT; | ||
275 | tmp->bi_next = NULL; | ||
276 | |||
277 | if (!new_chain) | ||
278 | new_chain = tail = tmp; | ||
279 | else { | ||
280 | tail->bi_next = tmp; | ||
281 | tail = tmp; | ||
282 | } | ||
283 | |||
284 | old_chain = old_chain->bi_next; | ||
285 | } | ||
286 | |||
287 | return new_chain; | ||
288 | |||
289 | err_out: | ||
290 | OSDBLK_DEBUG("bio_chain_clone with err\n"); | ||
291 | bio_chain_put(new_chain); | ||
292 | return NULL; | ||
293 | } | ||
294 | |||
295 | static void osdblk_rq_fn(struct request_queue *q) | ||
296 | { | ||
297 | struct osdblk_device *osdev = q->queuedata; | ||
298 | |||
299 | while (1) { | ||
300 | struct request *rq; | ||
301 | struct osdblk_request *orq; | ||
302 | struct osd_request *or; | ||
303 | struct bio *bio; | ||
304 | bool do_write, do_flush; | ||
305 | |||
306 | /* peek at request from block layer */ | ||
307 | rq = blk_fetch_request(q); | ||
308 | if (!rq) | ||
309 | break; | ||
310 | |||
311 | /* filter out block requests we don't understand */ | ||
312 | if (!blk_fs_request(rq) && !blk_barrier_rq(rq)) { | ||
313 | blk_end_request_all(rq, 0); | ||
314 | continue; | ||
315 | } | ||
316 | |||
317 | /* deduce our operation (read, write, flush) */ | ||
318 | /* I wish the block layer simplified cmd_type/cmd_flags/cmd[] | ||
319 | * into a clearly defined set of RPC commands: | ||
320 | * read, write, flush, scsi command, power mgmt req, | ||
321 | * driver-specific, etc. | ||
322 | */ | ||
323 | |||
324 | do_flush = (rq->special == (void *) 0xdeadbeefUL); | ||
325 | do_write = (rq_data_dir(rq) == WRITE); | ||
326 | |||
327 | if (!do_flush) { /* osd_flush does not use a bio */ | ||
328 | /* a bio clone to be passed down to OSD request */ | ||
329 | bio = bio_chain_clone(rq->bio, GFP_ATOMIC); | ||
330 | if (!bio) | ||
331 | break; | ||
332 | } else | ||
333 | bio = NULL; | ||
334 | |||
335 | /* alloc internal OSD request, for OSD command execution */ | ||
336 | or = osd_start_request(osdev->osd, GFP_ATOMIC); | ||
337 | if (!or) { | ||
338 | bio_chain_put(bio); | ||
339 | OSDBLK_DEBUG("osd_start_request with err\n"); | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | orq = &osdev->req[rq->tag]; | ||
344 | orq->rq = rq; | ||
345 | orq->bio = bio; | ||
346 | orq->osdev = osdev; | ||
347 | |||
348 | /* init OSD command: flush, write or read */ | ||
349 | if (do_flush) | ||
350 | osd_req_flush_object(or, &osdev->obj, | ||
351 | OSD_CDB_FLUSH_ALL, 0, 0); | ||
352 | else if (do_write) | ||
353 | osd_req_write(or, &osdev->obj, blk_rq_pos(rq) * 512ULL, | ||
354 | bio, blk_rq_bytes(rq)); | ||
355 | else | ||
356 | osd_req_read(or, &osdev->obj, blk_rq_pos(rq) * 512ULL, | ||
357 | bio, blk_rq_bytes(rq)); | ||
358 | |||
359 | OSDBLK_DEBUG("%s 0x%x bytes at 0x%llx\n", | ||
360 | do_flush ? "flush" : do_write ? | ||
361 | "write" : "read", blk_rq_bytes(rq), | ||
362 | blk_rq_pos(rq) * 512ULL); | ||
363 | |||
364 | /* begin OSD command execution */ | ||
365 | if (osd_async_op(or, osdblk_osd_complete, orq, | ||
366 | osdev->obj_cred)) { | ||
367 | osd_end_request(or); | ||
368 | blk_requeue_request(q, rq); | ||
369 | bio_chain_put(bio); | ||
370 | OSDBLK_DEBUG("osd_execute_request_async with err\n"); | ||
371 | break; | ||
372 | } | ||
373 | |||
374 | /* remove the special 'flush' marker, now that the command | ||
375 | * is executing | ||
376 | */ | ||
377 | rq->special = NULL; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static void osdblk_prepare_flush(struct request_queue *q, struct request *rq) | ||
382 | { | ||
383 | /* add driver-specific marker, to indicate that this request | ||
384 | * is a flush command | ||
385 | */ | ||
386 | rq->special = (void *) 0xdeadbeefUL; | ||
387 | } | ||
388 | |||
389 | static void osdblk_free_disk(struct osdblk_device *osdev) | ||
390 | { | ||
391 | struct gendisk *disk = osdev->disk; | ||
392 | |||
393 | if (!disk) | ||
394 | return; | ||
395 | |||
396 | if (disk->flags & GENHD_FL_UP) | ||
397 | del_gendisk(disk); | ||
398 | if (disk->queue) | ||
399 | blk_cleanup_queue(disk->queue); | ||
400 | put_disk(disk); | ||
401 | } | ||
402 | |||
403 | static int osdblk_init_disk(struct osdblk_device *osdev) | ||
404 | { | ||
405 | struct gendisk *disk; | ||
406 | struct request_queue *q; | ||
407 | int rc; | ||
408 | u64 obj_size = 0; | ||
409 | |||
410 | /* contact OSD, request size info about the object being mapped */ | ||
411 | rc = osdblk_get_obj_size(osdev, &obj_size); | ||
412 | if (rc) | ||
413 | return rc; | ||
414 | |||
415 | /* create gendisk info */ | ||
416 | disk = alloc_disk(OSDBLK_MINORS_PER_MAJOR); | ||
417 | if (!disk) | ||
418 | return -ENOMEM; | ||
419 | |||
420 | sprintf(disk->disk_name, DRV_NAME "%d", osdev->id); | ||
421 | disk->major = osdev->major; | ||
422 | disk->first_minor = 0; | ||
423 | disk->fops = &osdblk_bd_ops; | ||
424 | disk->private_data = osdev; | ||
425 | |||
426 | /* init rq */ | ||
427 | q = blk_init_queue(osdblk_rq_fn, &osdev->lock); | ||
428 | if (!q) { | ||
429 | put_disk(disk); | ||
430 | return -ENOMEM; | ||
431 | } | ||
432 | |||
433 | /* switch queue to TCQ mode; allocate tag map */ | ||
434 | rc = blk_queue_init_tags(q, OSDBLK_MAX_REQ, NULL); | ||
435 | if (rc) { | ||
436 | blk_cleanup_queue(q); | ||
437 | put_disk(disk); | ||
438 | return rc; | ||
439 | } | ||
440 | |||
441 | /* Set our limits to the lower device limits, because osdblk cannot | ||
442 | * sleep when allocating a lower-request and therefore cannot be | ||
443 | * bouncing. | ||
444 | */ | ||
445 | blk_queue_stack_limits(q, osd_request_queue(osdev->osd)); | ||
446 | |||
447 | blk_queue_prep_rq(q, blk_queue_start_tag); | ||
448 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, osdblk_prepare_flush); | ||
449 | |||
450 | disk->queue = q; | ||
451 | |||
452 | q->queuedata = osdev; | ||
453 | |||
454 | osdev->disk = disk; | ||
455 | osdev->q = q; | ||
456 | |||
457 | /* finally, announce the disk to the world */ | ||
458 | set_capacity(disk, obj_size / 512ULL); | ||
459 | add_disk(disk); | ||
460 | |||
461 | printk(KERN_INFO "%s: Added of size 0x%llx\n", | ||
462 | disk->disk_name, (unsigned long long)obj_size); | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | /******************************************************************** | ||
468 | * /sys/class/osdblk/ | ||
469 | * add map OSD object to blkdev | ||
470 | * remove unmap OSD object | ||
471 | * list show mappings | ||
472 | *******************************************************************/ | ||
473 | |||
474 | static void class_osdblk_release(struct class *cls) | ||
475 | { | ||
476 | kfree(cls); | ||
477 | } | ||
478 | |||
479 | static ssize_t class_osdblk_list(struct class *c, char *data) | ||
480 | { | ||
481 | int n = 0; | ||
482 | struct list_head *tmp; | ||
483 | |||
484 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
485 | |||
486 | list_for_each(tmp, &osdblkdev_list) { | ||
487 | struct osdblk_device *osdev; | ||
488 | |||
489 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
490 | |||
491 | n += sprintf(data+n, "%d %d %llu %llu %s\n", | ||
492 | osdev->id, | ||
493 | osdev->major, | ||
494 | osdev->obj.partition, | ||
495 | osdev->obj.id, | ||
496 | osdev->osd_path); | ||
497 | } | ||
498 | |||
499 | mutex_unlock(&ctl_mutex); | ||
500 | return n; | ||
501 | } | ||
502 | |||
503 | static ssize_t class_osdblk_add(struct class *c, const char *buf, size_t count) | ||
504 | { | ||
505 | struct osdblk_device *osdev; | ||
506 | ssize_t rc; | ||
507 | int irc, new_id = 0; | ||
508 | struct list_head *tmp; | ||
509 | |||
510 | if (!try_module_get(THIS_MODULE)) | ||
511 | return -ENODEV; | ||
512 | |||
513 | /* new osdblk_device object */ | ||
514 | osdev = kzalloc(sizeof(*osdev) + strlen(buf) + 1, GFP_KERNEL); | ||
515 | if (!osdev) { | ||
516 | rc = -ENOMEM; | ||
517 | goto err_out_mod; | ||
518 | } | ||
519 | |||
520 | /* static osdblk_device initialization */ | ||
521 | spin_lock_init(&osdev->lock); | ||
522 | INIT_LIST_HEAD(&osdev->node); | ||
523 | |||
524 | /* generate unique id: find highest unique id, add one */ | ||
525 | |||
526 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
527 | |||
528 | list_for_each(tmp, &osdblkdev_list) { | ||
529 | struct osdblk_device *osdev; | ||
530 | |||
531 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
532 | if (osdev->id > new_id) | ||
533 | new_id = osdev->id + 1; | ||
534 | } | ||
535 | |||
536 | osdev->id = new_id; | ||
537 | |||
538 | /* add to global list */ | ||
539 | list_add_tail(&osdev->node, &osdblkdev_list); | ||
540 | |||
541 | mutex_unlock(&ctl_mutex); | ||
542 | |||
543 | /* parse add command */ | ||
544 | if (sscanf(buf, "%llu %llu %s", &osdev->obj.partition, &osdev->obj.id, | ||
545 | osdev->osd_path) != 3) { | ||
546 | rc = -EINVAL; | ||
547 | goto err_out_slot; | ||
548 | } | ||
549 | |||
550 | /* initialize rest of new object */ | ||
551 | sprintf(osdev->name, DRV_NAME "%d", osdev->id); | ||
552 | |||
553 | /* contact requested OSD */ | ||
554 | osdev->osd = osduld_path_lookup(osdev->osd_path); | ||
555 | if (IS_ERR(osdev->osd)) { | ||
556 | rc = PTR_ERR(osdev->osd); | ||
557 | goto err_out_slot; | ||
558 | } | ||
559 | |||
560 | /* build OSD credential */ | ||
561 | osdblk_make_credential(osdev->obj_cred, &osdev->obj); | ||
562 | |||
563 | /* register our block device */ | ||
564 | irc = register_blkdev(0, osdev->name); | ||
565 | if (irc < 0) { | ||
566 | rc = irc; | ||
567 | goto err_out_osd; | ||
568 | } | ||
569 | |||
570 | osdev->major = irc; | ||
571 | |||
572 | /* set up and announce blkdev mapping */ | ||
573 | rc = osdblk_init_disk(osdev); | ||
574 | if (rc) | ||
575 | goto err_out_blkdev; | ||
576 | |||
577 | return count; | ||
578 | |||
579 | err_out_blkdev: | ||
580 | unregister_blkdev(osdev->major, osdev->name); | ||
581 | err_out_osd: | ||
582 | osduld_put_device(osdev->osd); | ||
583 | err_out_slot: | ||
584 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
585 | list_del_init(&osdev->node); | ||
586 | mutex_unlock(&ctl_mutex); | ||
587 | |||
588 | kfree(osdev); | ||
589 | err_out_mod: | ||
590 | OSDBLK_DEBUG("Error adding device %s\n", buf); | ||
591 | module_put(THIS_MODULE); | ||
592 | return rc; | ||
593 | } | ||
594 | |||
595 | static ssize_t class_osdblk_remove(struct class *c, const char *buf, | ||
596 | size_t count) | ||
597 | { | ||
598 | struct osdblk_device *osdev = NULL; | ||
599 | int target_id, rc; | ||
600 | unsigned long ul; | ||
601 | struct list_head *tmp; | ||
602 | |||
603 | rc = strict_strtoul(buf, 10, &ul); | ||
604 | if (rc) | ||
605 | return rc; | ||
606 | |||
607 | /* convert to int; abort if we lost anything in the conversion */ | ||
608 | target_id = (int) ul; | ||
609 | if (target_id != ul) | ||
610 | return -EINVAL; | ||
611 | |||
612 | /* remove object from list immediately */ | ||
613 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
614 | |||
615 | list_for_each(tmp, &osdblkdev_list) { | ||
616 | osdev = list_entry(tmp, struct osdblk_device, node); | ||
617 | if (osdev->id == target_id) { | ||
618 | list_del_init(&osdev->node); | ||
619 | break; | ||
620 | } | ||
621 | osdev = NULL; | ||
622 | } | ||
623 | |||
624 | mutex_unlock(&ctl_mutex); | ||
625 | |||
626 | if (!osdev) | ||
627 | return -ENOENT; | ||
628 | |||
629 | /* clean up and free blkdev and associated OSD connection */ | ||
630 | osdblk_free_disk(osdev); | ||
631 | unregister_blkdev(osdev->major, osdev->name); | ||
632 | osduld_put_device(osdev->osd); | ||
633 | kfree(osdev); | ||
634 | |||
635 | /* release module ref */ | ||
636 | module_put(THIS_MODULE); | ||
637 | |||
638 | return count; | ||
639 | } | ||
640 | |||
641 | static struct class_attribute class_osdblk_attrs[] = { | ||
642 | __ATTR(add, 0200, NULL, class_osdblk_add), | ||
643 | __ATTR(remove, 0200, NULL, class_osdblk_remove), | ||
644 | __ATTR(list, 0444, class_osdblk_list, NULL), | ||
645 | __ATTR_NULL | ||
646 | }; | ||
647 | |||
648 | static int osdblk_sysfs_init(void) | ||
649 | { | ||
650 | int ret = 0; | ||
651 | |||
652 | /* | ||
653 | * create control files in sysfs | ||
654 | * /sys/class/osdblk/... | ||
655 | */ | ||
656 | class_osdblk = kzalloc(sizeof(*class_osdblk), GFP_KERNEL); | ||
657 | if (!class_osdblk) | ||
658 | return -ENOMEM; | ||
659 | |||
660 | class_osdblk->name = DRV_NAME; | ||
661 | class_osdblk->owner = THIS_MODULE; | ||
662 | class_osdblk->class_release = class_osdblk_release; | ||
663 | class_osdblk->class_attrs = class_osdblk_attrs; | ||
664 | |||
665 | ret = class_register(class_osdblk); | ||
666 | if (ret) { | ||
667 | kfree(class_osdblk); | ||
668 | class_osdblk = NULL; | ||
669 | printk(PFX "failed to create class osdblk\n"); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static void osdblk_sysfs_cleanup(void) | ||
677 | { | ||
678 | if (class_osdblk) | ||
679 | class_destroy(class_osdblk); | ||
680 | class_osdblk = NULL; | ||
681 | } | ||
682 | |||
683 | static int __init osdblk_init(void) | ||
684 | { | ||
685 | int rc; | ||
686 | |||
687 | rc = osdblk_sysfs_init(); | ||
688 | if (rc) | ||
689 | return rc; | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | static void __exit osdblk_exit(void) | ||
695 | { | ||
696 | osdblk_sysfs_cleanup(); | ||
697 | } | ||
698 | |||
699 | module_init(osdblk_init); | ||
700 | module_exit(osdblk_exit); | ||
701 | |||
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 024f2d292581..aa1a3d5a3e2b 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -213,7 +213,7 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | |||
213 | * Only allow the generic SCSI ioctls if the host can support it. | 213 | * Only allow the generic SCSI ioctls if the host can support it. |
214 | */ | 214 | */ |
215 | if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) | 215 | if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI)) |
216 | return -ENOIOCTLCMD; | 216 | return -ENOTTY; |
217 | 217 | ||
218 | return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); | 218 | return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp); |
219 | } | 219 | } |
@@ -360,6 +360,9 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
360 | blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2); | 360 | blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2); |
361 | blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2); | 361 | blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2); |
362 | 362 | ||
363 | /* No need to bounce any requests */ | ||
364 | blk_queue_bounce_limit(vblk->disk->queue, BLK_BOUNCE_ANY); | ||
365 | |||
363 | /* No real sector limit. */ | 366 | /* No real sector limit. */ |
364 | blk_queue_max_sectors(vblk->disk->queue, -1U); | 367 | blk_queue_max_sectors(vblk->disk->queue, -1U); |
365 | 368 | ||
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 1df9dda2e377..d5cde6d86f89 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/types.h> | 31 | #include <linux/types.h> |
33 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
34 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 72429b6b2fa8..6c32fbf07164 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -81,6 +81,7 @@ static char *serial_version = "4.30"; | |||
81 | #include <linux/mm.h> | 81 | #include <linux/mm.h> |
82 | #include <linux/seq_file.h> | 82 | #include <linux/seq_file.h> |
83 | #include <linux/slab.h> | 83 | #include <linux/slab.h> |
84 | #include <linux/smp_lock.h> | ||
84 | #include <linux/init.h> | 85 | #include <linux/init.h> |
85 | #include <linux/bitops.h> | 86 | #include <linux/bitops.h> |
86 | 87 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index f3366d3f06cf..2dafc2da0648 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -633,6 +633,7 @@ | |||
633 | #include <linux/tty.h> | 633 | #include <linux/tty.h> |
634 | #include <linux/tty_flip.h> | 634 | #include <linux/tty_flip.h> |
635 | #include <linux/serial.h> | 635 | #include <linux/serial.h> |
636 | #include <linux/smp_lock.h> | ||
636 | #include <linux/major.h> | 637 | #include <linux/major.h> |
637 | #include <linux/string.h> | 638 | #include <linux/string.h> |
638 | #include <linux/fcntl.h> | 639 | #include <linux/fcntl.h> |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index abef1f7d84fe..ff647ca1c489 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/tty.h> | 36 | #include <linux/tty.h> |
37 | #include <linux/tty_flip.h> | 37 | #include <linux/tty_flip.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/smp_lock.h> | ||
39 | #include <linux/ioport.h> | 40 | #include <linux/ioport.h> |
40 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
41 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 94e7e3c8c05a..d97779ef72cb 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -552,7 +552,7 @@ static int hvc_chars_in_buffer(struct tty_struct *tty) | |||
552 | struct hvc_struct *hp = tty->driver_data; | 552 | struct hvc_struct *hp = tty->driver_data; |
553 | 553 | ||
554 | if (!hp) | 554 | if (!hp) |
555 | return -1; | 555 | return 0; |
556 | return hp->n_outbuf; | 556 | return hp->n_outbuf; |
557 | } | 557 | } |
558 | 558 | ||
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 621d1184673c..4f1f4cd670da 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -122,6 +122,7 @@ | |||
122 | #include <linux/fs.h> | 122 | #include <linux/fs.h> |
123 | #include <linux/sched.h> | 123 | #include <linux/sched.h> |
124 | #include <linux/serial.h> | 124 | #include <linux/serial.h> |
125 | #include <linux/smp_lock.h> | ||
125 | #include <linux/mm.h> | 126 | #include <linux/mm.h> |
126 | #include <linux/interrupt.h> | 127 | #include <linux/interrupt.h> |
127 | #include <linux/timer.h> | 128 | #include <linux/timer.h> |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 0c999f5bb3db..ab2f3349c5c4 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/smp_lock.h> | ||
23 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
24 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
25 | #include <linux/tty_flip.h> | 26 | #include <linux/tty_flip.h> |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 65b6ff2442c6..dd0083bbb64a 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/tty.h> | 34 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 35 | #include <linux/tty_flip.h> |
36 | #include <linux/major.h> | 36 | #include <linux/major.h> |
37 | #include <linux/smp_lock.h> | ||
37 | #include <linux/string.h> | 38 | #include <linux/string.h> |
38 | #include <linux/fcntl.h> | 39 | #include <linux/fcntl.h> |
39 | #include <linux/ptrace.h> | 40 | #include <linux/ptrace.h> |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 52d953eb30c3..dbf8d52f31d0 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/signal.h> | 24 | #include <linux/signal.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/smp_lock.h> | ||
26 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
27 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
28 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index 1c43c8cdee25..c68118efad84 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c | |||
@@ -97,6 +97,7 @@ | |||
97 | #include <linux/slab.h> | 97 | #include <linux/slab.h> |
98 | #include <linux/tty.h> | 98 | #include <linux/tty.h> |
99 | #include <linux/errno.h> | 99 | #include <linux/errno.h> |
100 | #include <linux/smp_lock.h> | ||
100 | #include <linux/string.h> /* used in new tty drivers */ | 101 | #include <linux/string.h> /* used in new tty drivers */ |
101 | #include <linux/signal.h> /* used in new tty drivers */ | 102 | #include <linux/signal.h> /* used in new tty drivers */ |
102 | #include <linux/if.h> | 103 | #include <linux/if.h> |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 2e99158ebb8a..6934025a1ac1 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/ioport.h> | 58 | #include <linux/ioport.h> |
59 | #include <linux/in.h> | 59 | #include <linux/in.h> |
60 | #include <linux/slab.h> | 60 | #include <linux/slab.h> |
61 | #include <linux/smp_lock.h> | ||
61 | #include <linux/tty.h> | 62 | #include <linux/tty.h> |
62 | #include <linux/errno.h> | 63 | #include <linux/errno.h> |
63 | #include <linux/string.h> /* used in new tty drivers */ | 64 | #include <linux/string.h> /* used in new tty drivers */ |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 94a5d5020abc..ff47907ff1bf 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -1331,9 +1331,6 @@ handle_newline: | |||
1331 | 1331 | ||
1332 | static void n_tty_write_wakeup(struct tty_struct *tty) | 1332 | static void n_tty_write_wakeup(struct tty_struct *tty) |
1333 | { | 1333 | { |
1334 | /* Write out any echoed characters that are still pending */ | ||
1335 | process_echoes(tty); | ||
1336 | |||
1337 | if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) | 1334 | if (tty->fasync && test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) |
1338 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); | 1335 | kill_fasync(&tty->fasync, SIGIO, POLL_OUT); |
1339 | } | 1336 | } |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 574f1c79b6e6..ec58d8c387ff 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -828,7 +828,7 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
828 | struct port *port = &dc->port[index]; | 828 | struct port *port = &dc->port[index]; |
829 | void __iomem *addr = port->dl_addr[port->toggle_dl]; | 829 | void __iomem *addr = port->dl_addr[port->toggle_dl]; |
830 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 830 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
831 | int i; | 831 | int i, ret; |
832 | 832 | ||
833 | if (unlikely(!tty)) { | 833 | if (unlikely(!tty)) { |
834 | DBG1("tty not open for port: %d?", index); | 834 | DBG1("tty not open for port: %d?", index); |
@@ -844,12 +844,14 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
844 | 844 | ||
845 | /* disable interrupt in downlink... */ | 845 | /* disable interrupt in downlink... */ |
846 | disable_transmit_dl(index, dc); | 846 | disable_transmit_dl(index, dc); |
847 | return 0; | 847 | ret = 0; |
848 | goto put; | ||
848 | } | 849 | } |
849 | 850 | ||
850 | if (unlikely(size == 0)) { | 851 | if (unlikely(size == 0)) { |
851 | dev_err(&dc->pdev->dev, "size == 0?\n"); | 852 | dev_err(&dc->pdev->dev, "size == 0?\n"); |
852 | return 1; | 853 | ret = 1; |
854 | goto put; | ||
853 | } | 855 | } |
854 | 856 | ||
855 | tty_buffer_request_room(tty, size); | 857 | tty_buffer_request_room(tty, size); |
@@ -871,8 +873,10 @@ static int receive_data(enum port_type index, struct nozomi *dc) | |||
871 | } | 873 | } |
872 | 874 | ||
873 | set_bit(index, &dc->flip); | 875 | set_bit(index, &dc->flip); |
876 | ret = 1; | ||
877 | put: | ||
874 | tty_kref_put(tty); | 878 | tty_kref_put(tty); |
875 | return 1; | 879 | return ret; |
876 | } | 880 | } |
877 | 881 | ||
878 | /* Debug for interrupts */ | 882 | /* Debug for interrupts */ |
@@ -1862,16 +1866,14 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty) | |||
1862 | { | 1866 | { |
1863 | struct port *port = tty->driver_data; | 1867 | struct port *port = tty->driver_data; |
1864 | struct nozomi *dc = get_dc_by_tty(tty); | 1868 | struct nozomi *dc = get_dc_by_tty(tty); |
1865 | s32 rval; | 1869 | s32 rval = 0; |
1866 | 1870 | ||
1867 | if (unlikely(!dc || !port)) { | 1871 | if (unlikely(!dc || !port)) { |
1868 | rval = -ENODEV; | ||
1869 | goto exit_in_buffer; | 1872 | goto exit_in_buffer; |
1870 | } | 1873 | } |
1871 | 1874 | ||
1872 | if (unlikely(!port->port.count)) { | 1875 | if (unlikely(!port->port.count)) { |
1873 | dev_err(&dc->pdev->dev, "No tty open?\n"); | 1876 | dev_err(&dc->pdev->dev, "No tty open?\n"); |
1874 | rval = -ENODEV; | ||
1875 | goto exit_in_buffer; | 1877 | goto exit_in_buffer; |
1876 | } | 1878 | } |
1877 | 1879 | ||
diff --git a/drivers/char/pcmcia/ipwireless/tty.c b/drivers/char/pcmcia/ipwireless/tty.c index 569f2f7743a7..674b3ab3587d 100644 --- a/drivers/char/pcmcia/ipwireless/tty.c +++ b/drivers/char/pcmcia/ipwireless/tty.c | |||
@@ -320,10 +320,10 @@ static int ipw_chars_in_buffer(struct tty_struct *linux_tty) | |||
320 | struct ipw_tty *tty = linux_tty->driver_data; | 320 | struct ipw_tty *tty = linux_tty->driver_data; |
321 | 321 | ||
322 | if (!tty) | 322 | if (!tty) |
323 | return -ENODEV; | 323 | return 0; |
324 | 324 | ||
325 | if (!tty->open_count) | 325 | if (!tty->open_count) |
326 | return -EINVAL; | 326 | return 0; |
327 | 327 | ||
328 | return tty->tx_bytes_queued; | 328 | return tty->tx_bytes_queued; |
329 | } | 329 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 9d1b4f548f67..6e6942c45f5b 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/major.h> | 22 | #include <linux/major.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/sysctl.h> | 26 | #include <linux/sysctl.h> |
26 | #include <linux/device.h> | 27 | #include <linux/device.h> |
27 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index ce81da5b2da9..d58c2eb07f07 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
45 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/smp_lock.h> | ||
47 | #include <linux/miscdevice.h> | 48 | #include <linux/miscdevice.h> |
48 | #include <linux/init.h> | 49 | #include <linux/init.h> |
49 | 50 | ||
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 217660451237..171711acf5cd 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/tty_flip.h> | 49 | #include <linux/tty_flip.h> |
50 | #include <linux/smp_lock.h> | ||
50 | #include <linux/spinlock.h> | 51 | #include <linux/spinlock.h> |
51 | #include <linux/device.h> | 52 | #include <linux/device.h> |
52 | 53 | ||
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 63d5b628477a..0e29a23ec4c5 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #include <linux/tty_driver.h> | 73 | #include <linux/tty_driver.h> |
74 | #include <linux/tty_flip.h> | 74 | #include <linux/tty_flip.h> |
75 | #include <linux/serial.h> | 75 | #include <linux/serial.h> |
76 | #include <linux/smp_lock.h> | ||
76 | #include <linux/string.h> | 77 | #include <linux/string.h> |
77 | #include <linux/fcntl.h> | 78 | #include <linux/fcntl.h> |
78 | #include <linux/ptrace.h> | 79 | #include <linux/ptrace.h> |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index f1f24f0ee26f..51e7a46787be 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/interrupt.h> | 52 | #include <linux/interrupt.h> |
53 | #include <linux/serial.h> | 53 | #include <linux/serial.h> |
54 | #include <linux/serialP.h> | 54 | #include <linux/serialP.h> |
55 | #include <linux/smp_lock.h> | ||
55 | #include <linux/string.h> | 56 | #include <linux/string.h> |
56 | #include <linux/fcntl.h> | 57 | #include <linux/fcntl.h> |
57 | #include <linux/ptrace.h> | 58 | #include <linux/ptrace.h> |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index e72be4190a44..268e17f9ec3f 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -87,6 +87,7 @@ | |||
87 | #include <linux/tty_flip.h> | 87 | #include <linux/tty_flip.h> |
88 | #include <linux/mm.h> | 88 | #include <linux/mm.h> |
89 | #include <linux/serial.h> | 89 | #include <linux/serial.h> |
90 | #include <linux/smp_lock.h> | ||
90 | #include <linux/fcntl.h> | 91 | #include <linux/fcntl.h> |
91 | #include <linux/major.h> | 92 | #include <linux/major.h> |
92 | #include <linux/delay.h> | 93 | #include <linux/delay.h> |
@@ -1808,10 +1809,10 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, | |||
1808 | if (clear & TIOCM_DTR) | 1809 | if (clear & TIOCM_DTR) |
1809 | port->MSVR &= ~MSVR_DTR; | 1810 | port->MSVR &= ~MSVR_DTR; |
1810 | } | 1811 | } |
1811 | spin_lock_irqsave(&bp->lock, flags); | 1812 | spin_lock(&bp->lock); |
1812 | sx_out(bp, CD186x_CAR, port_No(port)); | 1813 | sx_out(bp, CD186x_CAR, port_No(port)); |
1813 | sx_out(bp, CD186x_MSVR, port->MSVR); | 1814 | sx_out(bp, CD186x_MSVR, port->MSVR); |
1814 | spin_unlock_irqrestore(&bp->lock, flags); | 1815 | spin_unlock(&bp->lock); |
1815 | spin_unlock_irqrestore(&port->lock, flags); | 1816 | spin_unlock_irqrestore(&port->lock, flags); |
1816 | func_exit(); | 1817 | func_exit(); |
1817 | return 0; | 1818 | return 0; |
@@ -1832,11 +1833,11 @@ static int sx_send_break(struct tty_struct *tty, int length) | |||
1832 | port->break_length = SPECIALIX_TPS / HZ * length; | 1833 | port->break_length = SPECIALIX_TPS / HZ * length; |
1833 | port->COR2 |= COR2_ETC; | 1834 | port->COR2 |= COR2_ETC; |
1834 | port->IER |= IER_TXRDY; | 1835 | port->IER |= IER_TXRDY; |
1835 | spin_lock_irqsave(&bp->lock, flags); | 1836 | spin_lock(&bp->lock); |
1836 | sx_out(bp, CD186x_CAR, port_No(port)); | 1837 | sx_out(bp, CD186x_CAR, port_No(port)); |
1837 | sx_out(bp, CD186x_COR2, port->COR2); | 1838 | sx_out(bp, CD186x_COR2, port->COR2); |
1838 | sx_out(bp, CD186x_IER, port->IER); | 1839 | sx_out(bp, CD186x_IER, port->IER); |
1839 | spin_unlock_irqrestore(&bp->lock, flags); | 1840 | spin_unlock(&bp->lock); |
1840 | spin_unlock_irqrestore(&port->lock, flags); | 1841 | spin_unlock_irqrestore(&port->lock, flags); |
1841 | sx_wait_CCR(bp); | 1842 | sx_wait_CCR(bp); |
1842 | spin_lock_irqsave(&bp->lock, flags); | 1843 | spin_lock_irqsave(&bp->lock, flags); |
@@ -2022,9 +2023,9 @@ static void sx_unthrottle(struct tty_struct *tty) | |||
2022 | if (sx_crtscts(tty)) | 2023 | if (sx_crtscts(tty)) |
2023 | port->MSVR |= MSVR_DTR; | 2024 | port->MSVR |= MSVR_DTR; |
2024 | /* Else clause: see remark in "sx_throttle"... */ | 2025 | /* Else clause: see remark in "sx_throttle"... */ |
2025 | spin_lock_irqsave(&bp->lock, flags); | 2026 | spin_lock(&bp->lock); |
2026 | sx_out(bp, CD186x_CAR, port_No(port)); | 2027 | sx_out(bp, CD186x_CAR, port_No(port)); |
2027 | spin_unlock_irqrestore(&bp->lock, flags); | 2028 | spin_unlock(&bp->lock); |
2028 | if (I_IXOFF(tty)) { | 2029 | if (I_IXOFF(tty)) { |
2029 | spin_unlock_irqrestore(&port->lock, flags); | 2030 | spin_unlock_irqrestore(&port->lock, flags); |
2030 | sx_wait_CCR(bp); | 2031 | sx_wait_CCR(bp); |
@@ -2034,9 +2035,9 @@ static void sx_unthrottle(struct tty_struct *tty) | |||
2034 | sx_wait_CCR(bp); | 2035 | sx_wait_CCR(bp); |
2035 | spin_lock_irqsave(&port->lock, flags); | 2036 | spin_lock_irqsave(&port->lock, flags); |
2036 | } | 2037 | } |
2037 | spin_lock_irqsave(&bp->lock, flags); | 2038 | spin_lock(&bp->lock); |
2038 | sx_out(bp, CD186x_MSVR, port->MSVR); | 2039 | sx_out(bp, CD186x_MSVR, port->MSVR); |
2039 | spin_unlock_irqrestore(&bp->lock, flags); | 2040 | spin_unlock(&bp->lock); |
2040 | spin_unlock_irqrestore(&port->lock, flags); | 2041 | spin_unlock_irqrestore(&port->lock, flags); |
2041 | 2042 | ||
2042 | func_exit(); | 2043 | func_exit(); |
@@ -2060,10 +2061,10 @@ static void sx_stop(struct tty_struct *tty) | |||
2060 | 2061 | ||
2061 | spin_lock_irqsave(&port->lock, flags); | 2062 | spin_lock_irqsave(&port->lock, flags); |
2062 | port->IER &= ~IER_TXRDY; | 2063 | port->IER &= ~IER_TXRDY; |
2063 | spin_lock_irqsave(&bp->lock, flags); | 2064 | spin_lock(&bp->lock); |
2064 | sx_out(bp, CD186x_CAR, port_No(port)); | 2065 | sx_out(bp, CD186x_CAR, port_No(port)); |
2065 | sx_out(bp, CD186x_IER, port->IER); | 2066 | sx_out(bp, CD186x_IER, port->IER); |
2066 | spin_unlock_irqrestore(&bp->lock, flags); | 2067 | spin_unlock(&bp->lock); |
2067 | spin_unlock_irqrestore(&port->lock, flags); | 2068 | spin_unlock_irqrestore(&port->lock, flags); |
2068 | 2069 | ||
2069 | func_exit(); | 2070 | func_exit(); |
@@ -2088,10 +2089,10 @@ static void sx_start(struct tty_struct *tty) | |||
2088 | spin_lock_irqsave(&port->lock, flags); | 2089 | spin_lock_irqsave(&port->lock, flags); |
2089 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { | 2090 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { |
2090 | port->IER |= IER_TXRDY; | 2091 | port->IER |= IER_TXRDY; |
2091 | spin_lock_irqsave(&bp->lock, flags); | 2092 | spin_lock(&bp->lock); |
2092 | sx_out(bp, CD186x_CAR, port_No(port)); | 2093 | sx_out(bp, CD186x_CAR, port_No(port)); |
2093 | sx_out(bp, CD186x_IER, port->IER); | 2094 | sx_out(bp, CD186x_IER, port->IER); |
2094 | spin_unlock_irqrestore(&bp->lock, flags); | 2095 | spin_unlock(&bp->lock); |
2095 | } | 2096 | } |
2096 | spin_unlock_irqrestore(&port->lock, flags); | 2097 | spin_unlock_irqrestore(&port->lock, flags); |
2097 | 2098 | ||
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 518f2a25d91e..a81ec4fcf6ff 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -216,6 +216,7 @@ | |||
216 | #include <linux/eisa.h> | 216 | #include <linux/eisa.h> |
217 | #include <linux/pci.h> | 217 | #include <linux/pci.h> |
218 | #include <linux/slab.h> | 218 | #include <linux/slab.h> |
219 | #include <linux/smp_lock.h> | ||
219 | #include <linux/init.h> | 220 | #include <linux/init.h> |
220 | #include <linux/miscdevice.h> | 221 | #include <linux/miscdevice.h> |
221 | #include <linux/bitops.h> | 222 | #include <linux/bitops.h> |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index afded3a2379c..813552f14884 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -81,6 +81,7 @@ | |||
81 | #include <linux/mm.h> | 81 | #include <linux/mm.h> |
82 | #include <linux/seq_file.h> | 82 | #include <linux/seq_file.h> |
83 | #include <linux/slab.h> | 83 | #include <linux/slab.h> |
84 | #include <linux/smp_lock.h> | ||
84 | #include <linux/delay.h> | 85 | #include <linux/delay.h> |
85 | #include <linux/netdevice.h> | 86 | #include <linux/netdevice.h> |
86 | #include <linux/vmalloc.h> | 87 | #include <linux/vmalloc.h> |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index a2e67e6df3a1..91f20a92fddf 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/mm.h> | 62 | #include <linux/mm.h> |
63 | #include <linux/seq_file.h> | 63 | #include <linux/seq_file.h> |
64 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
65 | #include <linux/smp_lock.h> | ||
65 | #include <linux/netdevice.h> | 66 | #include <linux/netdevice.h> |
66 | #include <linux/vmalloc.h> | 67 | #include <linux/vmalloc.h> |
67 | #include <linux/init.h> | 68 | #include <linux/init.h> |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 6f727e3c53ad..8d4a2a8a0a70 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/mm.h> | 52 | #include <linux/mm.h> |
53 | #include <linux/seq_file.h> | 53 | #include <linux/seq_file.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/smp_lock.h> | ||
55 | #include <linux/netdevice.h> | 56 | #include <linux/netdevice.h> |
56 | #include <linux/vmalloc.h> | 57 | #include <linux/vmalloc.h> |
57 | #include <linux/init.h> | 58 | #include <linux/init.h> |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index ccdd828adcef..b0603b2e5684 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/poll.h> | 26 | #include <linux/poll.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | #include <linux/smp_lock.h> | ||
30 | 29 | ||
31 | #include "tpm.h" | 30 | #include "tpm.h" |
32 | 31 | ||
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index b24f6c6a1ea3..ad6ba4ed2808 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/bitops.h> | 22 | #include <linux/bitops.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/smp_lock.h> | ||
25 | 24 | ||
26 | #include <asm/io.h> | 25 | #include <asm/io.h> |
27 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 913aa8d3f1c5..acd76b767d4c 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/smp_lock.h> | ||
25 | #include <linux/device.h> | 24 | #include <linux/device.h> |
26 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
27 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
@@ -791,17 +790,20 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
791 | * N_TTY. | 790 | * N_TTY. |
792 | */ | 791 | */ |
793 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 792 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { |
794 | /* Avoid racing set_ldisc */ | 793 | /* Avoid racing set_ldisc or tty_ldisc_release */ |
795 | mutex_lock(&tty->ldisc_mutex); | 794 | mutex_lock(&tty->ldisc_mutex); |
796 | /* Switch back to N_TTY */ | 795 | if (tty->ldisc) { /* Not yet closed */ |
797 | tty_ldisc_halt(tty); | 796 | /* Switch back to N_TTY */ |
798 | tty_ldisc_wait_idle(tty); | 797 | tty_ldisc_halt(tty); |
799 | tty_ldisc_reinit(tty); | 798 | tty_ldisc_wait_idle(tty); |
800 | /* At this point we have a closed ldisc and we want to | 799 | tty_ldisc_reinit(tty); |
801 | reopen it. We could defer this to the next open but | 800 | /* At this point we have a closed ldisc and we want to |
802 | it means auditing a lot of other paths so this is a FIXME */ | 801 | reopen it. We could defer this to the next open but |
803 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | 802 | it means auditing a lot of other paths so this is |
804 | tty_ldisc_enable(tty); | 803 | a FIXME */ |
804 | WARN_ON(tty_ldisc_open(tty, tty->ldisc)); | ||
805 | tty_ldisc_enable(tty); | ||
806 | } | ||
805 | mutex_unlock(&tty->ldisc_mutex); | 807 | mutex_unlock(&tty->ldisc_mutex); |
806 | tty_reset_termios(tty); | 808 | tty_reset_termios(tty); |
807 | } | 809 | } |
@@ -866,6 +868,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
866 | 868 | ||
867 | tty_ldisc_wait_idle(tty); | 869 | tty_ldisc_wait_idle(tty); |
868 | 870 | ||
871 | mutex_lock(&tty->ldisc_mutex); | ||
869 | /* | 872 | /* |
870 | * Now kill off the ldisc | 873 | * Now kill off the ldisc |
871 | */ | 874 | */ |
@@ -876,6 +879,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
876 | 879 | ||
877 | /* Ensure the next open requests the N_TTY ldisc */ | 880 | /* Ensure the next open requests the N_TTY ldisc */ |
878 | tty_set_termios_ldisc(tty, N_TTY); | 881 | tty_set_termios_ldisc(tty, N_TTY); |
882 | mutex_unlock(&tty->ldisc_mutex); | ||
879 | 883 | ||
880 | /* This will need doing differently if we need to lock */ | 884 | /* This will need doing differently if we need to lock */ |
881 | if (o_tty) | 885 | if (o_tty) |
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c index 4e862a75f7ff..9769b1149f76 100644 --- a/drivers/char/tty_port.c +++ b/drivers/char/tty_port.c | |||
@@ -267,7 +267,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
267 | if (retval == 0) | 267 | if (retval == 0) |
268 | port->flags |= ASYNC_NORMAL_ACTIVE; | 268 | port->flags |= ASYNC_NORMAL_ACTIVE; |
269 | spin_unlock_irqrestore(&port->lock, flags); | 269 | spin_unlock_irqrestore(&port->lock, flags); |
270 | return 0; | 270 | return retval; |
271 | 271 | ||
272 | } | 272 | } |
273 | EXPORT_SYMBOL(tty_port_block_til_ready); | 273 | EXPORT_SYMBOL(tty_port_block_til_ready); |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index d94d25c12aa8..c1791a63d99d 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -495,11 +495,15 @@ void vcs_remove_sysfs(int index) | |||
495 | 495 | ||
496 | int __init vcs_init(void) | 496 | int __init vcs_init(void) |
497 | { | 497 | { |
498 | unsigned int i; | ||
499 | |||
498 | if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) | 500 | if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) |
499 | panic("unable to get major %d for vcs device", VCS_MAJOR); | 501 | panic("unable to get major %d for vcs device", VCS_MAJOR); |
500 | vc_class = class_create(THIS_MODULE, "vc"); | 502 | vc_class = class_create(THIS_MODULE, "vc"); |
501 | 503 | ||
502 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); | 504 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); |
503 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); | 505 | device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); |
506 | for (i = 0; i < MIN_NR_CONSOLES; i++) | ||
507 | vcs_make_sysfs(i); | ||
504 | return 0; | 508 | return 0; |
505 | } | 509 | } |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index d9113b4c76e3..404f4c1ee431 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -89,6 +89,7 @@ | |||
89 | #include <linux/mutex.h> | 89 | #include <linux/mutex.h> |
90 | #include <linux/vt_kern.h> | 90 | #include <linux/vt_kern.h> |
91 | #include <linux/selection.h> | 91 | #include <linux/selection.h> |
92 | #include <linux/smp_lock.h> | ||
92 | #include <linux/tiocl.h> | 93 | #include <linux/tiocl.h> |
93 | #include <linux/kbd_kern.h> | 94 | #include <linux/kbd_kern.h> |
94 | #include <linux/consolemap.h> | 95 | #include <linux/consolemap.h> |
@@ -769,14 +770,12 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
769 | visual_init(vc, currcons, 1); | 770 | visual_init(vc, currcons, 1); |
770 | if (!*vc->vc_uni_pagedir_loc) | 771 | if (!*vc->vc_uni_pagedir_loc) |
771 | con_set_default_unimap(vc); | 772 | con_set_default_unimap(vc); |
772 | if (!vc->vc_kmalloced) | 773 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); |
773 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); | ||
774 | if (!vc->vc_screenbuf) { | 774 | if (!vc->vc_screenbuf) { |
775 | kfree(vc); | 775 | kfree(vc); |
776 | vc_cons[currcons].d = NULL; | 776 | vc_cons[currcons].d = NULL; |
777 | return -ENOMEM; | 777 | return -ENOMEM; |
778 | } | 778 | } |
779 | vc->vc_kmalloced = 1; | ||
780 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); | 779 | vc_init(vc, vc->vc_rows, vc->vc_cols, 1); |
781 | vcs_make_sysfs(currcons); | 780 | vcs_make_sysfs(currcons); |
782 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); | 781 | atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); |
@@ -912,10 +911,8 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
912 | if (new_scr_end > new_origin) | 911 | if (new_scr_end > new_origin) |
913 | scr_memsetw((void *)new_origin, vc->vc_video_erase_char, | 912 | scr_memsetw((void *)new_origin, vc->vc_video_erase_char, |
914 | new_scr_end - new_origin); | 913 | new_scr_end - new_origin); |
915 | if (vc->vc_kmalloced) | 914 | kfree(vc->vc_screenbuf); |
916 | kfree(vc->vc_screenbuf); | ||
917 | vc->vc_screenbuf = newscreen; | 915 | vc->vc_screenbuf = newscreen; |
918 | vc->vc_kmalloced = 1; | ||
919 | vc->vc_screenbuf_size = new_screen_size; | 916 | vc->vc_screenbuf_size = new_screen_size; |
920 | set_origin(vc); | 917 | set_origin(vc); |
921 | 918 | ||
@@ -994,8 +991,7 @@ void vc_deallocate(unsigned int currcons) | |||
994 | vc->vc_sw->con_deinit(vc); | 991 | vc->vc_sw->con_deinit(vc); |
995 | put_pid(vc->vt_pid); | 992 | put_pid(vc->vt_pid); |
996 | module_put(vc->vc_sw->owner); | 993 | module_put(vc->vc_sw->owner); |
997 | if (vc->vc_kmalloced) | 994 | kfree(vc->vc_screenbuf); |
998 | kfree(vc->vc_screenbuf); | ||
999 | if (currcons >= MIN_NR_CONSOLES) | 995 | if (currcons >= MIN_NR_CONSOLES) |
1000 | kfree(vc); | 996 | kfree(vc); |
1001 | vc_cons[currcons].d = NULL; | 997 | vc_cons[currcons].d = NULL; |
@@ -2880,7 +2876,6 @@ static int __init con_init(void) | |||
2880 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 2876 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
2881 | visual_init(vc, currcons, 1); | 2877 | visual_init(vc, currcons, 1); |
2882 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); | 2878 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); |
2883 | vc->vc_kmalloced = 0; | ||
2884 | vc_init(vc, vc->vc_rows, vc->vc_cols, | 2879 | vc_init(vc, vc->vc_rows, vc->vc_cols, |
2885 | currcons || !vc->vc_sw->con_save_screen); | 2880 | currcons || !vc->vc_sw->con_save_screen); |
2886 | } | 2881 | } |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 7539bed0f7e0..95189f288f8c 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/console.h> | 25 | #include <linux/console.h> |
26 | #include <linux/consolemap.h> | 26 | #include <linux/consolemap.h> |
27 | #include <linux/signal.h> | 27 | #include <linux/signal.h> |
28 | #include <linux/smp_lock.h> | ||
28 | #include <linux/timex.h> | 29 | #include <linux/timex.h> |
29 | 30 | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index c769ef269fb5..408c2af25d50 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * cn_queue.c | 2 | * cn_queue.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index fd336c5a9057..08b2500f21ec 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * connector.c | 2 | * connector.c |
3 | * | 3 | * |
4 | * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 4 | * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -33,7 +33,7 @@ | |||
33 | #include <net/sock.h> | 33 | #include <net/sock.h> |
34 | 34 | ||
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | 36 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
37 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); | 37 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); |
38 | 38 | ||
39 | static u32 cn_idx = CN_IDX_CONNECTOR; | 39 | static u32 cn_idx = CN_IDX_CONNECTOR; |
diff --git a/drivers/gpio/vr41xx_giu.c b/drivers/gpio/vr41xx_giu.c index b70e06133e78..b16c9a8c03f5 100644 --- a/drivers/gpio/vr41xx_giu.c +++ b/drivers/gpio/vr41xx_giu.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
34 | #include <linux/types.h> | 33 | #include <linux/types.h> |
35 | 34 | ||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a6f73f1e99d9..3da9cfa31848 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -1090,6 +1090,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev) | |||
1090 | if (ret == false) | 1090 | if (ret == false) |
1091 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); | 1091 | DRM_ERROR("failed to set mode on crtc %p\n", crtc); |
1092 | } | 1092 | } |
1093 | /* disable the unused connectors while restoring the modesetting */ | ||
1094 | drm_helper_disable_unused_functions(dev); | ||
1093 | return 0; | 1095 | return 0; |
1094 | } | 1096 | } |
1095 | EXPORT_SYMBOL(drm_helper_resume_force_mode); | 1097 | EXPORT_SYMBOL(drm_helper_resume_force_mode); |
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 2960b6d73456..9903f270e440 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
@@ -101,6 +101,10 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count, | |||
101 | continue; | 101 | continue; |
102 | 102 | ||
103 | tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); | 103 | tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); |
104 | if (tmp == NULL) { | ||
105 | ret = -1; | ||
106 | goto fail; | ||
107 | } | ||
104 | ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, | 108 | ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, |
105 | root, tmp, &drm_debugfs_fops); | 109 | root, tmp, &drm_debugfs_fops); |
106 | if (!ent) { | 110 | if (!ent) { |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 8104ecaea26f..ffe8f4394d50 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -134,26 +134,29 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) | |||
134 | BUG_ON((size & (PAGE_SIZE - 1)) != 0); | 134 | BUG_ON((size & (PAGE_SIZE - 1)) != 0); |
135 | 135 | ||
136 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); | 136 | obj = kzalloc(sizeof(*obj), GFP_KERNEL); |
137 | if (!obj) | ||
138 | goto free; | ||
137 | 139 | ||
138 | obj->dev = dev; | 140 | obj->dev = dev; |
139 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); | 141 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); |
140 | if (IS_ERR(obj->filp)) { | 142 | if (IS_ERR(obj->filp)) |
141 | kfree(obj); | 143 | goto free; |
142 | return NULL; | ||
143 | } | ||
144 | 144 | ||
145 | kref_init(&obj->refcount); | 145 | kref_init(&obj->refcount); |
146 | kref_init(&obj->handlecount); | 146 | kref_init(&obj->handlecount); |
147 | obj->size = size; | 147 | obj->size = size; |
148 | if (dev->driver->gem_init_object != NULL && | 148 | if (dev->driver->gem_init_object != NULL && |
149 | dev->driver->gem_init_object(obj) != 0) { | 149 | dev->driver->gem_init_object(obj) != 0) { |
150 | fput(obj->filp); | 150 | goto fput; |
151 | kfree(obj); | ||
152 | return NULL; | ||
153 | } | 151 | } |
154 | atomic_inc(&dev->object_count); | 152 | atomic_inc(&dev->object_count); |
155 | atomic_add(obj->size, &dev->object_memory); | 153 | atomic_add(obj->size, &dev->object_memory); |
156 | return obj; | 154 | return obj; |
155 | fput: | ||
156 | fput(obj->filp); | ||
157 | free: | ||
158 | kfree(obj); | ||
159 | return NULL; | ||
157 | } | 160 | } |
158 | EXPORT_SYMBOL(drm_gem_object_alloc); | 161 | EXPORT_SYMBOL(drm_gem_object_alloc); |
159 | 162 | ||
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 155a5bbce680..55bb8a82d612 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -489,7 +489,7 @@ int drm_put_minor(struct drm_minor **minor_p) | |||
489 | */ | 489 | */ |
490 | void drm_put_dev(struct drm_device *dev) | 490 | void drm_put_dev(struct drm_device *dev) |
491 | { | 491 | { |
492 | struct drm_driver *driver = dev->driver; | 492 | struct drm_driver *driver; |
493 | struct drm_map_list *r_list, *list_temp; | 493 | struct drm_map_list *r_list, *list_temp; |
494 | 494 | ||
495 | DRM_DEBUG("\n"); | 495 | DRM_DEBUG("\n"); |
@@ -498,6 +498,7 @@ void drm_put_dev(struct drm_device *dev) | |||
498 | DRM_ERROR("cleanup called no dev\n"); | 498 | DRM_ERROR("cleanup called no dev\n"); |
499 | return; | 499 | return; |
500 | } | 500 | } |
501 | driver = dev->driver; | ||
501 | 502 | ||
502 | drm_vblank_cleanup(dev); | 503 | drm_vblank_cleanup(dev); |
503 | 504 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f112c769d533..8c4783180bf6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -846,7 +846,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
846 | return 0; | 846 | return 0; |
847 | } | 847 | } |
848 | 848 | ||
849 | printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); | 849 | DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); |
850 | 850 | ||
851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); | 851 | dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); |
852 | 852 | ||
@@ -885,8 +885,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data, | |||
885 | * some RAM for the framebuffer at early boot. This code figures out | 885 | * some RAM for the framebuffer at early boot. This code figures out |
886 | * how much was set aside so we can use it for our own purposes. | 886 | * how much was set aside so we can use it for our own purposes. |
887 | */ | 887 | */ |
888 | static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | 888 | static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, |
889 | unsigned long *preallocated_size) | 889 | uint32_t *preallocated_size) |
890 | { | 890 | { |
891 | struct pci_dev *bridge_dev; | 891 | struct pci_dev *bridge_dev; |
892 | u16 tmp = 0; | 892 | u16 tmp = 0; |
@@ -984,10 +984,11 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size, | |||
984 | return 0; | 984 | return 0; |
985 | } | 985 | } |
986 | 986 | ||
987 | static int i915_load_modeset_init(struct drm_device *dev) | 987 | static int i915_load_modeset_init(struct drm_device *dev, |
988 | unsigned long prealloc_size, | ||
989 | unsigned long agp_size) | ||
988 | { | 990 | { |
989 | struct drm_i915_private *dev_priv = dev->dev_private; | 991 | struct drm_i915_private *dev_priv = dev->dev_private; |
990 | unsigned long agp_size, prealloc_size; | ||
991 | int fb_bar = IS_I9XX(dev) ? 2 : 0; | 992 | int fb_bar = IS_I9XX(dev) ? 2 : 0; |
992 | int ret = 0; | 993 | int ret = 0; |
993 | 994 | ||
@@ -1002,10 +1003,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1002 | if (IS_I965G(dev) || IS_G33(dev)) | 1003 | if (IS_I965G(dev) || IS_G33(dev)) |
1003 | dev_priv->cursor_needs_physical = false; | 1004 | dev_priv->cursor_needs_physical = false; |
1004 | 1005 | ||
1005 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1006 | if (ret) | ||
1007 | goto out; | ||
1008 | |||
1009 | /* Basic memrange allocator for stolen space (aka vram) */ | 1006 | /* Basic memrange allocator for stolen space (aka vram) */ |
1010 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); | 1007 | drm_mm_init(&dev_priv->vram, 0, prealloc_size); |
1011 | 1008 | ||
@@ -1082,6 +1079,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) | |||
1082 | master->driver_priv = NULL; | 1079 | master->driver_priv = NULL; |
1083 | } | 1080 | } |
1084 | 1081 | ||
1082 | static void i915_get_mem_freq(struct drm_device *dev) | ||
1083 | { | ||
1084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1085 | u32 tmp; | ||
1086 | |||
1087 | if (!IS_IGD(dev)) | ||
1088 | return; | ||
1089 | |||
1090 | tmp = I915_READ(CLKCFG); | ||
1091 | |||
1092 | switch (tmp & CLKCFG_FSB_MASK) { | ||
1093 | case CLKCFG_FSB_533: | ||
1094 | dev_priv->fsb_freq = 533; /* 133*4 */ | ||
1095 | break; | ||
1096 | case CLKCFG_FSB_800: | ||
1097 | dev_priv->fsb_freq = 800; /* 200*4 */ | ||
1098 | break; | ||
1099 | case CLKCFG_FSB_667: | ||
1100 | dev_priv->fsb_freq = 667; /* 167*4 */ | ||
1101 | break; | ||
1102 | case CLKCFG_FSB_400: | ||
1103 | dev_priv->fsb_freq = 400; /* 100*4 */ | ||
1104 | break; | ||
1105 | } | ||
1106 | |||
1107 | switch (tmp & CLKCFG_MEM_MASK) { | ||
1108 | case CLKCFG_MEM_533: | ||
1109 | dev_priv->mem_freq = 533; | ||
1110 | break; | ||
1111 | case CLKCFG_MEM_667: | ||
1112 | dev_priv->mem_freq = 667; | ||
1113 | break; | ||
1114 | case CLKCFG_MEM_800: | ||
1115 | dev_priv->mem_freq = 800; | ||
1116 | break; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1085 | /** | 1120 | /** |
1086 | * i915_driver_load - setup chip and create an initial config | 1121 | * i915_driver_load - setup chip and create an initial config |
1087 | * @dev: DRM device | 1122 | * @dev: DRM device |
@@ -1098,6 +1133,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1098 | struct drm_i915_private *dev_priv = dev->dev_private; | 1133 | struct drm_i915_private *dev_priv = dev->dev_private; |
1099 | resource_size_t base, size; | 1134 | resource_size_t base, size; |
1100 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; | 1135 | int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; |
1136 | uint32_t agp_size, prealloc_size; | ||
1101 | 1137 | ||
1102 | /* i915 has 4 more counters */ | 1138 | /* i915 has 4 more counters */ |
1103 | dev->counters += 4; | 1139 | dev->counters += 4; |
@@ -1146,9 +1182,22 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1146 | "performance may suffer.\n"); | 1182 | "performance may suffer.\n"); |
1147 | } | 1183 | } |
1148 | 1184 | ||
1185 | ret = i915_probe_agp(dev, &agp_size, &prealloc_size); | ||
1186 | if (ret) | ||
1187 | goto out_iomapfree; | ||
1188 | |||
1149 | /* enable GEM by default */ | 1189 | /* enable GEM by default */ |
1150 | dev_priv->has_gem = 1; | 1190 | dev_priv->has_gem = 1; |
1151 | 1191 | ||
1192 | if (prealloc_size > agp_size * 3 / 4) { | ||
1193 | DRM_ERROR("Detected broken video BIOS with %d/%dkB of video " | ||
1194 | "memory stolen.\n", | ||
1195 | prealloc_size / 1024, agp_size / 1024); | ||
1196 | DRM_ERROR("Disabling GEM. (try reducing stolen memory or " | ||
1197 | "updating the BIOS to fix).\n"); | ||
1198 | dev_priv->has_gem = 0; | ||
1199 | } | ||
1200 | |||
1152 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1201 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
1153 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 1202 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
1154 | if (IS_G4X(dev) || IS_IGDNG(dev)) { | 1203 | if (IS_G4X(dev) || IS_IGDNG(dev)) { |
@@ -1165,6 +1214,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1165 | goto out_iomapfree; | 1214 | goto out_iomapfree; |
1166 | } | 1215 | } |
1167 | 1216 | ||
1217 | i915_get_mem_freq(dev); | ||
1218 | |||
1168 | /* On the 945G/GM, the chipset reports the MSI capability on the | 1219 | /* On the 945G/GM, the chipset reports the MSI capability on the |
1169 | * integrated graphics even though the support isn't actually there | 1220 | * integrated graphics even though the support isn't actually there |
1170 | * according to the published specs. It doesn't appear to function | 1221 | * according to the published specs. It doesn't appear to function |
@@ -1180,6 +1231,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1180 | pci_enable_msi(dev->pdev); | 1231 | pci_enable_msi(dev->pdev); |
1181 | 1232 | ||
1182 | spin_lock_init(&dev_priv->user_irq_lock); | 1233 | spin_lock_init(&dev_priv->user_irq_lock); |
1234 | spin_lock_init(&dev_priv->error_lock); | ||
1183 | dev_priv->user_irq_refcount = 0; | 1235 | dev_priv->user_irq_refcount = 0; |
1184 | 1236 | ||
1185 | ret = drm_vblank_init(dev, I915_NUM_PIPE); | 1237 | ret = drm_vblank_init(dev, I915_NUM_PIPE); |
@@ -1190,7 +1242,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1190 | } | 1242 | } |
1191 | 1243 | ||
1192 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 1244 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
1193 | ret = i915_load_modeset_init(dev); | 1245 | ret = i915_load_modeset_init(dev, prealloc_size, agp_size); |
1194 | if (ret < 0) { | 1246 | if (ret < 0) { |
1195 | DRM_ERROR("failed to init modeset\n"); | 1247 | DRM_ERROR("failed to init modeset\n"); |
1196 | goto out_rmmap; | 1248 | goto out_rmmap; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index e3cb4025e323..fc4b68aa2d05 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "drm_pciids.h" | 36 | #include "drm_pciids.h" |
37 | #include <linux/console.h> | 37 | #include <linux/console.h> |
38 | #include "drm_crtc_helper.h" | ||
38 | 39 | ||
39 | static unsigned int i915_modeset = -1; | 40 | static unsigned int i915_modeset = -1; |
40 | module_param_named(modeset, i915_modeset, int, 0400); | 41 | module_param_named(modeset, i915_modeset, int, 0400); |
@@ -57,8 +58,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
57 | struct drm_i915_private *dev_priv = dev->dev_private; | 58 | struct drm_i915_private *dev_priv = dev->dev_private; |
58 | 59 | ||
59 | if (!dev || !dev_priv) { | 60 | if (!dev || !dev_priv) { |
60 | printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv); | 61 | DRM_ERROR("dev: %p, dev_priv: %p\n", dev, dev_priv); |
61 | printk(KERN_ERR "DRM not initialized, aborting suspend.\n"); | 62 | DRM_ERROR("DRM not initialized, aborting suspend.\n"); |
62 | return -ENODEV; | 63 | return -ENODEV; |
63 | } | 64 | } |
64 | 65 | ||
@@ -115,6 +116,10 @@ static int i915_resume(struct drm_device *dev) | |||
115 | 116 | ||
116 | drm_irq_install(dev); | 117 | drm_irq_install(dev); |
117 | } | 118 | } |
119 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
120 | /* Resume the modeset for every activated CRTC */ | ||
121 | drm_helper_resume_force_mode(dev); | ||
122 | } | ||
118 | 123 | ||
119 | return ret; | 124 | return ret; |
120 | } | 125 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bb4c2d387b6c..d08752875885 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -133,6 +133,22 @@ struct sdvo_device_mapping { | |||
133 | u8 initialized; | 133 | u8 initialized; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | struct drm_i915_error_state { | ||
137 | u32 eir; | ||
138 | u32 pgtbl_er; | ||
139 | u32 pipeastat; | ||
140 | u32 pipebstat; | ||
141 | u32 ipeir; | ||
142 | u32 ipehr; | ||
143 | u32 instdone; | ||
144 | u32 acthd; | ||
145 | u32 instpm; | ||
146 | u32 instps; | ||
147 | u32 instdone1; | ||
148 | u32 seqno; | ||
149 | struct timeval time; | ||
150 | }; | ||
151 | |||
136 | typedef struct drm_i915_private { | 152 | typedef struct drm_i915_private { |
137 | struct drm_device *dev; | 153 | struct drm_device *dev; |
138 | 154 | ||
@@ -209,6 +225,11 @@ typedef struct drm_i915_private { | |||
209 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 225 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
210 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ | 226 | int num_fence_regs; /* 8 on pre-965, 16 otherwise */ |
211 | 227 | ||
228 | unsigned int fsb_freq, mem_freq; | ||
229 | |||
230 | spinlock_t error_lock; | ||
231 | struct drm_i915_error_state *first_error; | ||
232 | |||
212 | /* Register state */ | 233 | /* Register state */ |
213 | u8 saveLBB; | 234 | u8 saveLBB; |
214 | u32 saveDSPACNTR; | 235 | u32 saveDSPACNTR; |
@@ -468,9 +489,6 @@ struct drm_i915_gem_object { | |||
468 | */ | 489 | */ |
469 | int fence_reg; | 490 | int fence_reg; |
470 | 491 | ||
471 | /** Boolean whether this object has a valid gtt offset. */ | ||
472 | int gtt_bound; | ||
473 | |||
474 | /** How many users have pinned this object in GTT space */ | 492 | /** How many users have pinned this object in GTT space */ |
475 | int pin_count; | 493 | int pin_count; |
476 | 494 | ||
@@ -655,6 +673,7 @@ void i915_gem_free_object(struct drm_gem_object *obj); | |||
655 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); | 673 | int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); |
656 | void i915_gem_object_unpin(struct drm_gem_object *obj); | 674 | void i915_gem_object_unpin(struct drm_gem_object *obj); |
657 | int i915_gem_object_unbind(struct drm_gem_object *obj); | 675 | int i915_gem_object_unbind(struct drm_gem_object *obj); |
676 | void i915_gem_release_mmap(struct drm_gem_object *obj); | ||
658 | void i915_gem_lastclose(struct drm_device *dev); | 677 | void i915_gem_lastclose(struct drm_device *dev); |
659 | uint32_t i915_get_gem_seqno(struct drm_device *dev); | 678 | uint32_t i915_get_gem_seqno(struct drm_device *dev); |
660 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | 679 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); |
@@ -870,6 +889,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
870 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 889 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
871 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 890 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
872 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | 891 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) |
892 | /* dsparb controlled by hw only */ | ||
893 | #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
873 | 894 | ||
874 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 895 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
875 | 896 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 876b65cb7629..5bf420378b6d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1252,6 +1252,31 @@ out_free_list: | |||
1252 | return ret; | 1252 | return ret; |
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | /** | ||
1256 | * i915_gem_release_mmap - remove physical page mappings | ||
1257 | * @obj: obj in question | ||
1258 | * | ||
1259 | * Preserve the reservation of the mmaping with the DRM core code, but | ||
1260 | * relinquish ownership of the pages back to the system. | ||
1261 | * | ||
1262 | * It is vital that we remove the page mapping if we have mapped a tiled | ||
1263 | * object through the GTT and then lose the fence register due to | ||
1264 | * resource pressure. Similarly if the object has been moved out of the | ||
1265 | * aperture, than pages mapped into userspace must be revoked. Removing the | ||
1266 | * mapping will then trigger a page fault on the next user access, allowing | ||
1267 | * fixup by i915_gem_fault(). | ||
1268 | */ | ||
1269 | void | ||
1270 | i915_gem_release_mmap(struct drm_gem_object *obj) | ||
1271 | { | ||
1272 | struct drm_device *dev = obj->dev; | ||
1273 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
1274 | |||
1275 | if (dev->dev_mapping) | ||
1276 | unmap_mapping_range(dev->dev_mapping, | ||
1277 | obj_priv->mmap_offset, obj->size, 1); | ||
1278 | } | ||
1279 | |||
1255 | static void | 1280 | static void |
1256 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) | 1281 | i915_gem_free_mmap_offset(struct drm_gem_object *obj) |
1257 | { | 1282 | { |
@@ -1861,7 +1886,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1861 | { | 1886 | { |
1862 | struct drm_device *dev = obj->dev; | 1887 | struct drm_device *dev = obj->dev; |
1863 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | 1888 | struct drm_i915_gem_object *obj_priv = obj->driver_private; |
1864 | loff_t offset; | ||
1865 | int ret = 0; | 1889 | int ret = 0; |
1866 | 1890 | ||
1867 | #if WATCH_BUF | 1891 | #if WATCH_BUF |
@@ -1898,9 +1922,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1898 | BUG_ON(obj_priv->active); | 1922 | BUG_ON(obj_priv->active); |
1899 | 1923 | ||
1900 | /* blow away mappings if mapped through GTT */ | 1924 | /* blow away mappings if mapped through GTT */ |
1901 | offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT; | 1925 | i915_gem_release_mmap(obj); |
1902 | if (dev->dev_mapping) | ||
1903 | unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1); | ||
1904 | 1926 | ||
1905 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1927 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
1906 | i915_gem_clear_fence_reg(obj); | 1928 | i915_gem_clear_fence_reg(obj); |
@@ -2222,7 +2244,6 @@ try_again: | |||
2222 | /* None available, try to steal one or wait for a user to finish */ | 2244 | /* None available, try to steal one or wait for a user to finish */ |
2223 | if (i == dev_priv->num_fence_regs) { | 2245 | if (i == dev_priv->num_fence_regs) { |
2224 | uint32_t seqno = dev_priv->mm.next_gem_seqno; | 2246 | uint32_t seqno = dev_priv->mm.next_gem_seqno; |
2225 | loff_t offset; | ||
2226 | 2247 | ||
2227 | if (avail == 0) | 2248 | if (avail == 0) |
2228 | return -ENOSPC; | 2249 | return -ENOSPC; |
@@ -2274,10 +2295,7 @@ try_again: | |||
2274 | * Zap this virtual mapping so we can set up a fence again | 2295 | * Zap this virtual mapping so we can set up a fence again |
2275 | * for this object next time we need it. | 2296 | * for this object next time we need it. |
2276 | */ | 2297 | */ |
2277 | offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT; | 2298 | i915_gem_release_mmap(reg->obj); |
2278 | if (dev->dev_mapping) | ||
2279 | unmap_mapping_range(dev->dev_mapping, offset, | ||
2280 | reg->obj->size, 1); | ||
2281 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; | 2299 | old_obj_priv->fence_reg = I915_FENCE_REG_NONE; |
2282 | } | 2300 | } |
2283 | 2301 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c index 28146e405e87..9a44bfcb8139 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
@@ -75,11 +75,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
75 | case ACTIVE_LIST: | 75 | case ACTIVE_LIST: |
76 | seq_printf(m, "Active:\n"); | 76 | seq_printf(m, "Active:\n"); |
77 | lock = &dev_priv->mm.active_list_lock; | 77 | lock = &dev_priv->mm.active_list_lock; |
78 | spin_lock(lock); | ||
79 | head = &dev_priv->mm.active_list; | 78 | head = &dev_priv->mm.active_list; |
80 | break; | 79 | break; |
81 | case INACTIVE_LIST: | 80 | case INACTIVE_LIST: |
82 | seq_printf(m, "Inctive:\n"); | 81 | seq_printf(m, "Inactive:\n"); |
83 | head = &dev_priv->mm.inactive_list; | 82 | head = &dev_priv->mm.inactive_list; |
84 | break; | 83 | break; |
85 | case FLUSHING_LIST: | 84 | case FLUSHING_LIST: |
@@ -91,6 +90,8 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
91 | return 0; | 90 | return 0; |
92 | } | 91 | } |
93 | 92 | ||
93 | if (lock) | ||
94 | spin_lock(lock); | ||
94 | list_for_each_entry(obj_priv, head, list) | 95 | list_for_each_entry(obj_priv, head, list) |
95 | { | 96 | { |
96 | struct drm_gem_object *obj = obj_priv->obj; | 97 | struct drm_gem_object *obj = obj_priv->obj; |
@@ -104,7 +105,10 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
104 | if (obj->name) | 105 | if (obj->name) |
105 | seq_printf(m, " (name: %d)", obj->name); | 106 | seq_printf(m, " (name: %d)", obj->name); |
106 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 107 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
107 | seq_printf(m, " (fence: %d)\n", obj_priv->fence_reg); | 108 | seq_printf(m, " (fence: %d)", obj_priv->fence_reg); |
109 | if (obj_priv->gtt_space != NULL) | ||
110 | seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); | ||
111 | |||
108 | seq_printf(m, "\n"); | 112 | seq_printf(m, "\n"); |
109 | } | 113 | } |
110 | 114 | ||
@@ -323,6 +327,39 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
323 | return 0; | 327 | return 0; |
324 | } | 328 | } |
325 | 329 | ||
330 | static int i915_error_state(struct seq_file *m, void *unused) | ||
331 | { | ||
332 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
333 | struct drm_device *dev = node->minor->dev; | ||
334 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
335 | struct drm_i915_error_state *error; | ||
336 | unsigned long flags; | ||
337 | |||
338 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
339 | if (!dev_priv->first_error) { | ||
340 | seq_printf(m, "no error state collected\n"); | ||
341 | goto out; | ||
342 | } | ||
343 | |||
344 | error = dev_priv->first_error; | ||
345 | |||
346 | seq_printf(m, "EIR: 0x%08x\n", error->eir); | ||
347 | seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); | ||
348 | seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); | ||
349 | seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); | ||
350 | seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); | ||
351 | seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); | ||
352 | seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); | ||
353 | if (IS_I965G(dev)) { | ||
354 | seq_printf(m, " INSTPS: 0x%08x\n", error->instps); | ||
355 | seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); | ||
356 | } | ||
357 | |||
358 | out: | ||
359 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
360 | |||
361 | return 0; | ||
362 | } | ||
326 | 363 | ||
327 | static struct drm_info_list i915_gem_debugfs_list[] = { | 364 | static struct drm_info_list i915_gem_debugfs_list[] = { |
328 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, | 365 | {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, |
@@ -336,6 +373,7 @@ static struct drm_info_list i915_gem_debugfs_list[] = { | |||
336 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, | 373 | {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, |
337 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, | 374 | {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, |
338 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, | 375 | {"i915_batchbuffers", i915_batchbuffer_info, 0}, |
376 | {"i915_error_state", i915_error_state, 0}, | ||
339 | }; | 377 | }; |
340 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) | 378 | #define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) |
341 | 379 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index daeae62e1c28..a2d527b22ec4 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -521,6 +521,12 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
521 | goto err; | 521 | goto err; |
522 | } | 522 | } |
523 | 523 | ||
524 | /* If we've changed tiling, GTT-mappings of the object | ||
525 | * need to re-fault to ensure that the correct fence register | ||
526 | * setup is in place. | ||
527 | */ | ||
528 | i915_gem_release_mmap(obj); | ||
529 | |||
524 | obj_priv->tiling_mode = args->tiling_mode; | 530 | obj_priv->tiling_mode = args->tiling_mode; |
525 | obj_priv->stride = args->stride; | 531 | obj_priv->stride = args->stride; |
526 | } | 532 | } |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 228546f6eaa4..7ba23a69a0c0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -26,6 +26,7 @@ | |||
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/sysrq.h> | ||
29 | #include "drmP.h" | 30 | #include "drmP.h" |
30 | #include "drm.h" | 31 | #include "drm.h" |
31 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -41,9 +42,10 @@ | |||
41 | * we leave them always unmasked in IMR and then control enabling them through | 42 | * we leave them always unmasked in IMR and then control enabling them through |
42 | * PIPESTAT alone. | 43 | * PIPESTAT alone. |
43 | */ | 44 | */ |
44 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ | 45 | #define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \ |
45 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ | 46 | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \ |
46 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) | 47 | I915_DISPLAY_PIPE_B_EVENT_INTERRUPT | \ |
48 | I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) | ||
47 | 49 | ||
48 | /** Interrupts that we mask and unmask at runtime. */ | 50 | /** Interrupts that we mask and unmask at runtime. */ |
49 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) | 51 | #define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT) |
@@ -288,6 +290,47 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
288 | return ret; | 290 | return ret; |
289 | } | 291 | } |
290 | 292 | ||
293 | static void i915_capture_error_state(struct drm_device *dev) | ||
294 | { | ||
295 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
296 | struct drm_i915_error_state *error; | ||
297 | unsigned long flags; | ||
298 | |||
299 | spin_lock_irqsave(&dev_priv->error_lock, flags); | ||
300 | if (dev_priv->first_error) | ||
301 | goto out; | ||
302 | |||
303 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
304 | if (!error) { | ||
305 | DRM_DEBUG("out ot memory, not capturing error state\n"); | ||
306 | goto out; | ||
307 | } | ||
308 | |||
309 | error->eir = I915_READ(EIR); | ||
310 | error->pgtbl_er = I915_READ(PGTBL_ER); | ||
311 | error->pipeastat = I915_READ(PIPEASTAT); | ||
312 | error->pipebstat = I915_READ(PIPEBSTAT); | ||
313 | error->instpm = I915_READ(INSTPM); | ||
314 | if (!IS_I965G(dev)) { | ||
315 | error->ipeir = I915_READ(IPEIR); | ||
316 | error->ipehr = I915_READ(IPEHR); | ||
317 | error->instdone = I915_READ(INSTDONE); | ||
318 | error->acthd = I915_READ(ACTHD); | ||
319 | } else { | ||
320 | error->ipeir = I915_READ(IPEIR_I965); | ||
321 | error->ipehr = I915_READ(IPEHR_I965); | ||
322 | error->instdone = I915_READ(INSTDONE_I965); | ||
323 | error->instps = I915_READ(INSTPS); | ||
324 | error->instdone1 = I915_READ(INSTDONE1); | ||
325 | error->acthd = I915_READ(ACTHD_I965); | ||
326 | } | ||
327 | |||
328 | dev_priv->first_error = error; | ||
329 | |||
330 | out: | ||
331 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | ||
332 | } | ||
333 | |||
291 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 334 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
292 | { | 335 | { |
293 | struct drm_device *dev = (struct drm_device *) arg; | 336 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -333,11 +376,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
333 | * Clear the PIPE(A|B)STAT regs before the IIR | 376 | * Clear the PIPE(A|B)STAT regs before the IIR |
334 | */ | 377 | */ |
335 | if (pipea_stats & 0x8000ffff) { | 378 | if (pipea_stats & 0x8000ffff) { |
379 | if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
380 | DRM_DEBUG("pipe a underrun\n"); | ||
336 | I915_WRITE(PIPEASTAT, pipea_stats); | 381 | I915_WRITE(PIPEASTAT, pipea_stats); |
337 | irq_received = 1; | 382 | irq_received = 1; |
338 | } | 383 | } |
339 | 384 | ||
340 | if (pipeb_stats & 0x8000ffff) { | 385 | if (pipeb_stats & 0x8000ffff) { |
386 | if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS) | ||
387 | DRM_DEBUG("pipe b underrun\n"); | ||
341 | I915_WRITE(PIPEBSTAT, pipeb_stats); | 388 | I915_WRITE(PIPEBSTAT, pipeb_stats); |
342 | irq_received = 1; | 389 | irq_received = 1; |
343 | } | 390 | } |
@@ -362,6 +409,80 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
362 | I915_READ(PORT_HOTPLUG_STAT); | 409 | I915_READ(PORT_HOTPLUG_STAT); |
363 | } | 410 | } |
364 | 411 | ||
412 | if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) { | ||
413 | u32 eir = I915_READ(EIR); | ||
414 | |||
415 | i915_capture_error_state(dev); | ||
416 | |||
417 | printk(KERN_ERR "render error detected, EIR: 0x%08x\n", | ||
418 | eir); | ||
419 | if (eir & I915_ERROR_PAGE_TABLE) { | ||
420 | u32 pgtbl_err = I915_READ(PGTBL_ER); | ||
421 | printk(KERN_ERR "page table error\n"); | ||
422 | printk(KERN_ERR " PGTBL_ER: 0x%08x\n", | ||
423 | pgtbl_err); | ||
424 | I915_WRITE(PGTBL_ER, pgtbl_err); | ||
425 | (void)I915_READ(PGTBL_ER); | ||
426 | } | ||
427 | if (eir & I915_ERROR_MEMORY_REFRESH) { | ||
428 | printk(KERN_ERR "memory refresh error\n"); | ||
429 | printk(KERN_ERR "PIPEASTAT: 0x%08x\n", | ||
430 | pipea_stats); | ||
431 | printk(KERN_ERR "PIPEBSTAT: 0x%08x\n", | ||
432 | pipeb_stats); | ||
433 | /* pipestat has already been acked */ | ||
434 | } | ||
435 | if (eir & I915_ERROR_INSTRUCTION) { | ||
436 | printk(KERN_ERR "instruction error\n"); | ||
437 | printk(KERN_ERR " INSTPM: 0x%08x\n", | ||
438 | I915_READ(INSTPM)); | ||
439 | if (!IS_I965G(dev)) { | ||
440 | u32 ipeir = I915_READ(IPEIR); | ||
441 | |||
442 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
443 | I915_READ(IPEIR)); | ||
444 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
445 | I915_READ(IPEHR)); | ||
446 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
447 | I915_READ(INSTDONE)); | ||
448 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
449 | I915_READ(ACTHD)); | ||
450 | I915_WRITE(IPEIR, ipeir); | ||
451 | (void)I915_READ(IPEIR); | ||
452 | } else { | ||
453 | u32 ipeir = I915_READ(IPEIR_I965); | ||
454 | |||
455 | printk(KERN_ERR " IPEIR: 0x%08x\n", | ||
456 | I915_READ(IPEIR_I965)); | ||
457 | printk(KERN_ERR " IPEHR: 0x%08x\n", | ||
458 | I915_READ(IPEHR_I965)); | ||
459 | printk(KERN_ERR " INSTDONE: 0x%08x\n", | ||
460 | I915_READ(INSTDONE_I965)); | ||
461 | printk(KERN_ERR " INSTPS: 0x%08x\n", | ||
462 | I915_READ(INSTPS)); | ||
463 | printk(KERN_ERR " INSTDONE1: 0x%08x\n", | ||
464 | I915_READ(INSTDONE1)); | ||
465 | printk(KERN_ERR " ACTHD: 0x%08x\n", | ||
466 | I915_READ(ACTHD_I965)); | ||
467 | I915_WRITE(IPEIR_I965, ipeir); | ||
468 | (void)I915_READ(IPEIR_I965); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | I915_WRITE(EIR, eir); | ||
473 | (void)I915_READ(EIR); | ||
474 | eir = I915_READ(EIR); | ||
475 | if (eir) { | ||
476 | /* | ||
477 | * some errors might have become stuck, | ||
478 | * mask them. | ||
479 | */ | ||
480 | DRM_ERROR("EIR stuck: 0x%08x, masking\n", eir); | ||
481 | I915_WRITE(EMR, I915_READ(EMR) | eir); | ||
482 | I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); | ||
483 | } | ||
484 | } | ||
485 | |||
365 | I915_WRITE(IIR, iir); | 486 | I915_WRITE(IIR, iir); |
366 | new_iir = I915_READ(IIR); /* Flush posted writes */ | 487 | new_iir = I915_READ(IIR); /* Flush posted writes */ |
367 | 488 | ||
@@ -732,6 +853,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
732 | { | 853 | { |
733 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 854 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
734 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 855 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
856 | u32 error_mask; | ||
735 | 857 | ||
736 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); | 858 | DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); |
737 | 859 | ||
@@ -768,6 +890,21 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
768 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); | 890 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); |
769 | } | 891 | } |
770 | 892 | ||
893 | /* | ||
894 | * Enable some error detection, note the instruction error mask | ||
895 | * bit is reserved, so we leave it masked. | ||
896 | */ | ||
897 | if (IS_G4X(dev)) { | ||
898 | error_mask = ~(GM45_ERROR_PAGE_TABLE | | ||
899 | GM45_ERROR_MEM_PRIV | | ||
900 | GM45_ERROR_CP_PRIV | | ||
901 | I915_ERROR_MEMORY_REFRESH); | ||
902 | } else { | ||
903 | error_mask = ~(I915_ERROR_PAGE_TABLE | | ||
904 | I915_ERROR_MEMORY_REFRESH); | ||
905 | } | ||
906 | I915_WRITE(EMR, error_mask); | ||
907 | |||
771 | /* Disable pipe interrupt enables, clear pending pipe status */ | 908 | /* Disable pipe interrupt enables, clear pending pipe status */ |
772 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); | 909 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); |
773 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); | 910 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 88bf7521405f..6c0858484094 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -206,6 +206,7 @@ | |||
206 | /* | 206 | /* |
207 | * Instruction and interrupt control regs | 207 | * Instruction and interrupt control regs |
208 | */ | 208 | */ |
209 | #define PGTBL_ER 0x02024 | ||
209 | #define PRB0_TAIL 0x02030 | 210 | #define PRB0_TAIL 0x02030 |
210 | #define PRB0_HEAD 0x02034 | 211 | #define PRB0_HEAD 0x02034 |
211 | #define PRB0_START 0x02038 | 212 | #define PRB0_START 0x02038 |
@@ -226,11 +227,18 @@ | |||
226 | #define PRB1_HEAD 0x02044 /* 915+ only */ | 227 | #define PRB1_HEAD 0x02044 /* 915+ only */ |
227 | #define PRB1_START 0x02048 /* 915+ only */ | 228 | #define PRB1_START 0x02048 /* 915+ only */ |
228 | #define PRB1_CTL 0x0204c /* 915+ only */ | 229 | #define PRB1_CTL 0x0204c /* 915+ only */ |
230 | #define IPEIR_I965 0x02064 | ||
231 | #define IPEHR_I965 0x02068 | ||
232 | #define INSTDONE_I965 0x0206c | ||
233 | #define INSTPS 0x02070 /* 965+ only */ | ||
234 | #define INSTDONE1 0x0207c /* 965+ only */ | ||
229 | #define ACTHD_I965 0x02074 | 235 | #define ACTHD_I965 0x02074 |
230 | #define HWS_PGA 0x02080 | 236 | #define HWS_PGA 0x02080 |
231 | #define HWS_ADDRESS_MASK 0xfffff000 | 237 | #define HWS_ADDRESS_MASK 0xfffff000 |
232 | #define HWS_START_ADDRESS_SHIFT 4 | 238 | #define HWS_START_ADDRESS_SHIFT 4 |
233 | #define IPEIR 0x02088 | 239 | #define IPEIR 0x02088 |
240 | #define IPEHR 0x0208c | ||
241 | #define INSTDONE 0x02090 | ||
234 | #define NOPID 0x02094 | 242 | #define NOPID 0x02094 |
235 | #define HWSTAM 0x02098 | 243 | #define HWSTAM 0x02098 |
236 | #define SCPD0 0x0209c /* 915+ only */ | 244 | #define SCPD0 0x0209c /* 915+ only */ |
@@ -258,10 +266,22 @@ | |||
258 | #define EIR 0x020b0 | 266 | #define EIR 0x020b0 |
259 | #define EMR 0x020b4 | 267 | #define EMR 0x020b4 |
260 | #define ESR 0x020b8 | 268 | #define ESR 0x020b8 |
269 | #define GM45_ERROR_PAGE_TABLE (1<<5) | ||
270 | #define GM45_ERROR_MEM_PRIV (1<<4) | ||
271 | #define I915_ERROR_PAGE_TABLE (1<<4) | ||
272 | #define GM45_ERROR_CP_PRIV (1<<3) | ||
273 | #define I915_ERROR_MEMORY_REFRESH (1<<1) | ||
274 | #define I915_ERROR_INSTRUCTION (1<<0) | ||
261 | #define INSTPM 0x020c0 | 275 | #define INSTPM 0x020c0 |
262 | #define ACTHD 0x020c8 | 276 | #define ACTHD 0x020c8 |
263 | #define FW_BLC 0x020d8 | 277 | #define FW_BLC 0x020d8 |
278 | #define FW_BLC2 0x020dc | ||
264 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ | 279 | #define FW_BLC_SELF 0x020e0 /* 915+ only */ |
280 | #define FW_BLC_SELF_EN (1<<15) | ||
281 | #define MM_BURST_LENGTH 0x00700000 | ||
282 | #define MM_FIFO_WATERMARK 0x0001F000 | ||
283 | #define LM_BURST_LENGTH 0x00000700 | ||
284 | #define LM_FIFO_WATERMARK 0x0000001F | ||
265 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ | 285 | #define MI_ARB_STATE 0x020e4 /* 915+ only */ |
266 | #define CACHE_MODE_0 0x02120 /* 915+ only */ | 286 | #define CACHE_MODE_0 0x02120 /* 915+ only */ |
267 | #define CM0_MASK_SHIFT 16 | 287 | #define CM0_MASK_SHIFT 16 |
@@ -571,17 +591,21 @@ | |||
571 | 591 | ||
572 | /* Clocking configuration register */ | 592 | /* Clocking configuration register */ |
573 | #define CLKCFG 0x10c00 | 593 | #define CLKCFG 0x10c00 |
574 | #define CLKCFG_FSB_400 (0 << 0) /* hrawclk 100 */ | 594 | #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */ |
575 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ | 595 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ |
576 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ | 596 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ |
577 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ | 597 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ |
578 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ | 598 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ |
579 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ | 599 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ |
580 | /* this is a guess, could be 5 as well */ | 600 | /* Note, below two are guess */ |
581 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ | 601 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ |
582 | #define CLKCFG_FSB_1600_ALT (5 << 0) /* hrawclk 400 */ | 602 | #define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */ |
583 | #define CLKCFG_FSB_MASK (7 << 0) | 603 | #define CLKCFG_FSB_MASK (7 << 0) |
584 | 604 | #define CLKCFG_MEM_533 (1 << 4) | |
605 | #define CLKCFG_MEM_667 (2 << 4) | ||
606 | #define CLKCFG_MEM_800 (3 << 4) | ||
607 | #define CLKCFG_MEM_MASK (7 << 4) | ||
608 | |||
585 | /** GM965 GM45 render standby register */ | 609 | /** GM965 GM45 render standby register */ |
586 | #define MCHBAR_RENDER_STANDBY 0x111B8 | 610 | #define MCHBAR_RENDER_STANDBY 0x111B8 |
587 | 611 | ||
@@ -1581,6 +1605,34 @@ | |||
1581 | #define DSPARB_CSTART_SHIFT 7 | 1605 | #define DSPARB_CSTART_SHIFT 7 |
1582 | #define DSPARB_BSTART_MASK (0x7f) | 1606 | #define DSPARB_BSTART_MASK (0x7f) |
1583 | #define DSPARB_BSTART_SHIFT 0 | 1607 | #define DSPARB_BSTART_SHIFT 0 |
1608 | #define DSPARB_BEND_SHIFT 9 /* on 855 */ | ||
1609 | #define DSPARB_AEND_SHIFT 0 | ||
1610 | |||
1611 | #define DSPFW1 0x70034 | ||
1612 | #define DSPFW2 0x70038 | ||
1613 | #define DSPFW3 0x7003c | ||
1614 | #define IGD_SELF_REFRESH_EN (1<<30) | ||
1615 | |||
1616 | /* FIFO watermark sizes etc */ | ||
1617 | #define I915_FIFO_LINE_SIZE 64 | ||
1618 | #define I830_FIFO_LINE_SIZE 32 | ||
1619 | #define I945_FIFO_SIZE 127 /* 945 & 965 */ | ||
1620 | #define I915_FIFO_SIZE 95 | ||
1621 | #define I855GM_FIFO_SIZE 255 | ||
1622 | #define I830_FIFO_SIZE 95 | ||
1623 | #define I915_MAX_WM 0x3f | ||
1624 | |||
1625 | #define IGD_DISPLAY_FIFO 512 /* in 64byte unit */ | ||
1626 | #define IGD_FIFO_LINE_SIZE 64 | ||
1627 | #define IGD_MAX_WM 0x1ff | ||
1628 | #define IGD_DFT_WM 0x3f | ||
1629 | #define IGD_DFT_HPLLOFF_WM 0 | ||
1630 | #define IGD_GUARD_WM 10 | ||
1631 | #define IGD_CURSOR_FIFO 64 | ||
1632 | #define IGD_CURSOR_MAX_WM 0x3f | ||
1633 | #define IGD_CURSOR_DFT_WM 0 | ||
1634 | #define IGD_CURSOR_GUARD_WM 5 | ||
1635 | |||
1584 | /* | 1636 | /* |
1585 | * The two pipe frame counter registers are not synchronized, so | 1637 | * The two pipe frame counter registers are not synchronized, so |
1586 | * reading a stable value is somewhat tricky. The following code | 1638 | * reading a stable value is somewhat tricky. The following code |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 8d8e083d14ab..9e1d16e5c3ea 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -222,23 +222,12 @@ static void i915_restore_vga(struct drm_device *dev) | |||
222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); | 222 | I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK); |
223 | } | 223 | } |
224 | 224 | ||
225 | int i915_save_state(struct drm_device *dev) | 225 | static void i915_save_modeset_reg(struct drm_device *dev) |
226 | { | 226 | { |
227 | struct drm_i915_private *dev_priv = dev->dev_private; | 227 | struct drm_i915_private *dev_priv = dev->dev_private; |
228 | int i; | ||
229 | |||
230 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
231 | |||
232 | /* Render Standby */ | ||
233 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
234 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
235 | |||
236 | /* Hardware status page */ | ||
237 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
238 | |||
239 | /* Display arbitration control */ | ||
240 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
241 | 228 | ||
229 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
230 | return; | ||
242 | /* Pipe & plane A info */ | 231 | /* Pipe & plane A info */ |
243 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 232 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
244 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 233 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -294,7 +283,122 @@ int i915_save_state(struct drm_device *dev) | |||
294 | } | 283 | } |
295 | i915_save_palette(dev, PIPE_B); | 284 | i915_save_palette(dev, PIPE_B); |
296 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); | 285 | dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); |
286 | return; | ||
287 | } | ||
288 | static void i915_restore_modeset_reg(struct drm_device *dev) | ||
289 | { | ||
290 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
291 | |||
292 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
293 | return; | ||
294 | |||
295 | /* Pipe & plane A info */ | ||
296 | /* Prime the clock */ | ||
297 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
298 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
299 | ~DPLL_VCO_ENABLE); | ||
300 | DRM_UDELAY(150); | ||
301 | } | ||
302 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
303 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
304 | /* Actually enable it */ | ||
305 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
306 | DRM_UDELAY(150); | ||
307 | if (IS_I965G(dev)) | ||
308 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
309 | DRM_UDELAY(150); | ||
310 | |||
311 | /* Restore mode */ | ||
312 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
313 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
314 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
315 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
316 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
317 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
318 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
319 | |||
320 | /* Restore plane info */ | ||
321 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
322 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
323 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
324 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
325 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
326 | if (IS_I965G(dev)) { | ||
327 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
328 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
329 | } | ||
330 | |||
331 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
332 | |||
333 | i915_restore_palette(dev, PIPE_A); | ||
334 | /* Enable the plane */ | ||
335 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
336 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
337 | |||
338 | /* Pipe & plane B info */ | ||
339 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
340 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
341 | ~DPLL_VCO_ENABLE); | ||
342 | DRM_UDELAY(150); | ||
343 | } | ||
344 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
345 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
346 | /* Actually enable it */ | ||
347 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
348 | DRM_UDELAY(150); | ||
349 | if (IS_I965G(dev)) | ||
350 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
351 | DRM_UDELAY(150); | ||
352 | |||
353 | /* Restore mode */ | ||
354 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
355 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
356 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
357 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
358 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
359 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
360 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
361 | |||
362 | /* Restore plane info */ | ||
363 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
364 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
365 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
366 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
367 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
368 | if (IS_I965G(dev)) { | ||
369 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
370 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
371 | } | ||
372 | |||
373 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
374 | |||
375 | i915_restore_palette(dev, PIPE_B); | ||
376 | /* Enable the plane */ | ||
377 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
378 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
297 | 379 | ||
380 | return; | ||
381 | } | ||
382 | int i915_save_state(struct drm_device *dev) | ||
383 | { | ||
384 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
385 | int i; | ||
386 | |||
387 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | ||
388 | |||
389 | /* Render Standby */ | ||
390 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
391 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
392 | |||
393 | /* Hardware status page */ | ||
394 | dev_priv->saveHWS = I915_READ(HWS_PGA); | ||
395 | |||
396 | /* Display arbitration control */ | ||
397 | dev_priv->saveDSPARB = I915_READ(DSPARB); | ||
398 | |||
399 | /* This is only meaningful in non-KMS mode */ | ||
400 | /* Don't save them in KMS mode */ | ||
401 | i915_save_modeset_reg(dev); | ||
298 | /* Cursor state */ | 402 | /* Cursor state */ |
299 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); | 403 | dev_priv->saveCURACNTR = I915_READ(CURACNTR); |
300 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); | 404 | dev_priv->saveCURAPOS = I915_READ(CURAPOS); |
@@ -430,92 +534,9 @@ int i915_restore_state(struct drm_device *dev) | |||
430 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); | 534 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); |
431 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); | 535 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); |
432 | } | 536 | } |
433 | 537 | /* This is only meaningful in non-KMS mode */ | |
434 | /* Pipe & plane A info */ | 538 | /* Don't restore them in KMS mode */ |
435 | /* Prime the clock */ | 539 | i915_restore_modeset_reg(dev); |
436 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | ||
437 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A & | ||
438 | ~DPLL_VCO_ENABLE); | ||
439 | DRM_UDELAY(150); | ||
440 | } | ||
441 | I915_WRITE(FPA0, dev_priv->saveFPA0); | ||
442 | I915_WRITE(FPA1, dev_priv->saveFPA1); | ||
443 | /* Actually enable it */ | ||
444 | I915_WRITE(DPLL_A, dev_priv->saveDPLL_A); | ||
445 | DRM_UDELAY(150); | ||
446 | if (IS_I965G(dev)) | ||
447 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | ||
448 | DRM_UDELAY(150); | ||
449 | |||
450 | /* Restore mode */ | ||
451 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | ||
452 | I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A); | ||
453 | I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A); | ||
454 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | ||
455 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | ||
456 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | ||
457 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | ||
458 | |||
459 | /* Restore plane info */ | ||
460 | I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE); | ||
461 | I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS); | ||
462 | I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC); | ||
463 | I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR); | ||
464 | I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE); | ||
465 | if (IS_I965G(dev)) { | ||
466 | I915_WRITE(DSPASURF, dev_priv->saveDSPASURF); | ||
467 | I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF); | ||
468 | } | ||
469 | |||
470 | I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF); | ||
471 | |||
472 | i915_restore_palette(dev, PIPE_A); | ||
473 | /* Enable the plane */ | ||
474 | I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR); | ||
475 | I915_WRITE(DSPAADDR, I915_READ(DSPAADDR)); | ||
476 | |||
477 | /* Pipe & plane B info */ | ||
478 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | ||
479 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B & | ||
480 | ~DPLL_VCO_ENABLE); | ||
481 | DRM_UDELAY(150); | ||
482 | } | ||
483 | I915_WRITE(FPB0, dev_priv->saveFPB0); | ||
484 | I915_WRITE(FPB1, dev_priv->saveFPB1); | ||
485 | /* Actually enable it */ | ||
486 | I915_WRITE(DPLL_B, dev_priv->saveDPLL_B); | ||
487 | DRM_UDELAY(150); | ||
488 | if (IS_I965G(dev)) | ||
489 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | ||
490 | DRM_UDELAY(150); | ||
491 | |||
492 | /* Restore mode */ | ||
493 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | ||
494 | I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B); | ||
495 | I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B); | ||
496 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | ||
497 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | ||
498 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | ||
499 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | ||
500 | |||
501 | /* Restore plane info */ | ||
502 | I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE); | ||
503 | I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS); | ||
504 | I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC); | ||
505 | I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR); | ||
506 | I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE); | ||
507 | if (IS_I965G(dev)) { | ||
508 | I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF); | ||
509 | I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF); | ||
510 | } | ||
511 | |||
512 | I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF); | ||
513 | |||
514 | i915_restore_palette(dev, PIPE_B); | ||
515 | /* Enable the plane */ | ||
516 | I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR); | ||
517 | I915_WRITE(DSPBADDR, I915_READ(DSPBADDR)); | ||
518 | |||
519 | /* Cursor state */ | 540 | /* Cursor state */ |
520 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); | 541 | I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); |
521 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); | 542 | I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 716409a57244..7cc447191028 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -97,6 +97,7 @@ static void | |||
97 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, | 97 | parse_lfp_panel_data(struct drm_i915_private *dev_priv, |
98 | struct bdb_header *bdb) | 98 | struct bdb_header *bdb) |
99 | { | 99 | { |
100 | struct drm_device *dev = dev_priv->dev; | ||
100 | struct bdb_lvds_options *lvds_options; | 101 | struct bdb_lvds_options *lvds_options; |
101 | struct bdb_lvds_lfp_data *lvds_lfp_data; | 102 | struct bdb_lvds_lfp_data *lvds_lfp_data; |
102 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; | 103 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; |
@@ -132,7 +133,14 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
132 | entry = (struct bdb_lvds_lfp_data_entry *) | 133 | entry = (struct bdb_lvds_lfp_data_entry *) |
133 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * | 134 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * |
134 | lvds_options->panel_type)); | 135 | lvds_options->panel_type)); |
135 | dvo_timing = &entry->dvo_timing; | 136 | |
137 | /* On IGDNG mobile, LVDS data block removes panel fitting registers. | ||
138 | So dec 2 dword from dvo_timing offset */ | ||
139 | if (IS_IGDNG(dev)) | ||
140 | dvo_timing = (struct lvds_dvo_timing *) | ||
141 | ((u8 *)&entry->dvo_timing - 8); | ||
142 | else | ||
143 | dvo_timing = &entry->dvo_timing; | ||
136 | 144 | ||
137 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); | 145 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
138 | 146 | ||
@@ -195,10 +203,12 @@ parse_general_features(struct drm_i915_private *dev_priv, | |||
195 | dev_priv->lvds_use_ssc = general->enable_ssc; | 203 | dev_priv->lvds_use_ssc = general->enable_ssc; |
196 | 204 | ||
197 | if (dev_priv->lvds_use_ssc) { | 205 | if (dev_priv->lvds_use_ssc) { |
198 | if (IS_I855(dev_priv->dev)) | 206 | if (IS_I85X(dev_priv->dev)) |
199 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; | 207 | dev_priv->lvds_ssc_freq = |
200 | else | 208 | general->ssc_freq ? 66 : 48; |
201 | dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; | 209 | else |
210 | dev_priv->lvds_ssc_freq = | ||
211 | general->ssc_freq ? 100 : 96; | ||
202 | } | 212 | } |
203 | } | 213 | } |
204 | } | 214 | } |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 6de97fc66029..d6a1a6e5539a 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -46,7 +46,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
46 | 46 | ||
47 | temp = I915_READ(reg); | 47 | temp = I915_READ(reg); |
48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | 48 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
49 | temp |= ADPA_DAC_ENABLE; | 49 | temp &= ~ADPA_DAC_ENABLE; |
50 | 50 | ||
51 | switch(mode) { | 51 | switch(mode) { |
52 | case DRM_MODE_DPMS_ON: | 52 | case DRM_MODE_DPMS_ON: |
@@ -428,8 +428,34 @@ static void intel_crt_destroy(struct drm_connector *connector) | |||
428 | 428 | ||
429 | static int intel_crt_get_modes(struct drm_connector *connector) | 429 | static int intel_crt_get_modes(struct drm_connector *connector) |
430 | { | 430 | { |
431 | int ret; | ||
431 | struct intel_output *intel_output = to_intel_output(connector); | 432 | struct intel_output *intel_output = to_intel_output(connector); |
432 | return intel_ddc_get_modes(intel_output); | 433 | struct i2c_adapter *ddcbus; |
434 | struct drm_device *dev = connector->dev; | ||
435 | |||
436 | |||
437 | ret = intel_ddc_get_modes(intel_output); | ||
438 | if (ret || !IS_G4X(dev)) | ||
439 | goto end; | ||
440 | |||
441 | ddcbus = intel_output->ddc_bus; | ||
442 | /* Try to probe digital port for output in DVI-I -> VGA mode. */ | ||
443 | intel_output->ddc_bus = | ||
444 | intel_i2c_create(connector->dev, GPIOD, "CRTDDC_D"); | ||
445 | |||
446 | if (!intel_output->ddc_bus) { | ||
447 | intel_output->ddc_bus = ddcbus; | ||
448 | dev_printk(KERN_ERR, &connector->dev->pdev->dev, | ||
449 | "DDC bus registration failed for CRTDDC_D.\n"); | ||
450 | goto end; | ||
451 | } | ||
452 | /* Try to get modes by GPIOD port */ | ||
453 | ret = intel_ddc_get_modes(intel_output); | ||
454 | intel_i2c_destroy(ddcbus); | ||
455 | |||
456 | end: | ||
457 | return ret; | ||
458 | |||
433 | } | 459 | } |
434 | 460 | ||
435 | static int intel_crt_set_property(struct drm_connector *connector, | 461 | static int intel_crt_set_property(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 73e7b9cecac8..508838ee31e0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/kernel.h> | ||
28 | #include "drmP.h" | 29 | #include "drmP.h" |
29 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
30 | #include "i915_drm.h" | 31 | #include "i915_drm.h" |
@@ -34,6 +35,7 @@ | |||
34 | #include "drm_crtc_helper.h" | 35 | #include "drm_crtc_helper.h" |
35 | 36 | ||
36 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); | 37 | bool intel_pipe_has_type (struct drm_crtc *crtc, int type); |
38 | static void intel_update_watermarks(struct drm_device *dev); | ||
37 | 39 | ||
38 | typedef struct { | 40 | typedef struct { |
39 | /* given values */ | 41 | /* given values */ |
@@ -814,24 +816,21 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
814 | { | 816 | { |
815 | intel_clock_t clock; | 817 | intel_clock_t clock; |
816 | if (target < 200000) { | 818 | if (target < 200000) { |
817 | clock.dot = 161670; | ||
818 | clock.p = 20; | ||
819 | clock.p1 = 2; | 819 | clock.p1 = 2; |
820 | clock.p2 = 10; | 820 | clock.p2 = 10; |
821 | clock.n = 0x01; | 821 | clock.n = 2; |
822 | clock.m = 97; | 822 | clock.m1 = 23; |
823 | clock.m1 = 0x10; | 823 | clock.m2 = 8; |
824 | clock.m2 = 0x05; | ||
825 | } else { | 824 | } else { |
826 | clock.dot = 270000; | ||
827 | clock.p = 10; | ||
828 | clock.p1 = 1; | 825 | clock.p1 = 1; |
829 | clock.p2 = 10; | 826 | clock.p2 = 10; |
830 | clock.n = 0x02; | 827 | clock.n = 1; |
831 | clock.m = 108; | 828 | clock.m1 = 14; |
832 | clock.m1 = 0x12; | 829 | clock.m2 = 2; |
833 | clock.m2 = 0x06; | ||
834 | } | 830 | } |
831 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); | ||
832 | clock.p = (clock.p1 * clock.p2); | ||
833 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; | ||
835 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | 834 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
836 | return true; | 835 | return true; |
837 | } | 836 | } |
@@ -1005,7 +1004,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1005 | struct drm_i915_private *dev_priv = dev->dev_private; | 1004 | struct drm_i915_private *dev_priv = dev->dev_private; |
1006 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1005 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1007 | int pipe = intel_crtc->pipe; | 1006 | int pipe = intel_crtc->pipe; |
1008 | int plane = intel_crtc->pipe; | 1007 | int plane = intel_crtc->plane; |
1009 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; | 1008 | int pch_dpll_reg = (pipe == 0) ? PCH_DPLL_A : PCH_DPLL_B; |
1010 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | 1009 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; |
1011 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; | 1010 | int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; |
@@ -1335,8 +1334,10 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1335 | 1334 | ||
1336 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 1335 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
1337 | //intel_crtc_dpms_video(crtc, true); TODO | 1336 | //intel_crtc_dpms_video(crtc, true); TODO |
1337 | intel_update_watermarks(dev); | ||
1338 | break; | 1338 | break; |
1339 | case DRM_MODE_DPMS_OFF: | 1339 | case DRM_MODE_DPMS_OFF: |
1340 | intel_update_watermarks(dev); | ||
1340 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 1341 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
1341 | //intel_crtc_dpms_video(crtc, FALSE); TODO | 1342 | //intel_crtc_dpms_video(crtc, FALSE); TODO |
1342 | 1343 | ||
@@ -1515,7 +1516,6 @@ static int intel_get_core_clock_speed(struct drm_device *dev) | |||
1515 | return 0; /* Silence gcc warning */ | 1516 | return 0; /* Silence gcc warning */ |
1516 | } | 1517 | } |
1517 | 1518 | ||
1518 | |||
1519 | /** | 1519 | /** |
1520 | * Return the pipe currently connected to the panel fitter, | 1520 | * Return the pipe currently connected to the panel fitter, |
1521 | * or -1 if the panel fitter is not present or not in use | 1521 | * or -1 if the panel fitter is not present or not in use |
@@ -1574,7 +1574,7 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1574 | 1574 | ||
1575 | temp = (u64) DATA_N * pixel_clock; | 1575 | temp = (u64) DATA_N * pixel_clock; |
1576 | temp = div_u64(temp, link_clock); | 1576 | temp = div_u64(temp, link_clock); |
1577 | m_n->gmch_m = (temp * bytes_per_pixel) / nlanes; | 1577 | m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); |
1578 | m_n->gmch_n = DATA_N; | 1578 | m_n->gmch_n = DATA_N; |
1579 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 1579 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
1580 | 1580 | ||
@@ -1585,6 +1585,420 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | 1587 | ||
1588 | struct intel_watermark_params { | ||
1589 | unsigned long fifo_size; | ||
1590 | unsigned long max_wm; | ||
1591 | unsigned long default_wm; | ||
1592 | unsigned long guard_size; | ||
1593 | unsigned long cacheline_size; | ||
1594 | }; | ||
1595 | |||
1596 | /* IGD has different values for various configs */ | ||
1597 | static struct intel_watermark_params igd_display_wm = { | ||
1598 | IGD_DISPLAY_FIFO, | ||
1599 | IGD_MAX_WM, | ||
1600 | IGD_DFT_WM, | ||
1601 | IGD_GUARD_WM, | ||
1602 | IGD_FIFO_LINE_SIZE | ||
1603 | }; | ||
1604 | static struct intel_watermark_params igd_display_hplloff_wm = { | ||
1605 | IGD_DISPLAY_FIFO, | ||
1606 | IGD_MAX_WM, | ||
1607 | IGD_DFT_HPLLOFF_WM, | ||
1608 | IGD_GUARD_WM, | ||
1609 | IGD_FIFO_LINE_SIZE | ||
1610 | }; | ||
1611 | static struct intel_watermark_params igd_cursor_wm = { | ||
1612 | IGD_CURSOR_FIFO, | ||
1613 | IGD_CURSOR_MAX_WM, | ||
1614 | IGD_CURSOR_DFT_WM, | ||
1615 | IGD_CURSOR_GUARD_WM, | ||
1616 | IGD_FIFO_LINE_SIZE, | ||
1617 | }; | ||
1618 | static struct intel_watermark_params igd_cursor_hplloff_wm = { | ||
1619 | IGD_CURSOR_FIFO, | ||
1620 | IGD_CURSOR_MAX_WM, | ||
1621 | IGD_CURSOR_DFT_WM, | ||
1622 | IGD_CURSOR_GUARD_WM, | ||
1623 | IGD_FIFO_LINE_SIZE | ||
1624 | }; | ||
1625 | static struct intel_watermark_params i945_wm_info = { | ||
1626 | I915_FIFO_LINE_SIZE, | ||
1627 | I915_MAX_WM, | ||
1628 | 1, | ||
1629 | 0, | ||
1630 | IGD_FIFO_LINE_SIZE | ||
1631 | }; | ||
1632 | static struct intel_watermark_params i915_wm_info = { | ||
1633 | I945_FIFO_SIZE, | ||
1634 | I915_MAX_WM, | ||
1635 | 1, | ||
1636 | 0, | ||
1637 | I915_FIFO_LINE_SIZE | ||
1638 | }; | ||
1639 | static struct intel_watermark_params i855_wm_info = { | ||
1640 | I855GM_FIFO_SIZE, | ||
1641 | I915_MAX_WM, | ||
1642 | 1, | ||
1643 | 0, | ||
1644 | I830_FIFO_LINE_SIZE | ||
1645 | }; | ||
1646 | static struct intel_watermark_params i830_wm_info = { | ||
1647 | I830_FIFO_SIZE, | ||
1648 | I915_MAX_WM, | ||
1649 | 1, | ||
1650 | 0, | ||
1651 | I830_FIFO_LINE_SIZE | ||
1652 | }; | ||
1653 | |||
1654 | static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | ||
1655 | struct intel_watermark_params *wm, | ||
1656 | int pixel_size, | ||
1657 | unsigned long latency_ns) | ||
1658 | { | ||
1659 | unsigned long bytes_required, wm_size; | ||
1660 | |||
1661 | bytes_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; | ||
1662 | bytes_required /= wm->cacheline_size; | ||
1663 | wm_size = wm->fifo_size - bytes_required - wm->guard_size; | ||
1664 | |||
1665 | if (wm_size > wm->max_wm) | ||
1666 | wm_size = wm->max_wm; | ||
1667 | if (wm_size == 0) | ||
1668 | wm_size = wm->default_wm; | ||
1669 | return wm_size; | ||
1670 | } | ||
1671 | |||
1672 | struct cxsr_latency { | ||
1673 | int is_desktop; | ||
1674 | unsigned long fsb_freq; | ||
1675 | unsigned long mem_freq; | ||
1676 | unsigned long display_sr; | ||
1677 | unsigned long display_hpll_disable; | ||
1678 | unsigned long cursor_sr; | ||
1679 | unsigned long cursor_hpll_disable; | ||
1680 | }; | ||
1681 | |||
1682 | static struct cxsr_latency cxsr_latency_table[] = { | ||
1683 | {1, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | ||
1684 | {1, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | ||
1685 | {1, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | ||
1686 | |||
1687 | {1, 667, 400, 3400, 33400, 4021, 34021}, /* DDR2-400 SC */ | ||
1688 | {1, 667, 667, 3372, 33372, 3845, 33845}, /* DDR2-667 SC */ | ||
1689 | {1, 667, 800, 3386, 33386, 3822, 33822}, /* DDR2-800 SC */ | ||
1690 | |||
1691 | {1, 400, 400, 3472, 33472, 4173, 34173}, /* DDR2-400 SC */ | ||
1692 | {1, 400, 667, 3443, 33443, 3996, 33996}, /* DDR2-667 SC */ | ||
1693 | {1, 400, 800, 3430, 33430, 3946, 33946}, /* DDR2-800 SC */ | ||
1694 | |||
1695 | {0, 800, 400, 3438, 33438, 4065, 34065}, /* DDR2-400 SC */ | ||
1696 | {0, 800, 667, 3410, 33410, 3889, 33889}, /* DDR2-667 SC */ | ||
1697 | {0, 800, 800, 3403, 33403, 3845, 33845}, /* DDR2-800 SC */ | ||
1698 | |||
1699 | {0, 667, 400, 3456, 33456, 4103, 34106}, /* DDR2-400 SC */ | ||
1700 | {0, 667, 667, 3428, 33428, 3927, 33927}, /* DDR2-667 SC */ | ||
1701 | {0, 667, 800, 3443, 33443, 3905, 33905}, /* DDR2-800 SC */ | ||
1702 | |||
1703 | {0, 400, 400, 3528, 33528, 4255, 34255}, /* DDR2-400 SC */ | ||
1704 | {0, 400, 667, 3500, 33500, 4079, 34079}, /* DDR2-667 SC */ | ||
1705 | {0, 400, 800, 3487, 33487, 4029, 34029}, /* DDR2-800 SC */ | ||
1706 | }; | ||
1707 | |||
1708 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, | ||
1709 | int mem) | ||
1710 | { | ||
1711 | int i; | ||
1712 | struct cxsr_latency *latency; | ||
1713 | |||
1714 | if (fsb == 0 || mem == 0) | ||
1715 | return NULL; | ||
1716 | |||
1717 | for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { | ||
1718 | latency = &cxsr_latency_table[i]; | ||
1719 | if (is_desktop == latency->is_desktop && | ||
1720 | fsb == latency->fsb_freq && mem == latency->mem_freq) | ||
1721 | break; | ||
1722 | } | ||
1723 | if (i >= ARRAY_SIZE(cxsr_latency_table)) { | ||
1724 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1725 | return NULL; | ||
1726 | } | ||
1727 | return latency; | ||
1728 | } | ||
1729 | |||
1730 | static void igd_disable_cxsr(struct drm_device *dev) | ||
1731 | { | ||
1732 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1733 | u32 reg; | ||
1734 | |||
1735 | /* deactivate cxsr */ | ||
1736 | reg = I915_READ(DSPFW3); | ||
1737 | reg &= ~(IGD_SELF_REFRESH_EN); | ||
1738 | I915_WRITE(DSPFW3, reg); | ||
1739 | DRM_INFO("Big FIFO is disabled\n"); | ||
1740 | } | ||
1741 | |||
1742 | static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, | ||
1743 | int pixel_size) | ||
1744 | { | ||
1745 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1746 | u32 reg; | ||
1747 | unsigned long wm; | ||
1748 | struct cxsr_latency *latency; | ||
1749 | |||
1750 | latency = intel_get_cxsr_latency(IS_IGDG(dev), dev_priv->fsb_freq, | ||
1751 | dev_priv->mem_freq); | ||
1752 | if (!latency) { | ||
1753 | DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); | ||
1754 | igd_disable_cxsr(dev); | ||
1755 | return; | ||
1756 | } | ||
1757 | |||
1758 | /* Display SR */ | ||
1759 | wm = intel_calculate_wm(clock, &igd_display_wm, pixel_size, | ||
1760 | latency->display_sr); | ||
1761 | reg = I915_READ(DSPFW1); | ||
1762 | reg &= 0x7fffff; | ||
1763 | reg |= wm << 23; | ||
1764 | I915_WRITE(DSPFW1, reg); | ||
1765 | DRM_DEBUG("DSPFW1 register is %x\n", reg); | ||
1766 | |||
1767 | /* cursor SR */ | ||
1768 | wm = intel_calculate_wm(clock, &igd_cursor_wm, pixel_size, | ||
1769 | latency->cursor_sr); | ||
1770 | reg = I915_READ(DSPFW3); | ||
1771 | reg &= ~(0x3f << 24); | ||
1772 | reg |= (wm & 0x3f) << 24; | ||
1773 | I915_WRITE(DSPFW3, reg); | ||
1774 | |||
1775 | /* Display HPLL off SR */ | ||
1776 | wm = intel_calculate_wm(clock, &igd_display_hplloff_wm, | ||
1777 | latency->display_hpll_disable, I915_FIFO_LINE_SIZE); | ||
1778 | reg = I915_READ(DSPFW3); | ||
1779 | reg &= 0xfffffe00; | ||
1780 | reg |= wm & 0x1ff; | ||
1781 | I915_WRITE(DSPFW3, reg); | ||
1782 | |||
1783 | /* cursor HPLL off SR */ | ||
1784 | wm = intel_calculate_wm(clock, &igd_cursor_hplloff_wm, pixel_size, | ||
1785 | latency->cursor_hpll_disable); | ||
1786 | reg = I915_READ(DSPFW3); | ||
1787 | reg &= ~(0x3f << 16); | ||
1788 | reg |= (wm & 0x3f) << 16; | ||
1789 | I915_WRITE(DSPFW3, reg); | ||
1790 | DRM_DEBUG("DSPFW3 register is %x\n", reg); | ||
1791 | |||
1792 | /* activate cxsr */ | ||
1793 | reg = I915_READ(DSPFW3); | ||
1794 | reg |= IGD_SELF_REFRESH_EN; | ||
1795 | I915_WRITE(DSPFW3, reg); | ||
1796 | |||
1797 | DRM_INFO("Big FIFO is enabled\n"); | ||
1798 | |||
1799 | return; | ||
1800 | } | ||
1801 | |||
1802 | const static int latency_ns = 5000; /* default for non-igd platforms */ | ||
1803 | |||
1804 | |||
1805 | static void i965_update_wm(struct drm_device *dev) | ||
1806 | { | ||
1807 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1808 | |||
1809 | DRM_DEBUG("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR 8\n"); | ||
1810 | |||
1811 | /* 965 has limitations... */ | ||
1812 | I915_WRITE(DSPFW1, (8 << 16) | (8 << 8) | (8 << 0)); | ||
1813 | I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); | ||
1814 | } | ||
1815 | |||
1816 | static void i9xx_update_wm(struct drm_device *dev, int planea_clock, | ||
1817 | int planeb_clock, int sr_hdisplay, int pixel_size) | ||
1818 | { | ||
1819 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1820 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | ||
1821 | uint32_t fwater_hi = I915_READ(FW_BLC2) & LM_FIFO_WATERMARK; | ||
1822 | int bsize, asize, cwm, bwm = 1, awm = 1, srwm = 1; | ||
1823 | uint32_t dsparb = I915_READ(DSPARB); | ||
1824 | int planea_entries, planeb_entries; | ||
1825 | struct intel_watermark_params *wm_params; | ||
1826 | unsigned long line_time_us; | ||
1827 | int sr_clock, sr_entries = 0; | ||
1828 | |||
1829 | if (IS_I965GM(dev) || IS_I945GM(dev)) | ||
1830 | wm_params = &i945_wm_info; | ||
1831 | else if (IS_I9XX(dev)) | ||
1832 | wm_params = &i915_wm_info; | ||
1833 | else | ||
1834 | wm_params = &i855_wm_info; | ||
1835 | |||
1836 | planea_entries = intel_calculate_wm(planea_clock, wm_params, | ||
1837 | pixel_size, latency_ns); | ||
1838 | planeb_entries = intel_calculate_wm(planeb_clock, wm_params, | ||
1839 | pixel_size, latency_ns); | ||
1840 | |||
1841 | DRM_DEBUG("FIFO entries - A: %d, B: %d\n", planea_entries, | ||
1842 | planeb_entries); | ||
1843 | |||
1844 | if (IS_I9XX(dev)) { | ||
1845 | asize = dsparb & 0x7f; | ||
1846 | bsize = (dsparb >> DSPARB_CSTART_SHIFT) & 0x7f; | ||
1847 | } else { | ||
1848 | asize = dsparb & 0x1ff; | ||
1849 | bsize = (dsparb >> DSPARB_BEND_SHIFT) & 0x1ff; | ||
1850 | } | ||
1851 | DRM_DEBUG("FIFO size - A: %d, B: %d\n", asize, bsize); | ||
1852 | |||
1853 | /* Two extra entries for padding */ | ||
1854 | awm = asize - (planea_entries + 2); | ||
1855 | bwm = bsize - (planeb_entries + 2); | ||
1856 | |||
1857 | /* Sanity check against potentially bad FIFO allocations */ | ||
1858 | if (awm <= 0) { | ||
1859 | /* pipe is on but has too few FIFO entries */ | ||
1860 | if (planea_entries != 0) | ||
1861 | DRM_DEBUG("plane A needs more FIFO entries\n"); | ||
1862 | awm = 1; | ||
1863 | } | ||
1864 | if (bwm <= 0) { | ||
1865 | if (planeb_entries != 0) | ||
1866 | DRM_DEBUG("plane B needs more FIFO entries\n"); | ||
1867 | bwm = 1; | ||
1868 | } | ||
1869 | |||
1870 | /* | ||
1871 | * Overlay gets an aggressive default since video jitter is bad. | ||
1872 | */ | ||
1873 | cwm = 2; | ||
1874 | |||
1875 | /* Calc sr entries for one pipe configs */ | ||
1876 | if (!planea_clock || !planeb_clock) { | ||
1877 | sr_clock = planea_clock ? planea_clock : planeb_clock; | ||
1878 | line_time_us = (sr_hdisplay * 1000) / sr_clock; | ||
1879 | sr_entries = (((latency_ns / line_time_us) + 1) * pixel_size * | ||
1880 | sr_hdisplay) / 1000; | ||
1881 | sr_entries = roundup(sr_entries / wm_params->cacheline_size, 1); | ||
1882 | if (sr_entries < wm_params->fifo_size) | ||
1883 | srwm = wm_params->fifo_size - sr_entries; | ||
1884 | } | ||
1885 | |||
1886 | DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", | ||
1887 | awm, bwm, cwm, srwm); | ||
1888 | |||
1889 | fwater_lo = fwater_lo | ((bwm & 0x3f) << 16) | (awm & 0x3f); | ||
1890 | fwater_hi = fwater_hi | (cwm & 0x1f); | ||
1891 | |||
1892 | I915_WRITE(FW_BLC, fwater_lo); | ||
1893 | I915_WRITE(FW_BLC2, fwater_hi); | ||
1894 | if (IS_I9XX(dev)) | ||
1895 | I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); | ||
1896 | } | ||
1897 | |||
1898 | static void i830_update_wm(struct drm_device *dev, int planea_clock, | ||
1899 | int pixel_size) | ||
1900 | { | ||
1901 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1902 | uint32_t dsparb = I915_READ(DSPARB); | ||
1903 | uint32_t fwater_lo = I915_READ(FW_BLC) & MM_FIFO_WATERMARK; | ||
1904 | unsigned int asize, awm; | ||
1905 | int planea_entries; | ||
1906 | |||
1907 | planea_entries = intel_calculate_wm(planea_clock, &i830_wm_info, | ||
1908 | pixel_size, latency_ns); | ||
1909 | |||
1910 | asize = dsparb & 0x7f; | ||
1911 | |||
1912 | awm = asize - planea_entries; | ||
1913 | |||
1914 | fwater_lo = fwater_lo | awm; | ||
1915 | |||
1916 | I915_WRITE(FW_BLC, fwater_lo); | ||
1917 | } | ||
1918 | |||
1919 | /** | ||
1920 | * intel_update_watermarks - update FIFO watermark values based on current modes | ||
1921 | * | ||
1922 | * Calculate watermark values for the various WM regs based on current mode | ||
1923 | * and plane configuration. | ||
1924 | * | ||
1925 | * There are several cases to deal with here: | ||
1926 | * - normal (i.e. non-self-refresh) | ||
1927 | * - self-refresh (SR) mode | ||
1928 | * - lines are large relative to FIFO size (buffer can hold up to 2) | ||
1929 | * - lines are small relative to FIFO size (buffer can hold more than 2 | ||
1930 | * lines), so need to account for TLB latency | ||
1931 | * | ||
1932 | * The normal calculation is: | ||
1933 | * watermark = dotclock * bytes per pixel * latency | ||
1934 | * where latency is platform & configuration dependent (we assume pessimal | ||
1935 | * values here). | ||
1936 | * | ||
1937 | * The SR calculation is: | ||
1938 | * watermark = (trunc(latency/line time)+1) * surface width * | ||
1939 | * bytes per pixel | ||
1940 | * where | ||
1941 | * line time = htotal / dotclock | ||
1942 | * and latency is assumed to be high, as above. | ||
1943 | * | ||
1944 | * The final value programmed to the register should always be rounded up, | ||
1945 | * and include an extra 2 entries to account for clock crossings. | ||
1946 | * | ||
1947 | * We don't use the sprite, so we can ignore that. And on Crestline we have | ||
1948 | * to set the non-SR watermarks to 8. | ||
1949 | */ | ||
1950 | static void intel_update_watermarks(struct drm_device *dev) | ||
1951 | { | ||
1952 | struct drm_crtc *crtc; | ||
1953 | struct intel_crtc *intel_crtc; | ||
1954 | int sr_hdisplay = 0; | ||
1955 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | ||
1956 | int enabled = 0, pixel_size = 0; | ||
1957 | |||
1958 | if (DSPARB_HWCONTROL(dev)) | ||
1959 | return; | ||
1960 | |||
1961 | /* Get the clock config from both planes */ | ||
1962 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
1963 | intel_crtc = to_intel_crtc(crtc); | ||
1964 | if (crtc->enabled) { | ||
1965 | enabled++; | ||
1966 | if (intel_crtc->plane == 0) { | ||
1967 | DRM_DEBUG("plane A (pipe %d) clock: %d\n", | ||
1968 | intel_crtc->pipe, crtc->mode.clock); | ||
1969 | planea_clock = crtc->mode.clock; | ||
1970 | } else { | ||
1971 | DRM_DEBUG("plane B (pipe %d) clock: %d\n", | ||
1972 | intel_crtc->pipe, crtc->mode.clock); | ||
1973 | planeb_clock = crtc->mode.clock; | ||
1974 | } | ||
1975 | sr_hdisplay = crtc->mode.hdisplay; | ||
1976 | sr_clock = crtc->mode.clock; | ||
1977 | if (crtc->fb) | ||
1978 | pixel_size = crtc->fb->bits_per_pixel / 8; | ||
1979 | else | ||
1980 | pixel_size = 4; /* by default */ | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | if (enabled <= 0) | ||
1985 | return; | ||
1986 | |||
1987 | /* Single pipe configs can enable self refresh */ | ||
1988 | if (enabled == 1 && IS_IGD(dev)) | ||
1989 | igd_enable_cxsr(dev, sr_clock, pixel_size); | ||
1990 | else if (IS_IGD(dev)) | ||
1991 | igd_disable_cxsr(dev); | ||
1992 | |||
1993 | if (IS_I965G(dev)) | ||
1994 | i965_update_wm(dev); | ||
1995 | else if (IS_I9XX(dev) || IS_MOBILE(dev)) | ||
1996 | i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, | ||
1997 | pixel_size); | ||
1998 | else | ||
1999 | i830_update_wm(dev, planea_clock, pixel_size); | ||
2000 | } | ||
2001 | |||
1588 | static int intel_crtc_mode_set(struct drm_crtc *crtc, | 2002 | static int intel_crtc_mode_set(struct drm_crtc *crtc, |
1589 | struct drm_display_mode *mode, | 2003 | struct drm_display_mode *mode, |
1590 | struct drm_display_mode *adjusted_mode, | 2004 | struct drm_display_mode *adjusted_mode, |
@@ -1951,6 +2365,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1951 | 2365 | ||
1952 | /* Flush the plane changes */ | 2366 | /* Flush the plane changes */ |
1953 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 2367 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
2368 | |||
2369 | intel_update_watermarks(dev); | ||
2370 | |||
1954 | drm_vblank_post_modeset(dev, pipe); | 2371 | drm_vblank_post_modeset(dev, pipe); |
1955 | 2372 | ||
1956 | return ret; | 2373 | return ret; |
@@ -2439,6 +2856,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
2439 | 2856 | ||
2440 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); | 2857 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
2441 | intel_crtc->pipe = pipe; | 2858 | intel_crtc->pipe = pipe; |
2859 | intel_crtc->plane = pipe; | ||
2442 | for (i = 0; i < 256; i++) { | 2860 | for (i = 0; i < 256; i++) { |
2443 | intel_crtc->lut_r[i] = i; | 2861 | intel_crtc->lut_r[i] = i; |
2444 | intel_crtc->lut_g[i] = i; | 2862 | intel_crtc->lut_g[i] = i; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8f8d37d5663a..6770ae88370d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -246,7 +246,7 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
246 | } | 246 | } |
247 | 247 | ||
248 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { | 248 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { |
249 | printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status); | 249 | DRM_ERROR("dp_aux_ch not done status 0x%08x\n", status); |
250 | return -EBUSY; | 250 | return -EBUSY; |
251 | } | 251 | } |
252 | 252 | ||
@@ -254,11 +254,14 @@ intel_dp_aux_ch(struct intel_output *intel_output, | |||
254 | * Timeouts occur when the sink is not connected | 254 | * Timeouts occur when the sink is not connected |
255 | */ | 255 | */ |
256 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { | 256 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { |
257 | printk(KERN_ERR "dp_aux_ch receive error status 0x%08x\n", status); | 257 | DRM_ERROR("dp_aux_ch receive error status 0x%08x\n", status); |
258 | return -EIO; | 258 | return -EIO; |
259 | } | 259 | } |
260 | |||
261 | /* Timeouts occur when the device isn't connected, so they're | ||
262 | * "normal" -- don't fill the kernel log with these */ | ||
260 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { | 263 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { |
261 | printk(KERN_ERR "dp_aux_ch timeout status 0x%08x\n", status); | 264 | DRM_DEBUG("dp_aux_ch timeout status 0x%08x\n", status); |
262 | return -ETIMEDOUT; | 265 | return -ETIMEDOUT; |
263 | } | 266 | } |
264 | 267 | ||
@@ -411,7 +414,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
411 | dp_priv->link_bw = bws[clock]; | 414 | dp_priv->link_bw = bws[clock]; |
412 | dp_priv->lane_count = lane_count; | 415 | dp_priv->lane_count = lane_count; |
413 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 416 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); |
414 | printk(KERN_ERR "link bw %02x lane count %d clock %d\n", | 417 | DRM_DEBUG("Display port link bw %02x lane count %d clock %d\n", |
415 | dp_priv->link_bw, dp_priv->lane_count, | 418 | dp_priv->link_bw, dp_priv->lane_count, |
416 | adjusted_mode->clock); | 419 | adjusted_mode->clock); |
417 | return true; | 420 | return true; |
diff --git a/drivers/gpu/drm/i915/intel_dp_i2c.c b/drivers/gpu/drm/i915/intel_dp_i2c.c index 4e60f14b1a6d..a63b6f57d2d4 100644 --- a/drivers/gpu/drm/i915/intel_dp_i2c.c +++ b/drivers/gpu/drm/i915/intel_dp_i2c.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
31 | #include "intel_dp.h" | 31 | #include "intel_dp.h" |
32 | #include "drmP.h" | ||
32 | 33 | ||
33 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ | 34 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ |
34 | 35 | ||
@@ -84,7 +85,7 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | |||
84 | msg, msg_bytes, | 85 | msg, msg_bytes, |
85 | reply, reply_bytes); | 86 | reply, reply_bytes); |
86 | if (ret < 0) { | 87 | if (ret < 0) { |
87 | printk(KERN_ERR "aux_ch failed %d\n", ret); | 88 | DRM_DEBUG("aux_ch failed %d\n", ret); |
88 | return ret; | 89 | return ret; |
89 | } | 90 | } |
90 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | 91 | switch (reply[0] & AUX_I2C_REPLY_MASK) { |
@@ -94,14 +95,14 @@ i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | |||
94 | } | 95 | } |
95 | return reply_bytes - 1; | 96 | return reply_bytes - 1; |
96 | case AUX_I2C_REPLY_NACK: | 97 | case AUX_I2C_REPLY_NACK: |
97 | printk(KERN_ERR "aux_ch nack\n"); | 98 | DRM_DEBUG("aux_ch nack\n"); |
98 | return -EREMOTEIO; | 99 | return -EREMOTEIO; |
99 | case AUX_I2C_REPLY_DEFER: | 100 | case AUX_I2C_REPLY_DEFER: |
100 | printk(KERN_ERR "aux_ch defer\n"); | 101 | DRM_DEBUG("aux_ch defer\n"); |
101 | udelay(100); | 102 | udelay(100); |
102 | break; | 103 | break; |
103 | default: | 104 | default: |
104 | printk(KERN_ERR "aux_ch invalid reply 0x%02x\n", reply[0]); | 105 | DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); |
105 | return -EREMOTEIO; | 106 | return -EREMOTEIO; |
106 | } | 107 | } |
107 | } | 108 | } |
@@ -223,7 +224,7 @@ i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, | |||
223 | if (ret >= 0) | 224 | if (ret >= 0) |
224 | ret = num; | 225 | ret = num; |
225 | i2c_algo_dp_aux_stop(adapter, reading); | 226 | i2c_algo_dp_aux_stop(adapter, reading); |
226 | printk(KERN_ERR "dp_aux_xfer return %d\n", ret); | 227 | DRM_DEBUG("dp_aux_xfer return %d\n", ret); |
227 | return ret; | 228 | return ret; |
228 | } | 229 | } |
229 | 230 | ||
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 1af7d68e3807..1d30802e773e 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -453,7 +453,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
453 | size = ALIGN(size, PAGE_SIZE); | 453 | size = ALIGN(size, PAGE_SIZE); |
454 | fbo = drm_gem_object_alloc(dev, size); | 454 | fbo = drm_gem_object_alloc(dev, size); |
455 | if (!fbo) { | 455 | if (!fbo) { |
456 | printk(KERN_ERR "failed to allocate framebuffer\n"); | 456 | DRM_ERROR("failed to allocate framebuffer\n"); |
457 | ret = -ENOMEM; | 457 | ret = -ENOMEM; |
458 | goto out; | 458 | goto out; |
459 | } | 459 | } |
@@ -610,8 +610,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
610 | par->dev = dev; | 610 | par->dev = dev; |
611 | 611 | ||
612 | /* To allow resizeing without swapping buffers */ | 612 | /* To allow resizeing without swapping buffers */ |
613 | printk("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, | 613 | DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, |
614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); | 614 | intel_fb->base.height, obj_priv->gtt_offset, fbo); |
615 | 615 | ||
616 | mutex_unlock(&dev->struct_mutex); | 616 | mutex_unlock(&dev->struct_mutex); |
617 | return 0; | 617 | return 0; |
@@ -698,13 +698,13 @@ static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc * | |||
698 | } else | 698 | } else |
699 | intelfb_set_par(info); | 699 | intelfb_set_par(info); |
700 | 700 | ||
701 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 701 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
702 | info->fix.id); | 702 | info->fix.id); |
703 | 703 | ||
704 | /* Switch back to kernel console on panic */ | 704 | /* Switch back to kernel console on panic */ |
705 | kernelfb_mode = *modeset; | 705 | kernelfb_mode = *modeset; |
706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 706 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
707 | printk(KERN_INFO "registered panic notifier\n"); | 707 | DRM_DEBUG("registered panic notifier\n"); |
708 | 708 | ||
709 | return 0; | 709 | return 0; |
710 | } | 710 | } |
@@ -852,13 +852,13 @@ static int intelfb_single_fb_probe(struct drm_device *dev) | |||
852 | } else | 852 | } else |
853 | intelfb_set_par(info); | 853 | intelfb_set_par(info); |
854 | 854 | ||
855 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, | 855 | DRM_INFO("fb%d: %s frame buffer device\n", info->node, |
856 | info->fix.id); | 856 | info->fix.id); |
857 | 857 | ||
858 | /* Switch back to kernel console on panic */ | 858 | /* Switch back to kernel console on panic */ |
859 | kernelfb_mode = *modeset; | 859 | kernelfb_mode = *modeset; |
860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); | 860 | atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
861 | printk(KERN_INFO "registered panic notifier\n"); | 861 | DRM_DEBUG("registered panic notifier\n"); |
862 | 862 | ||
863 | return 0; | 863 | return 0; |
864 | } | 864 | } |
@@ -872,8 +872,8 @@ void intelfb_restore(void) | |||
872 | { | 872 | { |
873 | int ret; | 873 | int ret; |
874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { | 874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { |
875 | printk(KERN_ERR "Failed to restore crtc configuration: %d\n", | 875 | DRM_ERROR("Failed to restore crtc configuration: %d\n", |
876 | ret); | 876 | ret); |
877 | } | 877 | } |
878 | } | 878 | } |
879 | 879 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 9564ca44a977..9ab38efffecf 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "intel_drv.h" | 36 | #include "intel_drv.h" |
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | #include <linux/acpi.h> | ||
39 | 40 | ||
40 | #define I915_LVDS "i915_lvds" | 41 | #define I915_LVDS "i915_lvds" |
41 | 42 | ||
@@ -252,14 +253,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
252 | 253 | ||
253 | /* Should never happen!! */ | 254 | /* Should never happen!! */ |
254 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 255 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
255 | printk(KERN_ERR "Can't support LVDS on pipe A\n"); | 256 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
256 | return false; | 257 | return false; |
257 | } | 258 | } |
258 | 259 | ||
259 | /* Should never happen!! */ | 260 | /* Should never happen!! */ |
260 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { | 261 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { |
261 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { | 262 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { |
262 | printk(KERN_ERR "Can't enable LVDS and another " | 263 | DRM_ERROR("Can't enable LVDS and another " |
263 | "encoder on the same pipe\n"); | 264 | "encoder on the same pipe\n"); |
264 | return false; | 265 | return false; |
265 | } | 266 | } |
@@ -788,6 +789,65 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
788 | { } /* terminating entry */ | 789 | { } /* terminating entry */ |
789 | }; | 790 | }; |
790 | 791 | ||
792 | #ifdef CONFIG_ACPI | ||
793 | /* | ||
794 | * check_lid_device -- check whether @handle is an ACPI LID device. | ||
795 | * @handle: ACPI device handle | ||
796 | * @level : depth in the ACPI namespace tree | ||
797 | * @context: the number of LID device when we find the device | ||
798 | * @rv: a return value to fill if desired (Not use) | ||
799 | */ | ||
800 | static acpi_status | ||
801 | check_lid_device(acpi_handle handle, u32 level, void *context, | ||
802 | void **return_value) | ||
803 | { | ||
804 | struct acpi_device *acpi_dev; | ||
805 | int *lid_present = context; | ||
806 | |||
807 | acpi_dev = NULL; | ||
808 | /* Get the acpi device for device handle */ | ||
809 | if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { | ||
810 | /* If there is no ACPI device for handle, return */ | ||
811 | return AE_OK; | ||
812 | } | ||
813 | |||
814 | if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) | ||
815 | *lid_present = 1; | ||
816 | |||
817 | return AE_OK; | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * check whether there exists the ACPI LID device by enumerating the ACPI | ||
822 | * device tree. | ||
823 | */ | ||
824 | static int intel_lid_present(void) | ||
825 | { | ||
826 | int lid_present = 0; | ||
827 | |||
828 | if (acpi_disabled) { | ||
829 | /* If ACPI is disabled, there is no ACPI device tree to | ||
830 | * check, so assume the LID device would have been present. | ||
831 | */ | ||
832 | return 1; | ||
833 | } | ||
834 | |||
835 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
836 | ACPI_UINT32_MAX, | ||
837 | check_lid_device, &lid_present, NULL); | ||
838 | |||
839 | return lid_present; | ||
840 | } | ||
841 | #else | ||
842 | static int intel_lid_present(void) | ||
843 | { | ||
844 | /* In the absence of ACPI built in, assume that the LID device would | ||
845 | * have been present. | ||
846 | */ | ||
847 | return 1; | ||
848 | } | ||
849 | #endif | ||
850 | |||
791 | /** | 851 | /** |
792 | * intel_lvds_init - setup LVDS connectors on this device | 852 | * intel_lvds_init - setup LVDS connectors on this device |
793 | * @dev: drm device | 853 | * @dev: drm device |
@@ -811,6 +871,16 @@ void intel_lvds_init(struct drm_device *dev) | |||
811 | if (dmi_check_system(intel_no_lvds)) | 871 | if (dmi_check_system(intel_no_lvds)) |
812 | return; | 872 | return; |
813 | 873 | ||
874 | /* Assume that any device without an ACPI LID device also doesn't | ||
875 | * have an integrated LVDS. We would be better off parsing the BIOS | ||
876 | * to get a reliable indicator, but that code isn't written yet. | ||
877 | * | ||
878 | * In the case of all-in-one desktops using LVDS that we've seen, | ||
879 | * they're using SDVO LVDS. | ||
880 | */ | ||
881 | if (!intel_lid_present()) | ||
882 | return; | ||
883 | |||
814 | if (IS_IGDNG(dev)) { | 884 | if (IS_IGDNG(dev)) { |
815 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 885 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
816 | return; | 886 | return; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f03473779feb..4f0c30948bc4 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -68,12 +68,23 @@ struct intel_sdvo_priv { | |||
68 | * This is set if we treat the device as HDMI, instead of DVI. | 68 | * This is set if we treat the device as HDMI, instead of DVI. |
69 | */ | 69 | */ |
70 | bool is_hdmi; | 70 | bool is_hdmi; |
71 | |||
71 | /** | 72 | /** |
72 | * This is set if we detect output of sdvo device as LVDS. | 73 | * This is set if we detect output of sdvo device as LVDS. |
73 | */ | 74 | */ |
74 | bool is_lvds; | 75 | bool is_lvds; |
75 | 76 | ||
76 | /** | 77 | /** |
78 | * This is sdvo flags for input timing. | ||
79 | */ | ||
80 | uint8_t sdvo_flags; | ||
81 | |||
82 | /** | ||
83 | * This is sdvo fixed pannel mode pointer | ||
84 | */ | ||
85 | struct drm_display_mode *sdvo_lvds_fixed_mode; | ||
86 | |||
87 | /** | ||
77 | * Returned SDTV resolutions allowed for the current format, if the | 88 | * Returned SDTV resolutions allowed for the current format, if the |
78 | * device reported it. | 89 | * device reported it. |
79 | */ | 90 | */ |
@@ -592,6 +603,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
592 | uint16_t height) | 603 | uint16_t height) |
593 | { | 604 | { |
594 | struct intel_sdvo_preferred_input_timing_args args; | 605 | struct intel_sdvo_preferred_input_timing_args args; |
606 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | ||
595 | uint8_t status; | 607 | uint8_t status; |
596 | 608 | ||
597 | memset(&args, 0, sizeof(args)); | 609 | memset(&args, 0, sizeof(args)); |
@@ -599,7 +611,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
599 | args.width = width; | 611 | args.width = width; |
600 | args.height = height; | 612 | args.height = height; |
601 | args.interlace = 0; | 613 | args.interlace = 0; |
602 | args.scaled = 0; | 614 | |
615 | if (sdvo_priv->is_lvds && | ||
616 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | ||
617 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | ||
618 | args.scaled = 1; | ||
619 | |||
603 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 620 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
604 | &args, sizeof(args)); | 621 | &args, sizeof(args)); |
605 | status = intel_sdvo_read_response(output, NULL, 0); | 622 | status = intel_sdvo_read_response(output, NULL, 0); |
@@ -944,12 +961,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
944 | struct intel_output *output = enc_to_intel_output(encoder); | 961 | struct intel_output *output = enc_to_intel_output(encoder); |
945 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | 962 | struct intel_sdvo_priv *dev_priv = output->dev_priv; |
946 | 963 | ||
947 | if (!dev_priv->is_tv) { | 964 | if (dev_priv->is_tv) { |
948 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
949 | * SDVO device will be told of the multiplier during mode_set. | ||
950 | */ | ||
951 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
952 | } else { | ||
953 | struct intel_sdvo_dtd output_dtd; | 965 | struct intel_sdvo_dtd output_dtd; |
954 | bool success; | 966 | bool success; |
955 | 967 | ||
@@ -980,6 +992,47 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
980 | intel_sdvo_get_preferred_input_timing(output, | 992 | intel_sdvo_get_preferred_input_timing(output, |
981 | &input_dtd); | 993 | &input_dtd); |
982 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 994 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
995 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
996 | |||
997 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
998 | |||
999 | mode->clock = adjusted_mode->clock; | ||
1000 | |||
1001 | adjusted_mode->clock *= | ||
1002 | intel_sdvo_get_pixel_multiplier(mode); | ||
1003 | } else { | ||
1004 | return false; | ||
1005 | } | ||
1006 | } else if (dev_priv->is_lvds) { | ||
1007 | struct intel_sdvo_dtd output_dtd; | ||
1008 | bool success; | ||
1009 | |||
1010 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1011 | /* Set output timings */ | ||
1012 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1013 | dev_priv->sdvo_lvds_fixed_mode); | ||
1014 | |||
1015 | intel_sdvo_set_target_output(output, | ||
1016 | dev_priv->controlled_output); | ||
1017 | intel_sdvo_set_output_timing(output, &output_dtd); | ||
1018 | |||
1019 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1020 | intel_sdvo_set_target_input(output, true, false); | ||
1021 | |||
1022 | |||
1023 | success = intel_sdvo_create_preferred_input_timing( | ||
1024 | output, | ||
1025 | mode->clock / 10, | ||
1026 | mode->hdisplay, | ||
1027 | mode->vdisplay); | ||
1028 | |||
1029 | if (success) { | ||
1030 | struct intel_sdvo_dtd input_dtd; | ||
1031 | |||
1032 | intel_sdvo_get_preferred_input_timing(output, | ||
1033 | &input_dtd); | ||
1034 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1035 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
983 | 1036 | ||
984 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1037 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
985 | 1038 | ||
@@ -990,6 +1043,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
990 | } else { | 1043 | } else { |
991 | return false; | 1044 | return false; |
992 | } | 1045 | } |
1046 | |||
1047 | } else { | ||
1048 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1049 | * SDVO device will be told of the multiplier during mode_set. | ||
1050 | */ | ||
1051 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
993 | } | 1052 | } |
994 | return true; | 1053 | return true; |
995 | } | 1054 | } |
@@ -1033,15 +1092,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1033 | 1092 | ||
1034 | /* We have tried to get input timing in mode_fixup, and filled into | 1093 | /* We have tried to get input timing in mode_fixup, and filled into |
1035 | adjusted_mode */ | 1094 | adjusted_mode */ |
1036 | if (sdvo_priv->is_tv) | 1095 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { |
1037 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1096 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1038 | else | 1097 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; |
1098 | } else | ||
1039 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1099 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
1040 | 1100 | ||
1041 | /* If it's a TV, we already set the output timing in mode_fixup. | 1101 | /* If it's a TV, we already set the output timing in mode_fixup. |
1042 | * Otherwise, the output timing is equal to the input timing. | 1102 | * Otherwise, the output timing is equal to the input timing. |
1043 | */ | 1103 | */ |
1044 | if (!sdvo_priv->is_tv) { | 1104 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1045 | /* Set the output timing to the screen */ | 1105 | /* Set the output timing to the screen */ |
1046 | intel_sdvo_set_target_output(output, | 1106 | intel_sdvo_set_target_output(output, |
1047 | sdvo_priv->controlled_output); | 1107 | sdvo_priv->controlled_output); |
@@ -1116,6 +1176,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1116 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1176 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1117 | } | 1177 | } |
1118 | 1178 | ||
1179 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | ||
1180 | sdvox |= SDVO_STALL_SELECT; | ||
1119 | intel_sdvo_write_sdvox(output, sdvox); | 1181 | intel_sdvo_write_sdvox(output, sdvox); |
1120 | } | 1182 | } |
1121 | 1183 | ||
@@ -1276,6 +1338,17 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1276 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1338 | if (sdvo_priv->pixel_clock_max < mode->clock) |
1277 | return MODE_CLOCK_HIGH; | 1339 | return MODE_CLOCK_HIGH; |
1278 | 1340 | ||
1341 | if (sdvo_priv->is_lvds == true) { | ||
1342 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | ||
1343 | return MODE_PANEL; | ||
1344 | |||
1345 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | ||
1346 | return MODE_PANEL; | ||
1347 | |||
1348 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1349 | return MODE_PANEL; | ||
1350 | } | ||
1351 | |||
1279 | return MODE_OK; | 1352 | return MODE_OK; |
1280 | } | 1353 | } |
1281 | 1354 | ||
@@ -1549,6 +1622,8 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1549 | { | 1622 | { |
1550 | struct intel_output *intel_output = to_intel_output(connector); | 1623 | struct intel_output *intel_output = to_intel_output(connector); |
1551 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1624 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1625 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1626 | struct drm_display_mode *newmode; | ||
1552 | 1627 | ||
1553 | /* | 1628 | /* |
1554 | * Attempt to get the mode list from DDC. | 1629 | * Attempt to get the mode list from DDC. |
@@ -1557,11 +1632,10 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1557 | */ | 1632 | */ |
1558 | intel_ddc_get_modes(intel_output); | 1633 | intel_ddc_get_modes(intel_output); |
1559 | if (list_empty(&connector->probed_modes) == false) | 1634 | if (list_empty(&connector->probed_modes) == false) |
1560 | return; | 1635 | goto end; |
1561 | 1636 | ||
1562 | /* Fetch modes from VBT */ | 1637 | /* Fetch modes from VBT */ |
1563 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { | 1638 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
1564 | struct drm_display_mode *newmode; | ||
1565 | newmode = drm_mode_duplicate(connector->dev, | 1639 | newmode = drm_mode_duplicate(connector->dev, |
1566 | dev_priv->sdvo_lvds_vbt_mode); | 1640 | dev_priv->sdvo_lvds_vbt_mode); |
1567 | if (newmode != NULL) { | 1641 | if (newmode != NULL) { |
@@ -1571,6 +1645,16 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1571 | drm_mode_probed_add(connector, newmode); | 1645 | drm_mode_probed_add(connector, newmode); |
1572 | } | 1646 | } |
1573 | } | 1647 | } |
1648 | |||
1649 | end: | ||
1650 | list_for_each_entry(newmode, &connector->probed_modes, head) { | ||
1651 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1652 | sdvo_priv->sdvo_lvds_fixed_mode = | ||
1653 | drm_mode_duplicate(connector->dev, newmode); | ||
1654 | break; | ||
1655 | } | ||
1656 | } | ||
1657 | |||
1574 | } | 1658 | } |
1575 | 1659 | ||
1576 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1660 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
@@ -1593,14 +1677,20 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1593 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1677 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1594 | { | 1678 | { |
1595 | struct intel_output *intel_output = to_intel_output(connector); | 1679 | struct intel_output *intel_output = to_intel_output(connector); |
1680 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1596 | 1681 | ||
1597 | if (intel_output->i2c_bus) | 1682 | if (intel_output->i2c_bus) |
1598 | intel_i2c_destroy(intel_output->i2c_bus); | 1683 | intel_i2c_destroy(intel_output->i2c_bus); |
1599 | if (intel_output->ddc_bus) | 1684 | if (intel_output->ddc_bus) |
1600 | intel_i2c_destroy(intel_output->ddc_bus); | 1685 | intel_i2c_destroy(intel_output->ddc_bus); |
1601 | 1686 | ||
1687 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1688 | drm_mode_destroy(connector->dev, | ||
1689 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1690 | |||
1602 | drm_sysfs_connector_remove(connector); | 1691 | drm_sysfs_connector_remove(connector); |
1603 | drm_connector_cleanup(connector); | 1692 | drm_connector_cleanup(connector); |
1693 | |||
1604 | kfree(intel_output); | 1694 | kfree(intel_output); |
1605 | } | 1695 | } |
1606 | 1696 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index 193938b7d7f9..ba5cdf8ae40b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
@@ -715,6 +715,7 @@ struct intel_sdvo_enhancements_arg { | |||
715 | #define SDVO_HBUF_TX_ONCE (2 << 6) | 715 | #define SDVO_HBUF_TX_ONCE (2 << 6) |
716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) | 716 | #define SDVO_HBUF_TX_VSYNC (3 << 6) |
717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c | 717 | #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c |
718 | #define SDVO_NEED_TO_STALL (1 << 7) | ||
718 | 719 | ||
719 | struct intel_sdvo_encode{ | 720 | struct intel_sdvo_encode{ |
720 | u8 dvi_rev; | 721 | u8 dvi_rev; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 40b75032ea47..fe949a12fe40 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c | |||
@@ -327,7 +327,7 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp, | |||
327 | goto out_unref; | 327 | goto out_unref; |
328 | 328 | ||
329 | kmap_offset = dev_offset - bo->vm_node->start; | 329 | kmap_offset = dev_offset - bo->vm_node->start; |
330 | if (unlikely(kmap_offset) >= bo->num_pages) { | 330 | if (unlikely(kmap_offset >= bo->num_pages)) { |
331 | ret = -EFBIG; | 331 | ret = -EFBIG; |
332 | goto out_unref; | 332 | goto out_unref; |
333 | } | 333 | } |
@@ -401,7 +401,7 @@ ssize_t ttm_bo_fbdev_io(struct ttm_buffer_object *bo, const char __user *wbuf, | |||
401 | bool dummy; | 401 | bool dummy; |
402 | 402 | ||
403 | kmap_offset = (*f_pos >> PAGE_SHIFT); | 403 | kmap_offset = (*f_pos >> PAGE_SHIFT); |
404 | if (unlikely(kmap_offset) >= bo->num_pages) | 404 | if (unlikely(kmap_offset >= bo->num_pages)) |
405 | return -EFBIG; | 405 | return -EFBIG; |
406 | 406 | ||
407 | page_offset = *f_pos & ~PAGE_MASK; | 407 | page_offset = *f_pos & ~PAGE_MASK; |
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index c248c1d37268..5935b8842e86 100644 --- a/drivers/gpu/drm/via/via_irq.c +++ b/drivers/gpu/drm/via/via_irq.c | |||
@@ -183,7 +183,7 @@ int via_enable_vblank(struct drm_device *dev, int crtc) | |||
183 | } | 183 | } |
184 | 184 | ||
185 | status = VIA_READ(VIA_REG_INTERRUPT); | 185 | status = VIA_READ(VIA_REG_INTERRUPT); |
186 | VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE); | 186 | VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_VBLANK_ENABLE); |
187 | 187 | ||
188 | VIA_WRITE8(0x83d4, 0x11); | 188 | VIA_WRITE8(0x83d4, 0x11); |
189 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); | 189 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30); |
@@ -194,6 +194,10 @@ int via_enable_vblank(struct drm_device *dev, int crtc) | |||
194 | void via_disable_vblank(struct drm_device *dev, int crtc) | 194 | void via_disable_vblank(struct drm_device *dev, int crtc) |
195 | { | 195 | { |
196 | drm_via_private_t *dev_priv = dev->dev_private; | 196 | drm_via_private_t *dev_priv = dev->dev_private; |
197 | u32 status; | ||
198 | |||
199 | status = VIA_READ(VIA_REG_INTERRUPT); | ||
200 | VIA_WRITE(VIA_REG_INTERRUPT, status & ~VIA_IRQ_VBLANK_ENABLE); | ||
197 | 201 | ||
198 | VIA_WRITE8(0x83d4, 0x11); | 202 | VIA_WRITE8(0x83d4, 0x11); |
199 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); | 203 | VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30); |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f2c21d5d24e8..5eb10c2ce665 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1075,14 +1075,16 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event); | |||
1075 | */ | 1075 | */ |
1076 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) | 1076 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) |
1077 | { | 1077 | { |
1078 | struct hid_report_enum *report_enum = hid->report_enum + type; | 1078 | struct hid_report_enum *report_enum; |
1079 | struct hid_driver *hdrv = hid->driver; | 1079 | struct hid_driver *hdrv; |
1080 | struct hid_report *report; | 1080 | struct hid_report *report; |
1081 | unsigned int i; | 1081 | unsigned int i; |
1082 | int ret; | 1082 | int ret; |
1083 | 1083 | ||
1084 | if (!hid || !hid->driver) | 1084 | if (!hid || !hid->driver) |
1085 | return -ENODEV; | 1085 | return -ENODEV; |
1086 | report_enum = hid->report_enum + type; | ||
1087 | hdrv = hid->driver; | ||
1086 | 1088 | ||
1087 | if (!size) { | 1089 | if (!size) { |
1088 | dbg_hid("empty report\n"); | 1090 | dbg_hid("empty report\n"); |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 76c4bbe9dccb..3c1fcb7640ab 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/list.h> | 22 | #include <linux/list.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
27 | #include <asm/unaligned.h> | 26 | #include <asm/unaligned.h> |
28 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 9e9421525fb9..215b2addddbb 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -527,8 +527,10 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, | |||
527 | goto goodreturn; | 527 | goto goodreturn; |
528 | 528 | ||
529 | case HIDIOCGCOLLECTIONINDEX: | 529 | case HIDIOCGCOLLECTIONINDEX: |
530 | i = field->usage[uref->usage_index].collection_index; | ||
531 | unlock_kernel(); | ||
530 | kfree(uref_multi); | 532 | kfree(uref_multi); |
531 | return field->usage[uref->usage_index].collection_index; | 533 | return i; |
532 | case HIDIOCGUSAGES: | 534 | case HIDIOCGUSAGES: |
533 | for (i = 0; i < uref_multi->num_values; i++) | 535 | for (i = 0; i < uref_multi->num_values; i++) |
534 | uref_multi->values[i] = | 536 | uref_multi->values[i] = |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index ad2b3431b725..7d3f15d32fdf 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -357,7 +357,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
357 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 357 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
358 | { NULL, 0, 0, 0, 0, 0 } } | 358 | { NULL, 0, 0, 0, 0, 0 } } |
359 | }, | 359 | }, |
360 | { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, { | 360 | { 0x0014, "AB9", /* + AB9 Pro */ { |
361 | { "CPU Core", 0, 0, 10, 1, 0 }, | 361 | { "CPU Core", 0, 0, 10, 1, 0 }, |
362 | { "DDR", 1, 0, 10, 1, 0 }, | 362 | { "DDR", 1, 0, 10, 1, 0 }, |
363 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 363 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
@@ -455,7 +455,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
455 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, | 455 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, |
456 | { NULL, 0, 0, 0, 0, 0 } } | 456 | { NULL, 0, 0, 0, 0, 0 } } |
457 | }, | 457 | }, |
458 | { 0x0018, NULL /* Unknown, need DMI string */, { | 458 | { 0x0018, "AB9 QuadGT", { |
459 | { "CPU Core", 0, 0, 10, 1, 0 }, | 459 | { "CPU Core", 0, 0, 10, 1, 0 }, |
460 | { "DDR2", 1, 0, 20, 1, 0 }, | 460 | { "DDR2", 1, 0, 20, 1, 0 }, |
461 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 461 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -564,7 +564,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
564 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 564 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
565 | { NULL, 0, 0, 0, 0, 0 } } | 565 | { NULL, 0, 0, 0, 0, 0 } } |
566 | }, | 566 | }, |
567 | { 0x001C, NULL /* Unknown, need DMI string */, { | 567 | { 0x001C, "IX38 QuadGT", { |
568 | { "CPU Core", 0, 0, 10, 1, 0 }, | 568 | { "CPU Core", 0, 0, 10, 1, 0 }, |
569 | { "DDR2", 1, 0, 20, 1, 0 }, | 569 | { "DDR2", 1, 0, 20, 1, 0 }, |
570 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 570 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c index 86142a858238..58f66be61b1f 100644 --- a/drivers/hwmon/max6650.c +++ b/drivers/hwmon/max6650.c | |||
@@ -418,6 +418,7 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr, | |||
418 | data->count = 3; | 418 | data->count = 3; |
419 | break; | 419 | break; |
420 | default: | 420 | default: |
421 | mutex_unlock(&data->update_lock); | ||
421 | dev_err(&client->dev, | 422 | dev_err(&client->dev, |
422 | "illegal value for fan divider (%d)\n", div); | 423 | "illegal value for fan divider (%d)\n", div); |
423 | return -EINVAL; | 424 | return -EINVAL; |
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 56cd6004da36..6290a259456e 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
@@ -257,7 +257,7 @@ static inline int sht15_update_single_val(struct sht15_data *data, | |||
257 | (data->flag == SHT15_READING_NOTHING), | 257 | (data->flag == SHT15_READING_NOTHING), |
258 | msecs_to_jiffies(timeout_msecs)); | 258 | msecs_to_jiffies(timeout_msecs)); |
259 | if (ret == 0) {/* timeout occurred */ | 259 | if (ret == 0) {/* timeout occurred */ |
260 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));; | 260 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); |
261 | sht15_connection_reset(data); | 261 | sht15_connection_reset(data); |
262 | return -ETIME; | 262 | return -ETIME; |
263 | } | 263 | } |
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 3fae3a91ce5b..c89687a10835 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -187,6 +187,11 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) | |||
187 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); | 187 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); |
188 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); | 188 | davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); |
189 | 189 | ||
190 | /* Respond at reserved "SMBus Host" slave address" (and zero); | ||
191 | * we seem to have no option to not respond... | ||
192 | */ | ||
193 | davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); | ||
194 | |||
190 | dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); | 195 | dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); |
191 | dev_dbg(dev->dev, "PSC = %d\n", | 196 | dev_dbg(dev->dev, "PSC = %d\n", |
192 | davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); | 197 | davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); |
@@ -387,7 +392,7 @@ static void terminate_write(struct davinci_i2c_dev *dev) | |||
387 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); | 392 | davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); |
388 | 393 | ||
389 | if (!dev->terminate) | 394 | if (!dev->terminate) |
390 | dev_err(dev->dev, "TDR IRQ while no data to send\n"); | 395 | dev_dbg(dev->dev, "TDR IRQ while no data to send\n"); |
391 | } | 396 | } |
392 | 397 | ||
393 | /* | 398 | /* |
@@ -473,9 +478,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) | |||
473 | break; | 478 | break; |
474 | 479 | ||
475 | case DAVINCI_I2C_IVR_AAS: | 480 | case DAVINCI_I2C_IVR_AAS: |
476 | dev_warn(dev->dev, "Address as slave interrupt\n"); | 481 | dev_dbg(dev->dev, "Address as slave interrupt\n"); |
477 | }/* switch */ | 482 | break; |
478 | }/* while */ | 483 | |
484 | default: | ||
485 | dev_warn(dev->dev, "Unrecognized irq stat %d\n", stat); | ||
486 | break; | ||
487 | } | ||
488 | } | ||
479 | 489 | ||
480 | return count ? IRQ_HANDLED : IRQ_NONE; | 490 | return count ? IRQ_HANDLED : IRQ_NONE; |
481 | } | 491 | } |
@@ -505,7 +515,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) | |||
505 | return -ENODEV; | 515 | return -ENODEV; |
506 | } | 516 | } |
507 | 517 | ||
508 | ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, | 518 | ioarea = request_mem_region(mem->start, resource_size(mem), |
509 | pdev->name); | 519 | pdev->name); |
510 | if (!ioarea) { | 520 | if (!ioarea) { |
511 | dev_err(&pdev->dev, "I2C region already claimed\n"); | 521 | dev_err(&pdev->dev, "I2C region already claimed\n"); |
@@ -523,7 +533,7 @@ static int davinci_i2c_probe(struct platform_device *pdev) | |||
523 | dev->irq = irq->start; | 533 | dev->irq = irq->start; |
524 | platform_set_drvdata(pdev, dev); | 534 | platform_set_drvdata(pdev, dev); |
525 | 535 | ||
526 | dev->clk = clk_get(&pdev->dev, "I2CCLK"); | 536 | dev->clk = clk_get(&pdev->dev, NULL); |
527 | if (IS_ERR(dev->clk)) { | 537 | if (IS_ERR(dev->clk)) { |
528 | r = -ENODEV; | 538 | r = -ENODEV; |
529 | goto err_free_mem; | 539 | goto err_free_mem; |
@@ -568,7 +578,7 @@ err_free_mem: | |||
568 | put_device(&pdev->dev); | 578 | put_device(&pdev->dev); |
569 | kfree(dev); | 579 | kfree(dev); |
570 | err_release_region: | 580 | err_release_region: |
571 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 581 | release_mem_region(mem->start, resource_size(mem)); |
572 | 582 | ||
573 | return r; | 583 | return r; |
574 | } | 584 | } |
@@ -591,7 +601,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) | |||
591 | kfree(dev); | 601 | kfree(dev); |
592 | 602 | ||
593 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 603 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
594 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 604 | release_mem_region(mem->start, resource_size(mem)); |
595 | return 0; | 605 | return 0; |
596 | } | 606 | } |
597 | 607 | ||
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index ad8d2010c921..fdd83277c8a8 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -806,7 +806,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
806 | return -ENODEV; | 806 | return -ENODEV; |
807 | } | 807 | } |
808 | 808 | ||
809 | ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, | 809 | ioarea = request_mem_region(mem->start, resource_size(mem), |
810 | pdev->name); | 810 | pdev->name); |
811 | if (!ioarea) { | 811 | if (!ioarea) { |
812 | dev_err(&pdev->dev, "I2C region already claimed\n"); | 812 | dev_err(&pdev->dev, "I2C region already claimed\n"); |
@@ -905,7 +905,7 @@ err_free_mem: | |||
905 | platform_set_drvdata(pdev, NULL); | 905 | platform_set_drvdata(pdev, NULL); |
906 | kfree(dev); | 906 | kfree(dev); |
907 | err_release_region: | 907 | err_release_region: |
908 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 908 | release_mem_region(mem->start, resource_size(mem)); |
909 | 909 | ||
910 | return r; | 910 | return r; |
911 | } | 911 | } |
@@ -925,7 +925,7 @@ omap_i2c_remove(struct platform_device *pdev) | |||
925 | iounmap(dev->base); | 925 | iounmap(dev->base); |
926 | kfree(dev); | 926 | kfree(dev); |
927 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 927 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
928 | release_mem_region(mem->start, (mem->end - mem->start) + 1); | 928 | release_mem_region(mem->start, resource_size(mem)); |
929 | return 0; | 929 | return 0; |
930 | } | 930 | } |
931 | 931 | ||
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 1c01083b01b5..4f3d99cd1692 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c | |||
@@ -563,7 +563,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev) | |||
563 | goto err_irq; | 563 | goto err_irq; |
564 | } | 564 | } |
565 | 565 | ||
566 | size = (res->end - res->start) + 1; | 566 | size = resource_size(res); |
567 | 567 | ||
568 | pd->reg = ioremap(res->start, size); | 568 | pd->reg = ioremap(res->start, size); |
569 | if (pd->reg == NULL) { | 569 | if (pd->reg == NULL) { |
diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 042fda295f3a..6407f47bda82 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c | |||
@@ -92,7 +92,7 @@ static int simtec_i2c_probe(struct platform_device *dev) | |||
92 | goto err; | 92 | goto err; |
93 | } | 93 | } |
94 | 94 | ||
95 | size = (res->end-res->start)+1; | 95 | size = resource_size(res); |
96 | 96 | ||
97 | pd->ioarea = request_mem_region(res->start, size, dev->name); | 97 | pd->ioarea = request_mem_region(res->start, size, dev->name); |
98 | if (pd->ioarea == NULL) { | 98 | if (pd->ioarea == NULL) { |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 695181120cdb..7f878017b736 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -455,6 +455,7 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | |||
455 | 455 | ||
456 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; | 456 | rq->cmd_type = REQ_TYPE_ATA_TASKFILE; |
457 | rq->special = cmd; | 457 | rq->special = cmd; |
458 | cmd->rq = rq; | ||
458 | } | 459 | } |
459 | 460 | ||
460 | ide_devset_get(multcount, mult_count); | 461 | ide_devset_get(multcount, mult_count); |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 013dc595fab6..bc5fb12b913c 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -1064,6 +1064,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, | |||
1064 | tape->best_dsc_rw_freq = config.dsc_rw_frequency; | 1064 | tape->best_dsc_rw_freq = config.dsc_rw_frequency; |
1065 | break; | 1065 | break; |
1066 | case 0x0350: | 1066 | case 0x0350: |
1067 | memset(&config, 0, sizeof(config)); | ||
1067 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq; | 1068 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq; |
1068 | config.nr_stages = 1; | 1069 | config.nr_stages = 1; |
1069 | if (copy_to_user(argp, &config, sizeof(config))) | 1070 | if (copy_to_user(argp, &config, sizeof(config))) |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 114efd8dc8f5..1148140d08a1 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -608,8 +608,7 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
608 | p, compat_mode); | 608 | p, compat_mode); |
609 | 609 | ||
610 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) | 610 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) |
611 | return str_to_user(dev_name(&evdev->dev), | 611 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); |
612 | _IOC_SIZE(cmd), p); | ||
613 | 612 | ||
614 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) | 613 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) |
615 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | 614 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 0e12f89276a3..4cfd084fa897 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -536,7 +536,7 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
536 | default: | 536 | default: |
537 | if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { | 537 | if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { |
538 | int len; | 538 | int len; |
539 | const char *name = dev_name(&dev->dev); | 539 | const char *name = dev->name; |
540 | 540 | ||
541 | if (!name) | 541 | if (!name) |
542 | return 0; | 542 | return 0; |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index b868b8d5fbb3..f155ad8cdae7 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -470,20 +470,20 @@ static void xpad_irq_out(struct urb *urb) | |||
470 | status = urb->status; | 470 | status = urb->status; |
471 | 471 | ||
472 | switch (status) { | 472 | switch (status) { |
473 | case 0: | 473 | case 0: |
474 | /* success */ | 474 | /* success */ |
475 | break; | 475 | return; |
476 | case -ECONNRESET: | 476 | |
477 | case -ENOENT: | 477 | case -ECONNRESET: |
478 | case -ESHUTDOWN: | 478 | case -ENOENT: |
479 | /* this urb is terminated, clean up */ | 479 | case -ESHUTDOWN: |
480 | dbg("%s - urb shutting down with status: %d", | 480 | /* this urb is terminated, clean up */ |
481 | __func__, status); | 481 | dbg("%s - urb shutting down with status: %d", __func__, status); |
482 | return; | 482 | return; |
483 | default: | 483 | |
484 | dbg("%s - nonzero urb status received: %d", | 484 | default: |
485 | __func__, status); | 485 | dbg("%s - nonzero urb status received: %d", __func__, status); |
486 | goto exit; | 486 | goto exit; |
487 | } | 487 | } |
488 | 488 | ||
489 | exit: | 489 | exit: |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index df3f8aa68115..95fe0452dae4 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -895,6 +895,13 @@ static unsigned int atkbd_amilo_pa1510_forced_release_keys[] = { | |||
895 | }; | 895 | }; |
896 | 896 | ||
897 | /* | 897 | /* |
898 | * Amilo Pi 3525 key release for Fn+Volume keys not working | ||
899 | */ | ||
900 | static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { | ||
901 | 0x20, 0xa0, 0x2e, 0xae, 0x30, 0xb0, -1U | ||
902 | }; | ||
903 | |||
904 | /* | ||
898 | * Amilo Xi 3650 key release for light touch bar not working | 905 | * Amilo Xi 3650 key release for light touch bar not working |
899 | */ | 906 | */ |
900 | static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { | 907 | static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { |
@@ -902,6 +909,13 @@ static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { | |||
902 | }; | 909 | }; |
903 | 910 | ||
904 | /* | 911 | /* |
912 | * Soltech TA12 system with broken key release on volume keys and mute key | ||
913 | */ | ||
914 | static unsigned int atkdb_soltech_ta12_forced_release_keys[] = { | ||
915 | 0xa0, 0xae, 0xb0, -1U | ||
916 | }; | ||
917 | |||
918 | /* | ||
905 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 919 | * atkbd_set_keycode_table() initializes keyboard's keycode table |
906 | * according to the selected scancode set | 920 | * according to the selected scancode set |
907 | */ | 921 | */ |
@@ -1568,6 +1582,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1568 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, | 1582 | .driver_data = atkbd_amilo_pa1510_forced_release_keys, |
1569 | }, | 1583 | }, |
1570 | { | 1584 | { |
1585 | .ident = "Fujitsu Amilo Pi 3525", | ||
1586 | .matches = { | ||
1587 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
1588 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | ||
1589 | }, | ||
1590 | .callback = atkbd_setup_forced_release, | ||
1591 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | ||
1592 | }, | ||
1593 | { | ||
1571 | .ident = "Fujitsu Amilo Xi 3650", | 1594 | .ident = "Fujitsu Amilo Xi 3650", |
1572 | .matches = { | 1595 | .matches = { |
1573 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 1596 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), |
@@ -1576,6 +1599,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = { | |||
1576 | .callback = atkbd_setup_forced_release, | 1599 | .callback = atkbd_setup_forced_release, |
1577 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 1600 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, |
1578 | }, | 1601 | }, |
1602 | { | ||
1603 | .ident = "Soltech Corporation TA12", | ||
1604 | .matches = { | ||
1605 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | ||
1606 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | ||
1607 | }, | ||
1608 | .callback = atkbd_setup_forced_release, | ||
1609 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | ||
1610 | }, | ||
1579 | { } | 1611 | { } |
1580 | }; | 1612 | }; |
1581 | 1613 | ||
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index 6d67af5387ad..21cb755a54fb 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c | |||
@@ -114,7 +114,7 @@ static int __devexit pcspkr_remove(struct platform_device *dev) | |||
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int pcspkr_suspend(struct platform_device *dev, pm_message_t state) | 117 | static int pcspkr_suspend(struct device *dev) |
118 | { | 118 | { |
119 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | 119 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); |
120 | 120 | ||
@@ -127,14 +127,18 @@ static void pcspkr_shutdown(struct platform_device *dev) | |||
127 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); | 127 | pcspkr_event(NULL, EV_SND, SND_BELL, 0); |
128 | } | 128 | } |
129 | 129 | ||
130 | static struct dev_pm_ops pcspkr_pm_ops = { | ||
131 | .suspend = pcspkr_suspend, | ||
132 | }; | ||
133 | |||
130 | static struct platform_driver pcspkr_platform_driver = { | 134 | static struct platform_driver pcspkr_platform_driver = { |
131 | .driver = { | 135 | .driver = { |
132 | .name = "pcspkr", | 136 | .name = "pcspkr", |
133 | .owner = THIS_MODULE, | 137 | .owner = THIS_MODULE, |
138 | .pm = &pcspkr_pm_ops, | ||
134 | }, | 139 | }, |
135 | .probe = pcspkr_probe, | 140 | .probe = pcspkr_probe, |
136 | .remove = __devexit_p(pcspkr_remove), | 141 | .remove = __devexit_p(pcspkr_remove), |
137 | .suspend = pcspkr_suspend, | ||
138 | .shutdown = pcspkr_shutdown, | 142 | .shutdown = pcspkr_shutdown, |
139 | }; | 143 | }; |
140 | 144 | ||
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index 7c8957dd22c0..26e17a9a22eb 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
@@ -646,6 +646,15 @@ static struct dmi_system_id dmi_ids[] __initdata = { | |||
646 | }, | 646 | }, |
647 | { | 647 | { |
648 | .callback = dmi_matched, | 648 | .callback = dmi_matched, |
649 | .ident = "Maxdata Pro 7000 DX", | ||
650 | .matches = { | ||
651 | DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"), | ||
652 | DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"), | ||
653 | }, | ||
654 | .driver_data = keymap_fs_amilo_pro_v2000 | ||
655 | }, | ||
656 | { | ||
657 | .callback = dmi_matched, | ||
649 | .ident = "Fujitsu N3510", | 658 | .ident = "Fujitsu N3510", |
650 | .matches = { | 659 | .matches = { |
651 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 660 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 1ebfcab74662..8ff7e35c7069 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -408,6 +408,8 @@ static int if_write_room(struct tty_struct *tty) | |||
408 | return retval; | 408 | return retval; |
409 | } | 409 | } |
410 | 410 | ||
411 | /* FIXME: This function does not have error returns */ | ||
412 | |||
411 | static int if_chars_in_buffer(struct tty_struct *tty) | 413 | static int if_chars_in_buffer(struct tty_struct *tty) |
412 | { | 414 | { |
413 | struct cardstate *cs; | 415 | struct cardstate *cs; |
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index 8df889b0c1a9..9de54202c90c 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/kernel_stat.h> | 37 | #include <linux/kernel_stat.h> |
38 | #include <linux/usb.h> | 38 | #include <linux/usb.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/sched.h> | 40 | #include <linux/sched.h> |
42 | #include <linux/moduleparam.h> | 41 | #include <linux/moduleparam.h> |
43 | #include "hisax.h" | 42 | #include "hisax.h" |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index b4d4522e5071..2881a66c1aa9 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/isdn.h> | 14 | #include <linux/isdn.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/smp_lock.h> | ||
16 | #include "isdn_common.h" | 17 | #include "isdn_common.h" |
17 | #include "isdn_tty.h" | 18 | #include "isdn_tty.h" |
18 | #ifdef CONFIG_ISDN_AUDIO | 19 | #ifdef CONFIG_ISDN_AUDIO |
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index e2f45019ebf0..3e1532a180ff 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/mISDNif.h> | 18 | #include <linux/mISDNif.h> |
19 | #include <linux/kthread.h> | 19 | #include <linux/kthread.h> |
20 | #include <linux/smp_lock.h> | ||
20 | #include "core.h" | 21 | #include "core.h" |
21 | 22 | ||
22 | static u_int *debug; | 23 | static u_int *debug; |
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h index 9c3138265f8e..01c591923793 100644 --- a/drivers/lguest/lg.h +++ b/drivers/lguest/lg.h | |||
@@ -38,8 +38,6 @@ struct lguest_pages | |||
38 | #define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */ | 38 | #define CHANGED_GDT_TLS 4 /* Actually a subset of CHANGED_GDT */ |
39 | #define CHANGED_ALL 3 | 39 | #define CHANGED_ALL 3 |
40 | 40 | ||
41 | struct lguest; | ||
42 | |||
43 | struct lg_cpu { | 41 | struct lg_cpu { |
44 | unsigned int id; | 42 | unsigned int id; |
45 | struct lguest *lg; | 43 | struct lguest *lg; |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index 4601b059b2b2..0e246eaad05a 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/smp_lock.h> | ||
24 | #include <linux/string.h> | 25 | #include <linux/string.h> |
25 | #include <linux/dvb/ca.h> | 26 | #include <linux/dvb/ca.h> |
26 | #include "dvbdev.h" | 27 | #include "dvbdev.h" |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 79927305e84d..487919bea7ae 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/poll.h> | 27 | #include <linux/poll.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/list.h> | 29 | #include <linux/list.h> |
30 | #include <linux/smp_lock.h> | ||
31 | 30 | ||
32 | #define DVB_MAJOR 212 | 31 | #define DVB_MAJOR 212 |
33 | 32 | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index d1d959ed37b7..8d65c652ba50 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
39 | #include <linux/smp_lock.h> | ||
40 | 39 | ||
41 | #include <linux/kernel.h> | 40 | #include <linux/kernel.h> |
42 | #include <linux/sched.h> | 41 | #include <linux/sched.h> |
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index 837467f93805..575bf9d89419 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #include <linux/module.h> | 58 | #include <linux/module.h> |
59 | #include <linux/init.h> | 59 | #include <linux/init.h> |
60 | #include <linux/slab.h> | 60 | #include <linux/slab.h> |
61 | #include <linux/smp_lock.h> | ||
61 | #include <linux/input.h> | 62 | #include <linux/input.h> |
62 | #include <linux/videodev2.h> | 63 | #include <linux/videodev2.h> |
63 | #include <media/v4l2-device.h> | 64 | #include <media/v4l2-device.h> |
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 46d216329611..e85f318b4d2b 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -127,6 +127,7 @@ | |||
127 | #include <linux/module.h> | 127 | #include <linux/module.h> |
128 | #include <linux/init.h> | 128 | #include <linux/init.h> |
129 | #include <linux/slab.h> | 129 | #include <linux/slab.h> |
130 | #include <linux/smp_lock.h> | ||
130 | #include <linux/input.h> | 131 | #include <linux/input.h> |
131 | #include <linux/usb.h> | 132 | #include <linux/usb.h> |
132 | #include <linux/hid.h> | 133 | #include <linux/hid.h> |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 5eb1464af670..d147d29bb0d3 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/fs.h> | 41 | #include <linux/fs.h> |
42 | #include <linux/kernel.h> | 42 | #include <linux/kernel.h> |
43 | #include <linux/sched.h> | 43 | #include <linux/sched.h> |
44 | #include <linux/smp_lock.h> | ||
44 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
45 | #include <linux/kdev_t.h> | 46 | #include <linux/kdev_t.h> |
46 | #include "bttvp.h" | 47 | #include "bttvp.h" |
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 2943bfd32a94..428f0c45e6b7 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/device.h> | 32 | #include <linux/device.h> |
33 | #include <linux/firmware.h> | 33 | #include <linux/firmware.h> |
34 | #include <linux/smp_lock.h> | ||
34 | #include <media/v4l2-common.h> | 35 | #include <media/v4l2-common.h> |
35 | #include <media/v4l2-ioctl.h> | 36 | #include <media/v4l2-ioctl.h> |
36 | #include <media/cx2341x.h> | 37 | #include <media/cx2341x.h> |
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 70836af3ab48..5d6093336300 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kmod.h> | 26 | #include <linux/kmod.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
30 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
31 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 44eacfb0d0d6..356d6896da3f 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/device.h> | 33 | #include <linux/device.h> |
34 | #include <linux/firmware.h> | 34 | #include <linux/firmware.h> |
35 | #include <linux/smp_lock.h> | ||
35 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
36 | #include <media/v4l2-ioctl.h> | 37 | #include <media/v4l2-ioctl.h> |
37 | #include <media/cx2341x.h> | 38 | #include <media/cx2341x.h> |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index b12770848c00..2bb54c3ef5cd 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kmod.h> | 31 | #include <linux/kmod.h> |
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/smp_lock.h> | ||
34 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
35 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
36 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c index ec2f45dde164..0664d111085f 100644 --- a/drivers/media/video/dabusb.c +++ b/drivers/media/video/dabusb.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/list.h> | 32 | #include <linux/list.h> |
33 | #include <linux/vmalloc.h> | 33 | #include <linux/vmalloc.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/smp_lock.h> | ||
35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | #include <asm/atomic.h> | 38 | #include <asm/atomic.h> |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index db25c3034c11..8d17cf613306 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/module.h> | 62 | #include <linux/module.h> |
63 | #include <linux/poll.h> | 63 | #include <linux/poll.h> |
64 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
65 | #include <linux/smp_lock.h> | ||
65 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 66 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
66 | #include <linux/usb/input.h> | 67 | #include <linux/usb/input.h> |
67 | #endif | 68 | #endif |
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 0be6f814f539..0b658dee05a4 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/usb.h> | 29 | #include <linux/usb.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/version.h> | 32 | #include <linux/version.h> |
34 | #include <linux/mutex.h> | 33 | #include <linux/mutex.h> |
35 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 6be845ccc7d7..9e3262c0ba37 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/videodev2.h> | 48 | #include <linux/videodev2.h> |
49 | #include <linux/version.h> | 49 | #include <linux/version.h> |
50 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
51 | #include <linux/smp_lock.h> | ||
51 | #include <media/videobuf-vmalloc.h> | 52 | #include <media/videobuf-vmalloc.h> |
52 | #include <media/v4l2-common.h> | 53 | #include <media/v4l2-common.h> |
53 | #include <media/v4l2-ioctl.h> | 54 | #include <media/v4l2-ioctl.h> |
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 155804b061e9..b624a4c01fdc 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include <linux/mm.h> | 43 | #include <linux/mm.h> |
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/i2c.h> | 45 | #include <linux/i2c.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
48 | #include <linux/videotext.h> | 47 | #include <linux/videotext.h> |
49 | #include <linux/videodev2.h> | 48 | #include <linux/videodev2.h> |
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 271d6e931b75..12835fb82c95 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/mm.h> | 46 | #include <linux/mm.h> |
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/i2c.h> | 48 | #include <linux/i2c.h> |
49 | #include <linux/smp_lock.h> | ||
50 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
51 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
52 | #include <linux/videotext.h> | 51 | #include <linux/videotext.h> |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index add1757f8930..296788c3bf0e 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
26 | 27 | ||
27 | #include "saa7134-reg.h" | 28 | #include "saa7134-reg.h" |
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index c8f05297d0f0..85ffc2cba039 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c | |||
@@ -31,6 +31,7 @@ static const char version[] = "0.24"; | |||
31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
32 | #include <linux/vmalloc.h> | 32 | #include <linux/vmalloc.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/smp_lock.h> | ||
34 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
35 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
36 | #include "se401.h" | 37 | #include "se401.h" |
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 2e5937047278..4d6785e63455 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/smp_lock.h> | ||
30 | 31 | ||
31 | #include <linux/usb.h> | 32 | #include <linux/usb.h> |
32 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 0eb313082c97..eaada39c76fd 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/major.h> | 27 | #include <linux/major.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/poll.h> | 32 | #include <linux/poll.h> |
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 75f286f7a2e9..8b4e7dafce7b 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/init.h> | 62 | #include <linux/init.h> |
63 | #include <linux/vmalloc.h> | 63 | #include <linux/vmalloc.h> |
64 | #include <linux/slab.h> | 64 | #include <linux/slab.h> |
65 | #include <linux/smp_lock.h> | ||
65 | #include <linux/pagemap.h> | 66 | #include <linux/pagemap.h> |
66 | #include <linux/errno.h> | 67 | #include <linux/errno.h> |
67 | #include <linux/videodev.h> | 68 | #include <linux/videodev.h> |
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 8d73979596f9..45fce39ec9ad 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/vmalloc.h> | 43 | #include <linux/vmalloc.h> |
44 | #include <linux/mm.h> | 44 | #include <linux/mm.h> |
45 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
46 | #include <linux/smp_lock.h> | ||
46 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
47 | #include <linux/firmware.h> | 48 | #include <linux/firmware.h> |
48 | #include <linux/ihex.h> | 49 | #include <linux/ihex.h> |
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 90b58914f984..90d9b5c0e9a7 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/list.h> | 50 | #include <linux/list.h> |
51 | #include <linux/timer.h> | 51 | #include <linux/timer.h> |
52 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/smp_lock.h> | ||
53 | #include <linux/mm.h> | 54 | #include <linux/mm.h> |
54 | #include <linux/utsname.h> | 55 | #include <linux/utsname.h> |
55 | #include <linux/highmem.h> | 56 | #include <linux/highmem.h> |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 31eac66411d7..a7f1b69a7dab 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/kmod.h> | 26 | #include <linux/kmod.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
30 | #include <asm/system.h> | 29 | #include <asm/system.h> |
31 | 30 | ||
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c index 3d7df32a3d87..bcdefb1bcb3d 100644 --- a/drivers/media/video/zoran/zoran_driver.c +++ b/drivers/media/video/zoran/zoran_driver.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/module.h> | 49 | #include <linux/module.h> |
50 | #include <linux/delay.h> | 50 | #include <linux/delay.h> |
51 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
52 | #include <linux/smp_lock.h> | ||
52 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
53 | #include <linux/vmalloc.h> | 54 | #include <linux/vmalloc.h> |
54 | #include <linux/wait.h> | 55 | #include <linux/wait.h> |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index fa2d93a9fb8d..aed609832bc2 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
34 | #include <linux/device.h> | 33 | #include <linux/device.h> |
35 | #include <linux/miscdevice.h> | 34 | #include <linux/miscdevice.h> |
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c index eedbf9c32760..79689b10f937 100644 --- a/drivers/misc/sgi-gru/grukservices.c +++ b/drivers/misc/sgi-gru/grukservices.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
29 | #include <linux/device.h> | 28 | #include <linux/device.h> |
30 | #include <linux/miscdevice.h> | 29 | #include <linux/miscdevice.h> |
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index b56d72ff06e9..34e23489811a 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
@@ -384,7 +384,7 @@ static irqreturn_t mvsd_irq(int irq, void *dev) | |||
384 | u16 val[2] = {0, 0}; | 384 | u16 val[2] = {0, 0}; |
385 | val[0] = mvsd_read(MVSD_FIFO); | 385 | val[0] = mvsd_read(MVSD_FIFO); |
386 | val[1] = mvsd_read(MVSD_FIFO); | 386 | val[1] = mvsd_read(MVSD_FIFO); |
387 | memcpy(p, &val, s); | 387 | memcpy(p, ((void *)&val) + 4 - s, s); |
388 | s = 0; | 388 | s = 0; |
389 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 389 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
390 | } | 390 | } |
@@ -423,7 +423,7 @@ static irqreturn_t mvsd_irq(int irq, void *dev) | |||
423 | if (s < 4) { | 423 | if (s < 4) { |
424 | if (s && (intr_status & MVSD_NOR_TX_AVAIL)) { | 424 | if (s && (intr_status & MVSD_NOR_TX_AVAIL)) { |
425 | u16 val[2] = {0, 0}; | 425 | u16 val[2] = {0, 0}; |
426 | memcpy(&val, p, s); | 426 | memcpy(((void *)&val) + 4 - s, p, s); |
427 | mvsd_write(MVSD_FIFO, val[0]); | 427 | mvsd_write(MVSD_FIFO, val[0]); |
428 | mvsd_write(MVSD_FIFO, val[1]); | 428 | mvsd_write(MVSD_FIFO, val[1]); |
429 | s = 0; | 429 | s = 0; |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index d7d7109ef47e..e55ac792d68c 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -168,12 +168,12 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) | |||
168 | 168 | ||
169 | if (data->flags & MMC_DATA_READ) { | 169 | if (data->flags & MMC_DATA_READ) { |
170 | host->dma_dir = DMA_FROM_DEVICE; | 170 | host->dma_dir = DMA_FROM_DEVICE; |
171 | dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG; | 171 | dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC; |
172 | DRCMR(host->dma_drcmrtx) = 0; | 172 | DRCMR(host->dma_drcmrtx) = 0; |
173 | DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; | 173 | DRCMR(host->dma_drcmrrx) = host->dma | DRCMR_MAPVLD; |
174 | } else { | 174 | } else { |
175 | host->dma_dir = DMA_TO_DEVICE; | 175 | host->dma_dir = DMA_TO_DEVICE; |
176 | dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC; | 176 | dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG; |
177 | DRCMR(host->dma_drcmrrx) = 0; | 177 | DRCMR(host->dma_drcmrrx) = 0; |
178 | DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; | 178 | DRCMR(host->dma_drcmrtx) = host->dma | DRCMR_MAPVLD; |
179 | } | 179 | } |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 286ed594e5a0..e1f7d0a78b9d 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -657,6 +657,11 @@ static int io_init(struct ubi_device *ubi) | |||
657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) | 657 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) |
658 | ubi->bad_allowed = 1; | 658 | ubi->bad_allowed = 1; |
659 | 659 | ||
660 | if (ubi->mtd->type == MTD_NORFLASH) { | ||
661 | ubi_assert(ubi->mtd->writesize == 1); | ||
662 | ubi->nor_flash = 1; | ||
663 | } | ||
664 | |||
660 | ubi->min_io_size = ubi->mtd->writesize; | 665 | ubi->min_io_size = ubi->mtd->writesize; |
661 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; | 666 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; |
662 | 667 | ||
@@ -996,6 +1001,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
996 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", | 1001 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", |
997 | ubi->beb_rsvd_pebs); | 1002 | ubi->beb_rsvd_pebs); |
998 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); | 1003 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); |
1004 | ubi_msg("image sequence number: %d", ubi->image_seq); | ||
999 | 1005 | ||
1000 | /* | 1006 | /* |
1001 | * The below lock makes sure we do not race with 'ubi_thread()' which | 1007 | * The below lock makes sure we do not race with 'ubi_thread()' which |
diff --git a/drivers/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index c0ed60e8ade9..54b0186915fb 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c | |||
@@ -44,6 +44,8 @@ void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr) | |||
44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); | 44 | be32_to_cpu(ec_hdr->vid_hdr_offset)); |
45 | printk(KERN_DEBUG "\tdata_offset %d\n", | 45 | printk(KERN_DEBUG "\tdata_offset %d\n", |
46 | be32_to_cpu(ec_hdr->data_offset)); | 46 | be32_to_cpu(ec_hdr->data_offset)); |
47 | printk(KERN_DEBUG "\timage_seq %d\n", | ||
48 | be32_to_cpu(ec_hdr->image_seq)); | ||
47 | printk(KERN_DEBUG "\thdr_crc %#08x\n", | 49 | printk(KERN_DEBUG "\thdr_crc %#08x\n", |
48 | be32_to_cpu(ec_hdr->hdr_crc)); | 50 | be32_to_cpu(ec_hdr->hdr_crc)); |
49 | printk(KERN_DEBUG "erase counter header hexdump:\n"); | 51 | printk(KERN_DEBUG "erase counter header hexdump:\n"); |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 13777e5beac9..a4da7a09b949 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
@@ -93,6 +93,12 @@ void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req); | |||
93 | #define UBI_IO_DEBUG 0 | 93 | #define UBI_IO_DEBUG 0 |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | ||
97 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len); | ||
98 | #else | ||
99 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
100 | #endif | ||
101 | |||
96 | #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT | 102 | #ifdef CONFIG_MTD_UBI_DEBUG_DISABLE_BGT |
97 | #define DBG_DISABLE_BGT 1 | 103 | #define DBG_DISABLE_BGT 1 |
98 | #else | 104 | #else |
@@ -167,6 +173,7 @@ static inline int ubi_dbg_is_erase_failure(void) | |||
167 | #define ubi_dbg_is_bitflip() 0 | 173 | #define ubi_dbg_is_bitflip() 0 |
168 | #define ubi_dbg_is_write_failure() 0 | 174 | #define ubi_dbg_is_write_failure() 0 |
169 | #define ubi_dbg_is_erase_failure() 0 | 175 | #define ubi_dbg_is_erase_failure() 0 |
176 | #define ubi_dbg_check_all_ff(ubi, pnum, offset, len) 0 | ||
170 | 177 | ||
171 | #endif /* !CONFIG_MTD_UBI_DEBUG */ | 178 | #endif /* !CONFIG_MTD_UBI_DEBUG */ |
172 | #endif /* !__UBI_DEBUG_H__ */ | 179 | #endif /* !__UBI_DEBUG_H__ */ |
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 95aaac03f938..b5e478fa2661 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c | |||
@@ -332,6 +332,7 @@ static int gluebi_create(struct ubi_device_info *di, | |||
332 | } | 332 | } |
333 | 333 | ||
334 | gluebi->vol_id = vi->vol_id; | 334 | gluebi->vol_id = vi->vol_id; |
335 | gluebi->ubi_num = vi->ubi_num; | ||
335 | mtd->type = MTD_UBIVOLUME; | 336 | mtd->type = MTD_UBIVOLUME; |
336 | if (!di->ro_mode) | 337 | if (!di->ro_mode) |
337 | mtd->flags = MTD_WRITEABLE; | 338 | mtd->flags = MTD_WRITEABLE; |
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index effaff28bab1..4cb69925d8d9 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -98,17 +98,12 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); | 98 | static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum); |
99 | static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | 99 | static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, |
100 | const struct ubi_vid_hdr *vid_hdr); | 100 | const struct ubi_vid_hdr *vid_hdr); |
101 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | ||
102 | int len); | ||
103 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum); | ||
104 | #else | 101 | #else |
105 | #define paranoid_check_not_bad(ubi, pnum) 0 | 102 | #define paranoid_check_not_bad(ubi, pnum) 0 |
106 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 | 103 | #define paranoid_check_peb_ec_hdr(ubi, pnum) 0 |
107 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 | 104 | #define paranoid_check_ec_hdr(ubi, pnum, ec_hdr) 0 |
108 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 | 105 | #define paranoid_check_peb_vid_hdr(ubi, pnum) 0 |
109 | #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 | 106 | #define paranoid_check_vid_hdr(ubi, pnum, vid_hdr) 0 |
110 | #define paranoid_check_all_ff(ubi, pnum, offset, len) 0 | ||
111 | #define paranoid_check_empty(ubi, pnum) 0 | ||
112 | #endif | 107 | #endif |
113 | 108 | ||
114 | /** | 109 | /** |
@@ -244,7 +239,7 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
244 | return err > 0 ? -EINVAL : err; | 239 | return err > 0 ? -EINVAL : err; |
245 | 240 | ||
246 | /* The area we are writing to has to contain all 0xFF bytes */ | 241 | /* The area we are writing to has to contain all 0xFF bytes */ |
247 | err = paranoid_check_all_ff(ubi, pnum, offset, len); | 242 | err = ubi_dbg_check_all_ff(ubi, pnum, offset, len); |
248 | if (err) | 243 | if (err) |
249 | return err > 0 ? -EINVAL : err; | 244 | return err > 0 ? -EINVAL : err; |
250 | 245 | ||
@@ -271,8 +266,8 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset, | |||
271 | addr = (loff_t)pnum * ubi->peb_size + offset; | 266 | addr = (loff_t)pnum * ubi->peb_size + offset; |
272 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); | 267 | err = ubi->mtd->write(ubi->mtd, addr, len, &written, buf); |
273 | if (err) { | 268 | if (err) { |
274 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written" | 269 | ubi_err("error %d while writing %d bytes to PEB %d:%d, written " |
275 | " %zd bytes", err, len, pnum, offset, written); | 270 | "%zd bytes", err, len, pnum, offset, written); |
276 | ubi_dbg_dump_stack(); | 271 | ubi_dbg_dump_stack(); |
277 | } else | 272 | } else |
278 | ubi_assert(written == len); | 273 | ubi_assert(written == len); |
@@ -350,7 +345,7 @@ retry: | |||
350 | return -EIO; | 345 | return -EIO; |
351 | } | 346 | } |
352 | 347 | ||
353 | err = paranoid_check_all_ff(ubi, pnum, 0, ubi->peb_size); | 348 | err = ubi_dbg_check_all_ff(ubi, pnum, 0, ubi->peb_size); |
354 | if (err) | 349 | if (err) |
355 | return err > 0 ? -EINVAL : err; | 350 | return err > 0 ? -EINVAL : err; |
356 | 351 | ||
@@ -459,6 +454,54 @@ out: | |||
459 | } | 454 | } |
460 | 455 | ||
461 | /** | 456 | /** |
457 | * nor_erase_prepare - prepare a NOR flash PEB for erasure. | ||
458 | * @ubi: UBI device description object | ||
459 | * @pnum: physical eraseblock number to prepare | ||
460 | * | ||
461 | * NOR flash, or at least some of them, have peculiar embedded PEB erasure | ||
462 | * algorithm: the PEB is first filled with zeroes, then it is erased. And | ||
463 | * filling with zeroes starts from the end of the PEB. This was observed with | ||
464 | * Spansion S29GL512N NOR flash. | ||
465 | * | ||
466 | * This means that in case of a power cut we may end up with intact data at the | ||
467 | * beginning of the PEB, and all zeroes at the end of PEB. In other words, the | ||
468 | * EC and VID headers are OK, but a large chunk of data at the end of PEB is | ||
469 | * zeroed. This makes UBI mistakenly treat this PEB as used and associate it | ||
470 | * with an LEB, which leads to subsequent failures (e.g., UBIFS fails). | ||
471 | * | ||
472 | * This function is called before erasing NOR PEBs and it zeroes out EC and VID | ||
473 | * magic numbers in order to invalidate them and prevent the failures. Returns | ||
474 | * zero in case of success and a negative error code in case of failure. | ||
475 | */ | ||
476 | static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | ||
477 | { | ||
478 | int err; | ||
479 | size_t written; | ||
480 | loff_t addr; | ||
481 | uint32_t data = 0; | ||
482 | |||
483 | addr = (loff_t)pnum * ubi->peb_size; | ||
484 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
485 | if (err) { | ||
486 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
487 | "%zd bytes", err, pnum, 0, written); | ||
488 | ubi_dbg_dump_stack(); | ||
489 | return err; | ||
490 | } | ||
491 | |||
492 | addr += ubi->vid_hdr_aloffset; | ||
493 | err = ubi->mtd->write(ubi->mtd, addr, 4, &written, (void *)&data); | ||
494 | if (err) { | ||
495 | ubi_err("error %d while writing 4 bytes to PEB %d:%d, written " | ||
496 | "%zd bytes", err, pnum, ubi->vid_hdr_aloffset, written); | ||
497 | ubi_dbg_dump_stack(); | ||
498 | return err; | ||
499 | } | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | /** | ||
462 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. | 505 | * ubi_io_sync_erase - synchronously erase a physical eraseblock. |
463 | * @ubi: UBI device description object | 506 | * @ubi: UBI device description object |
464 | * @pnum: physical eraseblock number to erase | 507 | * @pnum: physical eraseblock number to erase |
@@ -489,6 +532,12 @@ int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture) | |||
489 | return -EROFS; | 532 | return -EROFS; |
490 | } | 533 | } |
491 | 534 | ||
535 | if (ubi->nor_flash) { | ||
536 | err = nor_erase_prepare(ubi, pnum); | ||
537 | if (err) | ||
538 | return err; | ||
539 | } | ||
540 | |||
492 | if (torture) { | 541 | if (torture) { |
493 | ret = torture_peb(ubi, pnum); | 542 | ret = torture_peb(ubi, pnum); |
494 | if (ret < 0) | 543 | if (ret < 0) |
@@ -672,11 +721,6 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
672 | if (read_err != -EBADMSG && | 721 | if (read_err != -EBADMSG && |
673 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { | 722 | check_pattern(ec_hdr, 0xFF, UBI_EC_HDR_SIZE)) { |
674 | /* The physical eraseblock is supposedly empty */ | 723 | /* The physical eraseblock is supposedly empty */ |
675 | err = paranoid_check_all_ff(ubi, pnum, 0, | ||
676 | ubi->peb_size); | ||
677 | if (err) | ||
678 | return err > 0 ? UBI_IO_BAD_EC_HDR : err; | ||
679 | |||
680 | if (verbose) | 724 | if (verbose) |
681 | ubi_warn("no EC header found at PEB %d, " | 725 | ubi_warn("no EC header found at PEB %d, " |
682 | "only 0xFF bytes", pnum); | 726 | "only 0xFF bytes", pnum); |
@@ -752,6 +796,7 @@ int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum, | |||
752 | ec_hdr->version = UBI_VERSION; | 796 | ec_hdr->version = UBI_VERSION; |
753 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); | 797 | ec_hdr->vid_hdr_offset = cpu_to_be32(ubi->vid_hdr_offset); |
754 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); | 798 | ec_hdr->data_offset = cpu_to_be32(ubi->leb_start); |
799 | ec_hdr->image_seq = cpu_to_be32(ubi->image_seq); | ||
755 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); | 800 | crc = crc32(UBI_CRC32_INIT, ec_hdr, UBI_EC_HDR_SIZE_CRC); |
756 | ec_hdr->hdr_crc = cpu_to_be32(crc); | 801 | ec_hdr->hdr_crc = cpu_to_be32(crc); |
757 | 802 | ||
@@ -947,15 +992,6 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
947 | if (read_err != -EBADMSG && | 992 | if (read_err != -EBADMSG && |
948 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { | 993 | check_pattern(vid_hdr, 0xFF, UBI_VID_HDR_SIZE)) { |
949 | /* The physical eraseblock is supposedly free */ | 994 | /* The physical eraseblock is supposedly free */ |
950 | |||
951 | /* | ||
952 | * The below is just a paranoid check, it has to be | ||
953 | * compiled out if paranoid checks are disabled. | ||
954 | */ | ||
955 | err = paranoid_check_empty(ubi, pnum); | ||
956 | if (err) | ||
957 | return err > 0 ? UBI_IO_BAD_VID_HDR : err; | ||
958 | |||
959 | if (verbose) | 995 | if (verbose) |
960 | ubi_warn("no VID header found at PEB %d, " | 996 | ubi_warn("no VID header found at PEB %d, " |
961 | "only 0xFF bytes", pnum); | 997 | "only 0xFF bytes", pnum); |
@@ -1229,7 +1265,7 @@ exit: | |||
1229 | } | 1265 | } |
1230 | 1266 | ||
1231 | /** | 1267 | /** |
1232 | * paranoid_check_all_ff - check that a region of flash is empty. | 1268 | * ubi_dbg_check_all_ff - check that a region of flash is empty. |
1233 | * @ubi: UBI device description object | 1269 | * @ubi: UBI device description object |
1234 | * @pnum: the physical eraseblock number to check | 1270 | * @pnum: the physical eraseblock number to check |
1235 | * @offset: the starting offset within the physical eraseblock to check | 1271 | * @offset: the starting offset within the physical eraseblock to check |
@@ -1239,8 +1275,7 @@ exit: | |||
1239 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error | 1275 | * @offset of the physical eraseblock @pnum, %1 if not, and a negative error |
1240 | * code if an error occurred. | 1276 | * code if an error occurred. |
1241 | */ | 1277 | */ |
1242 | static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset, | 1278 | int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) |
1243 | int len) | ||
1244 | { | 1279 | { |
1245 | size_t read; | 1280 | size_t read; |
1246 | int err; | 1281 | int err; |
@@ -1276,74 +1311,4 @@ error: | |||
1276 | return err; | 1311 | return err; |
1277 | } | 1312 | } |
1278 | 1313 | ||
1279 | /** | ||
1280 | * paranoid_check_empty - whether a PEB is empty. | ||
1281 | * @ubi: UBI device description object | ||
1282 | * @pnum: the physical eraseblock number to check | ||
1283 | * | ||
1284 | * This function makes sure PEB @pnum is empty, which means it contains only | ||
1285 | * %0xFF data bytes. Returns zero if the PEB is empty, %1 if not, and a | ||
1286 | * negative error code in case of failure. | ||
1287 | * | ||
1288 | * Empty PEBs have the EC header, and do not have the VID header. The caller of | ||
1289 | * this function should have already made sure the PEB does not have the VID | ||
1290 | * header. However, this function re-checks that, because it is possible that | ||
1291 | * the header and data has already been written to the PEB. | ||
1292 | * | ||
1293 | * Let's consider a possible scenario. Suppose there are 2 tasks - A and B. | ||
1294 | * Task A is in 'wear_leveling_worker()'. It is reading VID header of PEB X to | ||
1295 | * find which LEB it corresponds to. PEB X is currently unmapped, and has no | ||
1296 | * VID header. Task B is trying to write to PEB X. | ||
1297 | * | ||
1298 | * Task A: in 'ubi_io_read_vid_hdr()': reads the VID header from PEB X. The | ||
1299 | * read data contain all 0xFF bytes; | ||
1300 | * Task B: writes VID header and some data to PEB X; | ||
1301 | * Task A: assumes PEB X is empty, calls 'paranoid_check_empty()'. And if we | ||
1302 | * do not re-read the VID header, and do not cancel the checking if it | ||
1303 | * is there, we fail. | ||
1304 | */ | ||
1305 | static int paranoid_check_empty(struct ubi_device *ubi, int pnum) | ||
1306 | { | ||
1307 | int err, offs = ubi->vid_hdr_aloffset, len = ubi->vid_hdr_alsize; | ||
1308 | size_t read; | ||
1309 | uint32_t magic; | ||
1310 | const struct ubi_vid_hdr *vid_hdr; | ||
1311 | |||
1312 | mutex_lock(&ubi->dbg_buf_mutex); | ||
1313 | err = ubi->mtd->read(ubi->mtd, offs, len, &read, ubi->dbg_peb_buf); | ||
1314 | if (err && err != -EUCLEAN) { | ||
1315 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " | ||
1316 | "read %zd bytes", err, len, pnum, offs, read); | ||
1317 | goto error; | ||
1318 | } | ||
1319 | |||
1320 | vid_hdr = ubi->dbg_peb_buf; | ||
1321 | magic = be32_to_cpu(vid_hdr->magic); | ||
1322 | if (magic == UBI_VID_HDR_MAGIC) | ||
1323 | /* The PEB contains VID header, so it is not empty */ | ||
1324 | goto out; | ||
1325 | |||
1326 | err = check_pattern(ubi->dbg_peb_buf, 0xFF, len); | ||
1327 | if (err == 0) { | ||
1328 | ubi_err("flash region at PEB %d:%d, length %d does not " | ||
1329 | "contain all 0xFF bytes", pnum, offs, len); | ||
1330 | goto fail; | ||
1331 | } | ||
1332 | |||
1333 | out: | ||
1334 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1335 | return 0; | ||
1336 | |||
1337 | fail: | ||
1338 | ubi_err("paranoid check failed for PEB %d", pnum); | ||
1339 | ubi_msg("hex dump of the %d-%d region", offs, offs + len); | ||
1340 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | ||
1341 | ubi->dbg_peb_buf, len, 1); | ||
1342 | err = 1; | ||
1343 | error: | ||
1344 | ubi_dbg_dump_stack(); | ||
1345 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1346 | return err; | ||
1347 | } | ||
1348 | |||
1349 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1314 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index c3d653ba5ca0..a423131b6171 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -757,6 +757,8 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
757 | si->is_empty = 0; | 757 | si->is_empty = 0; |
758 | 758 | ||
759 | if (!ec_corr) { | 759 | if (!ec_corr) { |
760 | int image_seq; | ||
761 | |||
760 | /* Make sure UBI version is OK */ | 762 | /* Make sure UBI version is OK */ |
761 | if (ech->version != UBI_VERSION) { | 763 | if (ech->version != UBI_VERSION) { |
762 | ubi_err("this UBI version is %d, image version is %d", | 764 | ubi_err("this UBI version is %d, image version is %d", |
@@ -778,6 +780,18 @@ static int process_eb(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
778 | ubi_dbg_dump_ec_hdr(ech); | 780 | ubi_dbg_dump_ec_hdr(ech); |
779 | return -EINVAL; | 781 | return -EINVAL; |
780 | } | 782 | } |
783 | |||
784 | image_seq = be32_to_cpu(ech->image_seq); | ||
785 | if (!si->image_seq_set) { | ||
786 | ubi->image_seq = image_seq; | ||
787 | si->image_seq_set = 1; | ||
788 | } else if (ubi->image_seq != image_seq) { | ||
789 | ubi_err("bad image sequence number %d in PEB %d, " | ||
790 | "expected %d", image_seq, pnum, ubi->image_seq); | ||
791 | ubi_dbg_dump_ec_hdr(ech); | ||
792 | return -EINVAL; | ||
793 | } | ||
794 | |||
781 | } | 795 | } |
782 | 796 | ||
783 | /* OK, we've done with the EC header, let's look at the VID header */ | 797 | /* OK, we've done with the EC header, let's look at the VID header */ |
diff --git a/drivers/mtd/ubi/scan.h b/drivers/mtd/ubi/scan.h index 61df208e2f20..1017cf12def5 100644 --- a/drivers/mtd/ubi/scan.h +++ b/drivers/mtd/ubi/scan.h | |||
@@ -102,6 +102,7 @@ struct ubi_scan_volume { | |||
102 | * @mean_ec: mean erase counter value | 102 | * @mean_ec: mean erase counter value |
103 | * @ec_sum: a temporary variable used when calculating @mean_ec | 103 | * @ec_sum: a temporary variable used when calculating @mean_ec |
104 | * @ec_count: a temporary variable used when calculating @mean_ec | 104 | * @ec_count: a temporary variable used when calculating @mean_ec |
105 | * @image_seq_set: indicates @ubi->image_seq is known | ||
105 | * | 106 | * |
106 | * This data structure contains the result of scanning and may be used by other | 107 | * This data structure contains the result of scanning and may be used by other |
107 | * UBI sub-systems to build final UBI data structures, further error-recovery | 108 | * UBI sub-systems to build final UBI data structures, further error-recovery |
@@ -124,6 +125,7 @@ struct ubi_scan_info { | |||
124 | int mean_ec; | 125 | int mean_ec; |
125 | uint64_t ec_sum; | 126 | uint64_t ec_sum; |
126 | int ec_count; | 127 | int ec_count; |
128 | int image_seq_set; | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | struct ubi_device; | 131 | struct ubi_device; |
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h index 8419fdccc79c..503ea9b27309 100644 --- a/drivers/mtd/ubi/ubi-media.h +++ b/drivers/mtd/ubi/ubi-media.h | |||
@@ -129,6 +129,7 @@ enum { | |||
129 | * @ec: the erase counter | 129 | * @ec: the erase counter |
130 | * @vid_hdr_offset: where the VID header starts | 130 | * @vid_hdr_offset: where the VID header starts |
131 | * @data_offset: where the user data start | 131 | * @data_offset: where the user data start |
132 | * @image_seq: image sequence number | ||
132 | * @padding2: reserved for future, zeroes | 133 | * @padding2: reserved for future, zeroes |
133 | * @hdr_crc: erase counter header CRC checksum | 134 | * @hdr_crc: erase counter header CRC checksum |
134 | * | 135 | * |
@@ -144,6 +145,14 @@ enum { | |||
144 | * volume identifier header and user data, relative to the beginning of the | 145 | * volume identifier header and user data, relative to the beginning of the |
145 | * physical eraseblock. These values have to be the same for all physical | 146 | * physical eraseblock. These values have to be the same for all physical |
146 | * eraseblocks. | 147 | * eraseblocks. |
148 | * | ||
149 | * The @image_seq field is used to validate a UBI image that has been prepared | ||
150 | * for a UBI device. The @image_seq value can be any value, but it must be the | ||
151 | * same on all eraseblocks. UBI will ensure that all new erase counter headers | ||
152 | * also contain this value, and will check the value when scanning at start-up. | ||
153 | * One way to make use of @image_seq is to increase its value by one every time | ||
154 | * an image is flashed over an existing image, then, if the flashing does not | ||
155 | * complete, UBI will detect the error when scanning. | ||
147 | */ | 156 | */ |
148 | struct ubi_ec_hdr { | 157 | struct ubi_ec_hdr { |
149 | __be32 magic; | 158 | __be32 magic; |
@@ -152,7 +161,8 @@ struct ubi_ec_hdr { | |||
152 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ | 161 | __be64 ec; /* Warning: the current limit is 31-bit anyway! */ |
153 | __be32 vid_hdr_offset; | 162 | __be32 vid_hdr_offset; |
154 | __be32 data_offset; | 163 | __be32 data_offset; |
155 | __u8 padding2[36]; | 164 | __be32 image_seq; |
165 | __u8 padding2[32]; | ||
156 | __be32 hdr_crc; | 166 | __be32 hdr_crc; |
157 | } __attribute__ ((packed)); | 167 | } __attribute__ ((packed)); |
158 | 168 | ||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 28acd133c997..6a5fe9633783 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -301,6 +301,7 @@ struct ubi_wl_entry; | |||
301 | * @vol->readers, @vol->writers, @vol->exclusive, | 301 | * @vol->readers, @vol->writers, @vol->exclusive, |
302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. | 302 | * @vol->ref_count, @vol->mapping and @vol->eba_tbl. |
303 | * @ref_count: count of references on the UBI device | 303 | * @ref_count: count of references on the UBI device |
304 | * @image_seq: image sequence number recorded on EC headers | ||
304 | * | 305 | * |
305 | * @rsvd_pebs: count of reserved physical eraseblocks | 306 | * @rsvd_pebs: count of reserved physical eraseblocks |
306 | * @avail_pebs: count of available physical eraseblocks | 307 | * @avail_pebs: count of available physical eraseblocks |
@@ -372,6 +373,7 @@ struct ubi_wl_entry; | |||
372 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset | 373 | * @vid_hdr_shift: contains @vid_hdr_offset - @vid_hdr_aloffset |
373 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or | 374 | * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or |
374 | * not | 375 | * not |
376 | * @nor_flash: non-zero if working on top of NOR flash | ||
375 | * @mtd: MTD device descriptor | 377 | * @mtd: MTD device descriptor |
376 | * | 378 | * |
377 | * @peb_buf1: a buffer of PEB size used for different purposes | 379 | * @peb_buf1: a buffer of PEB size used for different purposes |
@@ -390,6 +392,7 @@ struct ubi_device { | |||
390 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; | 392 | struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT]; |
391 | spinlock_t volumes_lock; | 393 | spinlock_t volumes_lock; |
392 | int ref_count; | 394 | int ref_count; |
395 | int image_seq; | ||
393 | 396 | ||
394 | int rsvd_pebs; | 397 | int rsvd_pebs; |
395 | int avail_pebs; | 398 | int avail_pebs; |
@@ -452,7 +455,8 @@ struct ubi_device { | |||
452 | int vid_hdr_offset; | 455 | int vid_hdr_offset; |
453 | int vid_hdr_aloffset; | 456 | int vid_hdr_aloffset; |
454 | int vid_hdr_shift; | 457 | int vid_hdr_shift; |
455 | int bad_allowed; | 458 | unsigned int bad_allowed:1; |
459 | unsigned int nor_flash:1; | ||
456 | struct mtd_info *mtd; | 460 | struct mtd_info *mtd; |
457 | 461 | ||
458 | void *peb_buf1; | 462 | void *peb_buf1; |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 2b2472300610..600c7229d5cf 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -459,6 +459,14 @@ retry: | |||
459 | dbg_wl("PEB %d EC %d", e->pnum, e->ec); | 459 | dbg_wl("PEB %d EC %d", e->pnum, e->ec); |
460 | prot_queue_add(ubi, e); | 460 | prot_queue_add(ubi, e); |
461 | spin_unlock(&ubi->wl_lock); | 461 | spin_unlock(&ubi->wl_lock); |
462 | |||
463 | err = ubi_dbg_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, | ||
464 | ubi->peb_size - ubi->vid_hdr_aloffset); | ||
465 | if (err) { | ||
466 | ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); | ||
467 | return err > 0 ? -EINVAL : err; | ||
468 | } | ||
469 | |||
462 | return e->pnum; | 470 | return e->pnum; |
463 | } | 471 | } |
464 | 472 | ||
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 8ae72ec14456..0e2ba21d4441 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -908,6 +908,7 @@ static const struct net_device_ops rtl8139_netdev_ops = { | |||
908 | .ndo_open = rtl8139_open, | 908 | .ndo_open = rtl8139_open, |
909 | .ndo_stop = rtl8139_close, | 909 | .ndo_stop = rtl8139_close, |
910 | .ndo_get_stats = rtl8139_get_stats, | 910 | .ndo_get_stats = rtl8139_get_stats, |
911 | .ndo_change_mtu = eth_change_mtu, | ||
911 | .ndo_validate_addr = eth_validate_addr, | 912 | .ndo_validate_addr = eth_validate_addr, |
912 | .ndo_set_mac_address = rtl8139_set_mac_address, | 913 | .ndo_set_mac_address = rtl8139_set_mac_address, |
913 | .ndo_start_xmit = rtl8139_start_xmit, | 914 | .ndo_start_xmit = rtl8139_start_xmit, |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c155bd3ec9f1..b5a7513df4eb 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1729,6 +1729,12 @@ config KS8842 | |||
1729 | help | 1729 | help |
1730 | This platform driver is for Micrel KSZ8842 chip. | 1730 | This platform driver is for Micrel KSZ8842 chip. |
1731 | 1731 | ||
1732 | config KS8851 | ||
1733 | tristate "Micrel KS8851 SPI" | ||
1734 | depends on SPI | ||
1735 | help | ||
1736 | SPI driver for Micrel KS8851 SPI attached network chip. | ||
1737 | |||
1732 | config VIA_RHINE | 1738 | config VIA_RHINE |
1733 | tristate "VIA Rhine support" | 1739 | tristate "VIA Rhine support" |
1734 | depends on NET_PCI && PCI | 1740 | depends on NET_PCI && PCI |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 4b58a59f211b..ead8cab3cfe1 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -88,6 +88,7 @@ obj-$(CONFIG_SKGE) += skge.o | |||
88 | obj-$(CONFIG_SKY2) += sky2.o | 88 | obj-$(CONFIG_SKY2) += sky2.o |
89 | obj-$(CONFIG_SKFP) += skfp/ | 89 | obj-$(CONFIG_SKFP) += skfp/ |
90 | obj-$(CONFIG_KS8842) += ks8842.o | 90 | obj-$(CONFIG_KS8842) += ks8842.o |
91 | obj-$(CONFIG_KS8851) += ks8851.o | ||
91 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o | 92 | obj-$(CONFIG_VIA_RHINE) += via-rhine.o |
92 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o | 93 | obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o |
93 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o | 94 | obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o |
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig index 2895db13bfa4..c37ee9e6b67b 100644 --- a/drivers/net/arm/Kconfig +++ b/drivers/net/arm/Kconfig | |||
@@ -63,3 +63,11 @@ config IXP4XX_ETH | |||
63 | help | 63 | help |
64 | Say Y here if you want to use built-in Ethernet ports | 64 | Say Y here if you want to use built-in Ethernet ports |
65 | on IXP4xx processor. | 65 | on IXP4xx processor. |
66 | |||
67 | config W90P910_ETH | ||
68 | tristate "Nuvoton w90p910 Ethernet support" | ||
69 | depends on ARM && ARCH_W90X900 | ||
70 | select PHYLIB | ||
71 | help | ||
72 | Say Y here if you want to use built-in Ethernet ports | ||
73 | on w90p910 processor. | ||
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile index 811a3ccd14c1..303171f589e6 100644 --- a/drivers/net/arm/Makefile +++ b/drivers/net/arm/Makefile | |||
@@ -11,3 +11,4 @@ obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o | |||
11 | obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o | 11 | obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o |
12 | obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o | 12 | obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o |
13 | obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o | 13 | obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o |
14 | obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o | ||
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c index 6f42ad728915..3fe09876e76d 100644 --- a/drivers/net/arm/ixp4xx_eth.c +++ b/drivers/net/arm/ixp4xx_eth.c | |||
@@ -1142,7 +1142,9 @@ static const struct net_device_ops ixp4xx_netdev_ops = { | |||
1142 | .ndo_start_xmit = eth_xmit, | 1142 | .ndo_start_xmit = eth_xmit, |
1143 | .ndo_set_multicast_list = eth_set_mcast_list, | 1143 | .ndo_set_multicast_list = eth_set_mcast_list, |
1144 | .ndo_do_ioctl = eth_ioctl, | 1144 | .ndo_do_ioctl = eth_ioctl, |
1145 | 1145 | .ndo_change_mtu = eth_change_mtu, | |
1146 | .ndo_set_mac_address = eth_mac_addr, | ||
1147 | .ndo_validate_addr = eth_validate_addr, | ||
1146 | }; | 1148 | }; |
1147 | 1149 | ||
1148 | static int __devinit eth_init_one(struct platform_device *pdev) | 1150 | static int __devinit eth_init_one(struct platform_device *pdev) |
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c new file mode 100644 index 000000000000..616fb7985a34 --- /dev/null +++ b/drivers/net/arm/w90p910_ether.c | |||
@@ -0,0 +1,1105 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Nuvoton technology corporation. | ||
3 | * | ||
4 | * Wan ZongShun <mcuos.com@gmail.com> | ||
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 as published by | ||
8 | * the Free Software Foundation;version 2 of the License. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/mii.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/skbuff.h> | ||
18 | #include <linux/ethtool.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/clk.h> | ||
21 | |||
22 | #define DRV_MODULE_NAME "w90p910-emc" | ||
23 | #define DRV_MODULE_VERSION "0.1" | ||
24 | |||
25 | /* Ethernet MAC Registers */ | ||
26 | #define REG_CAMCMR 0x00 | ||
27 | #define REG_CAMEN 0x04 | ||
28 | #define REG_CAMM_BASE 0x08 | ||
29 | #define REG_CAML_BASE 0x0c | ||
30 | #define REG_TXDLSA 0x88 | ||
31 | #define REG_RXDLSA 0x8C | ||
32 | #define REG_MCMDR 0x90 | ||
33 | #define REG_MIID 0x94 | ||
34 | #define REG_MIIDA 0x98 | ||
35 | #define REG_FFTCR 0x9C | ||
36 | #define REG_TSDR 0xa0 | ||
37 | #define REG_RSDR 0xa4 | ||
38 | #define REG_DMARFC 0xa8 | ||
39 | #define REG_MIEN 0xac | ||
40 | #define REG_MISTA 0xb0 | ||
41 | #define REG_CTXDSA 0xcc | ||
42 | #define REG_CTXBSA 0xd0 | ||
43 | #define REG_CRXDSA 0xd4 | ||
44 | #define REG_CRXBSA 0xd8 | ||
45 | |||
46 | /* mac controller bit */ | ||
47 | #define MCMDR_RXON 0x01 | ||
48 | #define MCMDR_ACP (0x01 << 3) | ||
49 | #define MCMDR_SPCRC (0x01 << 5) | ||
50 | #define MCMDR_TXON (0x01 << 8) | ||
51 | #define MCMDR_FDUP (0x01 << 18) | ||
52 | #define MCMDR_ENMDC (0x01 << 19) | ||
53 | #define MCMDR_OPMOD (0x01 << 20) | ||
54 | #define SWR (0x01 << 24) | ||
55 | |||
56 | /* cam command regiser */ | ||
57 | #define CAMCMR_AUP 0x01 | ||
58 | #define CAMCMR_AMP (0x01 << 1) | ||
59 | #define CAMCMR_ABP (0x01 << 2) | ||
60 | #define CAMCMR_CCAM (0x01 << 3) | ||
61 | #define CAMCMR_ECMP (0x01 << 4) | ||
62 | #define CAM0EN 0x01 | ||
63 | |||
64 | /* mac mii controller bit */ | ||
65 | #define MDCCR (0x0a << 20) | ||
66 | #define PHYAD (0x01 << 8) | ||
67 | #define PHYWR (0x01 << 16) | ||
68 | #define PHYBUSY (0x01 << 17) | ||
69 | #define PHYPRESP (0x01 << 18) | ||
70 | #define CAM_ENTRY_SIZE 0x08 | ||
71 | |||
72 | /* rx and tx status */ | ||
73 | #define TXDS_TXCP (0x01 << 19) | ||
74 | #define RXDS_CRCE (0x01 << 17) | ||
75 | #define RXDS_PTLE (0x01 << 19) | ||
76 | #define RXDS_RXGD (0x01 << 20) | ||
77 | #define RXDS_ALIE (0x01 << 21) | ||
78 | #define RXDS_RP (0x01 << 22) | ||
79 | |||
80 | /* mac interrupt status*/ | ||
81 | #define MISTA_EXDEF (0x01 << 19) | ||
82 | #define MISTA_TXBERR (0x01 << 24) | ||
83 | #define MISTA_TDU (0x01 << 23) | ||
84 | #define MISTA_RDU (0x01 << 10) | ||
85 | #define MISTA_RXBERR (0x01 << 11) | ||
86 | |||
87 | #define ENSTART 0x01 | ||
88 | #define ENRXINTR 0x01 | ||
89 | #define ENRXGD (0x01 << 4) | ||
90 | #define ENRXBERR (0x01 << 11) | ||
91 | #define ENTXINTR (0x01 << 16) | ||
92 | #define ENTXCP (0x01 << 18) | ||
93 | #define ENTXABT (0x01 << 21) | ||
94 | #define ENTXBERR (0x01 << 24) | ||
95 | #define ENMDC (0x01 << 19) | ||
96 | #define PHYBUSY (0x01 << 17) | ||
97 | #define MDCCR_VAL 0xa00000 | ||
98 | |||
99 | /* rx and tx owner bit */ | ||
100 | #define RX_OWEN_DMA (0x01 << 31) | ||
101 | #define RX_OWEN_CPU (~(0x03 << 30)) | ||
102 | #define TX_OWEN_DMA (0x01 << 31) | ||
103 | #define TX_OWEN_CPU (~(0x01 << 31)) | ||
104 | |||
105 | /* tx frame desc controller bit */ | ||
106 | #define MACTXINTEN 0x04 | ||
107 | #define CRCMODE 0x02 | ||
108 | #define PADDINGMODE 0x01 | ||
109 | |||
110 | /* fftcr controller bit */ | ||
111 | #define TXTHD (0x03 << 8) | ||
112 | #define BLENGTH (0x01 << 20) | ||
113 | |||
114 | /* global setting for driver */ | ||
115 | #define RX_DESC_SIZE 50 | ||
116 | #define TX_DESC_SIZE 10 | ||
117 | #define MAX_RBUFF_SZ 0x600 | ||
118 | #define MAX_TBUFF_SZ 0x600 | ||
119 | #define TX_TIMEOUT 50 | ||
120 | #define DELAY 1000 | ||
121 | #define CAM0 0x0 | ||
122 | |||
123 | static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg); | ||
124 | |||
125 | struct w90p910_rxbd { | ||
126 | unsigned int sl; | ||
127 | unsigned int buffer; | ||
128 | unsigned int reserved; | ||
129 | unsigned int next; | ||
130 | }; | ||
131 | |||
132 | struct w90p910_txbd { | ||
133 | unsigned int mode; | ||
134 | unsigned int buffer; | ||
135 | unsigned int sl; | ||
136 | unsigned int next; | ||
137 | }; | ||
138 | |||
139 | struct recv_pdesc { | ||
140 | struct w90p910_rxbd desclist[RX_DESC_SIZE]; | ||
141 | char recv_buf[RX_DESC_SIZE][MAX_RBUFF_SZ]; | ||
142 | }; | ||
143 | |||
144 | struct tran_pdesc { | ||
145 | struct w90p910_txbd desclist[TX_DESC_SIZE]; | ||
146 | char tran_buf[RX_DESC_SIZE][MAX_TBUFF_SZ]; | ||
147 | }; | ||
148 | |||
149 | struct w90p910_ether { | ||
150 | struct recv_pdesc *rdesc; | ||
151 | struct recv_pdesc *rdesc_phys; | ||
152 | struct tran_pdesc *tdesc; | ||
153 | struct tran_pdesc *tdesc_phys; | ||
154 | struct net_device_stats stats; | ||
155 | struct platform_device *pdev; | ||
156 | struct sk_buff *skb; | ||
157 | struct clk *clk; | ||
158 | struct clk *rmiiclk; | ||
159 | struct mii_if_info mii; | ||
160 | struct timer_list check_timer; | ||
161 | void __iomem *reg; | ||
162 | unsigned int rxirq; | ||
163 | unsigned int txirq; | ||
164 | unsigned int cur_tx; | ||
165 | unsigned int cur_rx; | ||
166 | unsigned int finish_tx; | ||
167 | unsigned int rx_packets; | ||
168 | unsigned int rx_bytes; | ||
169 | unsigned int start_tx_ptr; | ||
170 | unsigned int start_rx_ptr; | ||
171 | unsigned int linkflag; | ||
172 | spinlock_t lock; | ||
173 | }; | ||
174 | |||
175 | static void update_linkspeed_register(struct net_device *dev, | ||
176 | unsigned int speed, unsigned int duplex) | ||
177 | { | ||
178 | struct w90p910_ether *ether = netdev_priv(dev); | ||
179 | unsigned int val; | ||
180 | |||
181 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
182 | |||
183 | if (speed == SPEED_100) { | ||
184 | /* 100 full/half duplex */ | ||
185 | if (duplex == DUPLEX_FULL) { | ||
186 | val |= (MCMDR_OPMOD | MCMDR_FDUP); | ||
187 | } else { | ||
188 | val |= MCMDR_OPMOD; | ||
189 | val &= ~MCMDR_FDUP; | ||
190 | } | ||
191 | } else { | ||
192 | /* 10 full/half duplex */ | ||
193 | if (duplex == DUPLEX_FULL) { | ||
194 | val |= MCMDR_FDUP; | ||
195 | val &= ~MCMDR_OPMOD; | ||
196 | } else { | ||
197 | val &= ~(MCMDR_FDUP | MCMDR_OPMOD); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
202 | } | ||
203 | |||
204 | static void update_linkspeed(struct net_device *dev) | ||
205 | { | ||
206 | struct w90p910_ether *ether = netdev_priv(dev); | ||
207 | struct platform_device *pdev; | ||
208 | unsigned int bmsr, bmcr, lpa, speed, duplex; | ||
209 | |||
210 | pdev = ether->pdev; | ||
211 | |||
212 | if (!mii_link_ok(ðer->mii)) { | ||
213 | ether->linkflag = 0x0; | ||
214 | netif_carrier_off(dev); | ||
215 | dev_warn(&pdev->dev, "%s: Link down.\n", dev->name); | ||
216 | return; | ||
217 | } | ||
218 | |||
219 | if (ether->linkflag == 1) | ||
220 | return; | ||
221 | |||
222 | bmsr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMSR); | ||
223 | bmcr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMCR); | ||
224 | |||
225 | if (bmcr & BMCR_ANENABLE) { | ||
226 | if (!(bmsr & BMSR_ANEGCOMPLETE)) | ||
227 | return; | ||
228 | |||
229 | lpa = w90p910_mdio_read(dev, ether->mii.phy_id, MII_LPA); | ||
230 | |||
231 | if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) | ||
232 | speed = SPEED_100; | ||
233 | else | ||
234 | speed = SPEED_10; | ||
235 | |||
236 | if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) | ||
237 | duplex = DUPLEX_FULL; | ||
238 | else | ||
239 | duplex = DUPLEX_HALF; | ||
240 | |||
241 | } else { | ||
242 | speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; | ||
243 | duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; | ||
244 | } | ||
245 | |||
246 | update_linkspeed_register(dev, speed, duplex); | ||
247 | |||
248 | dev_info(&pdev->dev, "%s: Link now %i-%s\n", dev->name, speed, | ||
249 | (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); | ||
250 | ether->linkflag = 0x01; | ||
251 | |||
252 | netif_carrier_on(dev); | ||
253 | } | ||
254 | |||
255 | static void w90p910_check_link(unsigned long dev_id) | ||
256 | { | ||
257 | struct net_device *dev = (struct net_device *) dev_id; | ||
258 | struct w90p910_ether *ether = netdev_priv(dev); | ||
259 | |||
260 | update_linkspeed(dev); | ||
261 | mod_timer(ðer->check_timer, jiffies + msecs_to_jiffies(1000)); | ||
262 | } | ||
263 | |||
264 | static void w90p910_write_cam(struct net_device *dev, | ||
265 | unsigned int x, unsigned char *pval) | ||
266 | { | ||
267 | struct w90p910_ether *ether = netdev_priv(dev); | ||
268 | unsigned int msw, lsw; | ||
269 | |||
270 | msw = (pval[0] << 24) | (pval[1] << 16) | (pval[2] << 8) | pval[3]; | ||
271 | |||
272 | lsw = (pval[4] << 24) | (pval[5] << 16); | ||
273 | |||
274 | __raw_writel(lsw, ether->reg + REG_CAML_BASE + x * CAM_ENTRY_SIZE); | ||
275 | __raw_writel(msw, ether->reg + REG_CAMM_BASE + x * CAM_ENTRY_SIZE); | ||
276 | } | ||
277 | |||
278 | static void w90p910_init_desc(struct net_device *dev) | ||
279 | { | ||
280 | struct w90p910_ether *ether; | ||
281 | struct w90p910_txbd *tdesc, *tdesc_phys; | ||
282 | struct w90p910_rxbd *rdesc, *rdesc_phys; | ||
283 | unsigned int i, j; | ||
284 | |||
285 | ether = netdev_priv(dev); | ||
286 | |||
287 | ether->tdesc = (struct tran_pdesc *) | ||
288 | dma_alloc_coherent(NULL, sizeof(struct tran_pdesc), | ||
289 | (dma_addr_t *) ðer->tdesc_phys, GFP_KERNEL); | ||
290 | |||
291 | ether->rdesc = (struct recv_pdesc *) | ||
292 | dma_alloc_coherent(NULL, sizeof(struct recv_pdesc), | ||
293 | (dma_addr_t *) ðer->rdesc_phys, GFP_KERNEL); | ||
294 | |||
295 | for (i = 0; i < TX_DESC_SIZE; i++) { | ||
296 | tdesc = &(ether->tdesc->desclist[i]); | ||
297 | |||
298 | j = ((i + 1) / TX_DESC_SIZE); | ||
299 | |||
300 | if (j != 0) { | ||
301 | tdesc_phys = &(ether->tdesc_phys->desclist[0]); | ||
302 | ether->start_tx_ptr = (unsigned int)tdesc_phys; | ||
303 | tdesc->next = (unsigned int)ether->start_tx_ptr; | ||
304 | } else { | ||
305 | tdesc_phys = &(ether->tdesc_phys->desclist[i+1]); | ||
306 | tdesc->next = (unsigned int)tdesc_phys; | ||
307 | } | ||
308 | |||
309 | tdesc->buffer = (unsigned int)ether->tdesc_phys->tran_buf[i]; | ||
310 | tdesc->sl = 0; | ||
311 | tdesc->mode = 0; | ||
312 | } | ||
313 | |||
314 | for (i = 0; i < RX_DESC_SIZE; i++) { | ||
315 | rdesc = &(ether->rdesc->desclist[i]); | ||
316 | |||
317 | j = ((i + 1) / RX_DESC_SIZE); | ||
318 | |||
319 | if (j != 0) { | ||
320 | rdesc_phys = &(ether->rdesc_phys->desclist[0]); | ||
321 | ether->start_rx_ptr = (unsigned int)rdesc_phys; | ||
322 | rdesc->next = (unsigned int)ether->start_rx_ptr; | ||
323 | } else { | ||
324 | rdesc_phys = &(ether->rdesc_phys->desclist[i+1]); | ||
325 | rdesc->next = (unsigned int)rdesc_phys; | ||
326 | } | ||
327 | |||
328 | rdesc->sl = RX_OWEN_DMA; | ||
329 | rdesc->buffer = (unsigned int)ether->rdesc_phys->recv_buf[i]; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | static void w90p910_set_fifo_threshold(struct net_device *dev) | ||
334 | { | ||
335 | struct w90p910_ether *ether = netdev_priv(dev); | ||
336 | unsigned int val; | ||
337 | |||
338 | val = TXTHD | BLENGTH; | ||
339 | __raw_writel(val, ether->reg + REG_FFTCR); | ||
340 | } | ||
341 | |||
342 | static void w90p910_return_default_idle(struct net_device *dev) | ||
343 | { | ||
344 | struct w90p910_ether *ether = netdev_priv(dev); | ||
345 | unsigned int val; | ||
346 | |||
347 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
348 | val |= SWR; | ||
349 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
350 | } | ||
351 | |||
352 | static void w90p910_trigger_rx(struct net_device *dev) | ||
353 | { | ||
354 | struct w90p910_ether *ether = netdev_priv(dev); | ||
355 | |||
356 | __raw_writel(ENSTART, ether->reg + REG_RSDR); | ||
357 | } | ||
358 | |||
359 | static void w90p910_trigger_tx(struct net_device *dev) | ||
360 | { | ||
361 | struct w90p910_ether *ether = netdev_priv(dev); | ||
362 | |||
363 | __raw_writel(ENSTART, ether->reg + REG_TSDR); | ||
364 | } | ||
365 | |||
366 | static void w90p910_enable_mac_interrupt(struct net_device *dev) | ||
367 | { | ||
368 | struct w90p910_ether *ether = netdev_priv(dev); | ||
369 | unsigned int val; | ||
370 | |||
371 | val = ENTXINTR | ENRXINTR | ENRXGD | ENTXCP; | ||
372 | val |= ENTXBERR | ENRXBERR | ENTXABT; | ||
373 | |||
374 | __raw_writel(val, ether->reg + REG_MIEN); | ||
375 | } | ||
376 | |||
377 | static void w90p910_get_and_clear_int(struct net_device *dev, | ||
378 | unsigned int *val) | ||
379 | { | ||
380 | struct w90p910_ether *ether = netdev_priv(dev); | ||
381 | |||
382 | *val = __raw_readl(ether->reg + REG_MISTA); | ||
383 | __raw_writel(*val, ether->reg + REG_MISTA); | ||
384 | } | ||
385 | |||
386 | static void w90p910_set_global_maccmd(struct net_device *dev) | ||
387 | { | ||
388 | struct w90p910_ether *ether = netdev_priv(dev); | ||
389 | unsigned int val; | ||
390 | |||
391 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
392 | val |= MCMDR_SPCRC | MCMDR_ENMDC | MCMDR_ACP | ENMDC; | ||
393 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
394 | } | ||
395 | |||
396 | static void w90p910_enable_cam(struct net_device *dev) | ||
397 | { | ||
398 | struct w90p910_ether *ether = netdev_priv(dev); | ||
399 | unsigned int val; | ||
400 | |||
401 | w90p910_write_cam(dev, CAM0, dev->dev_addr); | ||
402 | |||
403 | val = __raw_readl(ether->reg + REG_CAMEN); | ||
404 | val |= CAM0EN; | ||
405 | __raw_writel(val, ether->reg + REG_CAMEN); | ||
406 | } | ||
407 | |||
408 | static void w90p910_enable_cam_command(struct net_device *dev) | ||
409 | { | ||
410 | struct w90p910_ether *ether = netdev_priv(dev); | ||
411 | unsigned int val; | ||
412 | |||
413 | val = CAMCMR_ECMP | CAMCMR_ABP | CAMCMR_AMP; | ||
414 | __raw_writel(val, ether->reg + REG_CAMCMR); | ||
415 | } | ||
416 | |||
417 | static void w90p910_enable_tx(struct net_device *dev, unsigned int enable) | ||
418 | { | ||
419 | struct w90p910_ether *ether = netdev_priv(dev); | ||
420 | unsigned int val; | ||
421 | |||
422 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
423 | |||
424 | if (enable) | ||
425 | val |= MCMDR_TXON; | ||
426 | else | ||
427 | val &= ~MCMDR_TXON; | ||
428 | |||
429 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
430 | } | ||
431 | |||
432 | static void w90p910_enable_rx(struct net_device *dev, unsigned int enable) | ||
433 | { | ||
434 | struct w90p910_ether *ether = netdev_priv(dev); | ||
435 | unsigned int val; | ||
436 | |||
437 | val = __raw_readl(ether->reg + REG_MCMDR); | ||
438 | |||
439 | if (enable) | ||
440 | val |= MCMDR_RXON; | ||
441 | else | ||
442 | val &= ~MCMDR_RXON; | ||
443 | |||
444 | __raw_writel(val, ether->reg + REG_MCMDR); | ||
445 | } | ||
446 | |||
447 | static void w90p910_set_curdest(struct net_device *dev) | ||
448 | { | ||
449 | struct w90p910_ether *ether = netdev_priv(dev); | ||
450 | |||
451 | __raw_writel(ether->start_rx_ptr, ether->reg + REG_RXDLSA); | ||
452 | __raw_writel(ether->start_tx_ptr, ether->reg + REG_TXDLSA); | ||
453 | } | ||
454 | |||
455 | static void w90p910_reset_mac(struct net_device *dev) | ||
456 | { | ||
457 | struct w90p910_ether *ether = netdev_priv(dev); | ||
458 | |||
459 | spin_lock(ðer->lock); | ||
460 | |||
461 | w90p910_enable_tx(dev, 0); | ||
462 | w90p910_enable_rx(dev, 0); | ||
463 | w90p910_set_fifo_threshold(dev); | ||
464 | w90p910_return_default_idle(dev); | ||
465 | |||
466 | if (!netif_queue_stopped(dev)) | ||
467 | netif_stop_queue(dev); | ||
468 | |||
469 | w90p910_init_desc(dev); | ||
470 | |||
471 | dev->trans_start = jiffies; | ||
472 | ether->cur_tx = 0x0; | ||
473 | ether->finish_tx = 0x0; | ||
474 | ether->cur_rx = 0x0; | ||
475 | |||
476 | w90p910_set_curdest(dev); | ||
477 | w90p910_enable_cam(dev); | ||
478 | w90p910_enable_cam_command(dev); | ||
479 | w90p910_enable_mac_interrupt(dev); | ||
480 | w90p910_enable_tx(dev, 1); | ||
481 | w90p910_enable_rx(dev, 1); | ||
482 | w90p910_trigger_tx(dev); | ||
483 | w90p910_trigger_rx(dev); | ||
484 | |||
485 | dev->trans_start = jiffies; | ||
486 | |||
487 | if (netif_queue_stopped(dev)) | ||
488 | netif_wake_queue(dev); | ||
489 | |||
490 | spin_unlock(ðer->lock); | ||
491 | } | ||
492 | |||
493 | static void w90p910_mdio_write(struct net_device *dev, | ||
494 | int phy_id, int reg, int data) | ||
495 | { | ||
496 | struct w90p910_ether *ether = netdev_priv(dev); | ||
497 | struct platform_device *pdev; | ||
498 | unsigned int val, i; | ||
499 | |||
500 | pdev = ether->pdev; | ||
501 | |||
502 | __raw_writel(data, ether->reg + REG_MIID); | ||
503 | |||
504 | val = (phy_id << 0x08) | reg; | ||
505 | val |= PHYBUSY | PHYWR | MDCCR_VAL; | ||
506 | __raw_writel(val, ether->reg + REG_MIIDA); | ||
507 | |||
508 | for (i = 0; i < DELAY; i++) { | ||
509 | if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0) | ||
510 | break; | ||
511 | } | ||
512 | |||
513 | if (i == DELAY) | ||
514 | dev_warn(&pdev->dev, "mdio write timed out\n"); | ||
515 | } | ||
516 | |||
517 | static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg) | ||
518 | { | ||
519 | struct w90p910_ether *ether = netdev_priv(dev); | ||
520 | struct platform_device *pdev; | ||
521 | unsigned int val, i, data; | ||
522 | |||
523 | pdev = ether->pdev; | ||
524 | |||
525 | val = (phy_id << 0x08) | reg; | ||
526 | val |= PHYBUSY | MDCCR_VAL; | ||
527 | __raw_writel(val, ether->reg + REG_MIIDA); | ||
528 | |||
529 | for (i = 0; i < DELAY; i++) { | ||
530 | if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0) | ||
531 | break; | ||
532 | } | ||
533 | |||
534 | if (i == DELAY) { | ||
535 | dev_warn(&pdev->dev, "mdio read timed out\n"); | ||
536 | data = 0xffff; | ||
537 | } else { | ||
538 | data = __raw_readl(ether->reg + REG_MIID); | ||
539 | } | ||
540 | |||
541 | return data; | ||
542 | } | ||
543 | |||
544 | static int set_mac_address(struct net_device *dev, void *addr) | ||
545 | { | ||
546 | struct sockaddr *address = addr; | ||
547 | |||
548 | if (!is_valid_ether_addr(address->sa_data)) | ||
549 | return -EADDRNOTAVAIL; | ||
550 | |||
551 | memcpy(dev->dev_addr, address->sa_data, dev->addr_len); | ||
552 | w90p910_write_cam(dev, CAM0, dev->dev_addr); | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | static int w90p910_ether_close(struct net_device *dev) | ||
558 | { | ||
559 | struct w90p910_ether *ether = netdev_priv(dev); | ||
560 | |||
561 | dma_free_writecombine(NULL, sizeof(struct w90p910_rxbd), | ||
562 | ether->rdesc, (dma_addr_t)ether->rdesc_phys); | ||
563 | dma_free_writecombine(NULL, sizeof(struct w90p910_txbd), | ||
564 | ether->tdesc, (dma_addr_t)ether->tdesc_phys); | ||
565 | |||
566 | netif_stop_queue(dev); | ||
567 | |||
568 | del_timer_sync(ðer->check_timer); | ||
569 | clk_disable(ether->rmiiclk); | ||
570 | clk_disable(ether->clk); | ||
571 | |||
572 | free_irq(ether->txirq, dev); | ||
573 | free_irq(ether->rxirq, dev); | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | static struct net_device_stats *w90p910_ether_stats(struct net_device *dev) | ||
579 | { | ||
580 | struct w90p910_ether *ether; | ||
581 | |||
582 | ether = netdev_priv(dev); | ||
583 | |||
584 | return ðer->stats; | ||
585 | } | ||
586 | |||
587 | static int w90p910_send_frame(struct net_device *dev, | ||
588 | unsigned char *data, int length) | ||
589 | { | ||
590 | struct w90p910_ether *ether; | ||
591 | struct w90p910_txbd *txbd; | ||
592 | struct platform_device *pdev; | ||
593 | unsigned char *buffer; | ||
594 | |||
595 | ether = netdev_priv(dev); | ||
596 | pdev = ether->pdev; | ||
597 | |||
598 | txbd = ðer->tdesc->desclist[ether->cur_tx]; | ||
599 | buffer = ether->tdesc->tran_buf[ether->cur_tx]; | ||
600 | if (length > 1514) { | ||
601 | dev_err(&pdev->dev, "send data %d bytes, check it\n", length); | ||
602 | length = 1514; | ||
603 | } | ||
604 | |||
605 | txbd->sl = length & 0xFFFF; | ||
606 | |||
607 | memcpy(buffer, data, length); | ||
608 | |||
609 | txbd->mode = TX_OWEN_DMA | PADDINGMODE | CRCMODE | MACTXINTEN; | ||
610 | |||
611 | w90p910_enable_tx(dev, 1); | ||
612 | |||
613 | w90p910_trigger_tx(dev); | ||
614 | |||
615 | ether->cur_tx = (ether->cur_tx+1) % TX_DESC_SIZE; | ||
616 | txbd = ðer->tdesc->desclist[ether->cur_tx]; | ||
617 | |||
618 | dev->trans_start = jiffies; | ||
619 | |||
620 | if (txbd->mode & TX_OWEN_DMA) | ||
621 | netif_stop_queue(dev); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int w90p910_ether_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
627 | { | ||
628 | struct w90p910_ether *ether = netdev_priv(dev); | ||
629 | |||
630 | if (!(w90p910_send_frame(dev, skb->data, skb->len))) { | ||
631 | ether->skb = skb; | ||
632 | dev_kfree_skb_irq(skb); | ||
633 | return 0; | ||
634 | } | ||
635 | return -1; | ||
636 | } | ||
637 | |||
638 | static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id) | ||
639 | { | ||
640 | struct w90p910_ether *ether; | ||
641 | struct w90p910_txbd *txbd; | ||
642 | struct platform_device *pdev; | ||
643 | struct tran_pdesc *tran_pdesc; | ||
644 | struct net_device *dev; | ||
645 | unsigned int cur_entry, entry, status; | ||
646 | |||
647 | dev = (struct net_device *)dev_id; | ||
648 | ether = netdev_priv(dev); | ||
649 | pdev = ether->pdev; | ||
650 | |||
651 | spin_lock(ðer->lock); | ||
652 | |||
653 | w90p910_get_and_clear_int(dev, &status); | ||
654 | |||
655 | cur_entry = __raw_readl(ether->reg + REG_CTXDSA); | ||
656 | |||
657 | tran_pdesc = ether->tdesc_phys; | ||
658 | entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); | ||
659 | |||
660 | while (entry != cur_entry) { | ||
661 | txbd = ðer->tdesc->desclist[ether->finish_tx]; | ||
662 | |||
663 | ether->finish_tx = (ether->finish_tx + 1) % TX_DESC_SIZE; | ||
664 | |||
665 | if (txbd->sl & TXDS_TXCP) { | ||
666 | ether->stats.tx_packets++; | ||
667 | ether->stats.tx_bytes += txbd->sl & 0xFFFF; | ||
668 | } else { | ||
669 | ether->stats.tx_errors++; | ||
670 | } | ||
671 | |||
672 | txbd->sl = 0x0; | ||
673 | txbd->mode = 0x0; | ||
674 | |||
675 | if (netif_queue_stopped(dev)) | ||
676 | netif_wake_queue(dev); | ||
677 | |||
678 | entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); | ||
679 | } | ||
680 | |||
681 | if (status & MISTA_EXDEF) { | ||
682 | dev_err(&pdev->dev, "emc defer exceed interrupt\n"); | ||
683 | } else if (status & MISTA_TXBERR) { | ||
684 | dev_err(&pdev->dev, "emc bus error interrupt\n"); | ||
685 | w90p910_reset_mac(dev); | ||
686 | } else if (status & MISTA_TDU) { | ||
687 | if (netif_queue_stopped(dev)) | ||
688 | netif_wake_queue(dev); | ||
689 | } | ||
690 | |||
691 | spin_unlock(ðer->lock); | ||
692 | |||
693 | return IRQ_HANDLED; | ||
694 | } | ||
695 | |||
696 | static void netdev_rx(struct net_device *dev) | ||
697 | { | ||
698 | struct w90p910_ether *ether; | ||
699 | struct w90p910_rxbd *rxbd; | ||
700 | struct platform_device *pdev; | ||
701 | struct recv_pdesc *rdesc_phys; | ||
702 | struct sk_buff *skb; | ||
703 | unsigned char *data; | ||
704 | unsigned int length, status, val, entry; | ||
705 | |||
706 | ether = netdev_priv(dev); | ||
707 | pdev = ether->pdev; | ||
708 | rdesc_phys = ether->rdesc_phys; | ||
709 | |||
710 | rxbd = ðer->rdesc->desclist[ether->cur_rx]; | ||
711 | |||
712 | do { | ||
713 | val = __raw_readl(ether->reg + REG_CRXDSA); | ||
714 | entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx]; | ||
715 | |||
716 | if (val == entry) | ||
717 | break; | ||
718 | |||
719 | status = rxbd->sl; | ||
720 | length = status & 0xFFFF; | ||
721 | |||
722 | if (status & RXDS_RXGD) { | ||
723 | data = ether->rdesc->recv_buf[ether->cur_rx]; | ||
724 | skb = dev_alloc_skb(length+2); | ||
725 | if (!skb) { | ||
726 | dev_err(&pdev->dev, "get skb buffer error\n"); | ||
727 | ether->stats.rx_dropped++; | ||
728 | return; | ||
729 | } | ||
730 | |||
731 | skb->dev = dev; | ||
732 | skb_reserve(skb, 2); | ||
733 | skb_put(skb, length); | ||
734 | skb_copy_to_linear_data(skb, data, length); | ||
735 | skb->protocol = eth_type_trans(skb, dev); | ||
736 | ether->stats.rx_packets++; | ||
737 | ether->stats.rx_bytes += length; | ||
738 | netif_rx(skb); | ||
739 | } else { | ||
740 | ether->stats.rx_errors++; | ||
741 | |||
742 | if (status & RXDS_RP) { | ||
743 | dev_err(&pdev->dev, "rx runt err\n"); | ||
744 | ether->stats.rx_length_errors++; | ||
745 | } else if (status & RXDS_CRCE) { | ||
746 | dev_err(&pdev->dev, "rx crc err\n"); | ||
747 | ether->stats.rx_crc_errors++; | ||
748 | } | ||
749 | |||
750 | if (status & RXDS_ALIE) { | ||
751 | dev_err(&pdev->dev, "rx aligment err\n"); | ||
752 | ether->stats.rx_frame_errors++; | ||
753 | } else if (status & RXDS_PTLE) { | ||
754 | dev_err(&pdev->dev, "rx longer err\n"); | ||
755 | ether->stats.rx_over_errors++; | ||
756 | } | ||
757 | } | ||
758 | |||
759 | rxbd->sl = RX_OWEN_DMA; | ||
760 | rxbd->reserved = 0x0; | ||
761 | ether->cur_rx = (ether->cur_rx+1) % RX_DESC_SIZE; | ||
762 | rxbd = ðer->rdesc->desclist[ether->cur_rx]; | ||
763 | |||
764 | dev->last_rx = jiffies; | ||
765 | } while (1); | ||
766 | } | ||
767 | |||
768 | static irqreturn_t w90p910_rx_interrupt(int irq, void *dev_id) | ||
769 | { | ||
770 | struct net_device *dev; | ||
771 | struct w90p910_ether *ether; | ||
772 | struct platform_device *pdev; | ||
773 | unsigned int status; | ||
774 | |||
775 | dev = (struct net_device *)dev_id; | ||
776 | ether = netdev_priv(dev); | ||
777 | pdev = ether->pdev; | ||
778 | |||
779 | spin_lock(ðer->lock); | ||
780 | |||
781 | w90p910_get_and_clear_int(dev, &status); | ||
782 | |||
783 | if (status & MISTA_RDU) { | ||
784 | netdev_rx(dev); | ||
785 | |||
786 | w90p910_trigger_rx(dev); | ||
787 | |||
788 | spin_unlock(ðer->lock); | ||
789 | return IRQ_HANDLED; | ||
790 | } else if (status & MISTA_RXBERR) { | ||
791 | dev_err(&pdev->dev, "emc rx bus error\n"); | ||
792 | w90p910_reset_mac(dev); | ||
793 | } | ||
794 | |||
795 | netdev_rx(dev); | ||
796 | spin_unlock(ðer->lock); | ||
797 | return IRQ_HANDLED; | ||
798 | } | ||
799 | |||
800 | static int w90p910_ether_open(struct net_device *dev) | ||
801 | { | ||
802 | struct w90p910_ether *ether; | ||
803 | struct platform_device *pdev; | ||
804 | |||
805 | ether = netdev_priv(dev); | ||
806 | pdev = ether->pdev; | ||
807 | |||
808 | w90p910_reset_mac(dev); | ||
809 | w90p910_set_fifo_threshold(dev); | ||
810 | w90p910_set_curdest(dev); | ||
811 | w90p910_enable_cam(dev); | ||
812 | w90p910_enable_cam_command(dev); | ||
813 | w90p910_enable_mac_interrupt(dev); | ||
814 | w90p910_set_global_maccmd(dev); | ||
815 | w90p910_enable_rx(dev, 1); | ||
816 | |||
817 | ether->rx_packets = 0x0; | ||
818 | ether->rx_bytes = 0x0; | ||
819 | |||
820 | if (request_irq(ether->txirq, w90p910_tx_interrupt, | ||
821 | 0x0, pdev->name, dev)) { | ||
822 | dev_err(&pdev->dev, "register irq tx failed\n"); | ||
823 | return -EAGAIN; | ||
824 | } | ||
825 | |||
826 | if (request_irq(ether->rxirq, w90p910_rx_interrupt, | ||
827 | 0x0, pdev->name, dev)) { | ||
828 | dev_err(&pdev->dev, "register irq rx failed\n"); | ||
829 | return -EAGAIN; | ||
830 | } | ||
831 | |||
832 | mod_timer(ðer->check_timer, jiffies + msecs_to_jiffies(1000)); | ||
833 | netif_start_queue(dev); | ||
834 | w90p910_trigger_rx(dev); | ||
835 | |||
836 | dev_info(&pdev->dev, "%s is OPENED\n", dev->name); | ||
837 | |||
838 | return 0; | ||
839 | } | ||
840 | |||
841 | static void w90p910_ether_set_multicast_list(struct net_device *dev) | ||
842 | { | ||
843 | struct w90p910_ether *ether; | ||
844 | unsigned int rx_mode; | ||
845 | |||
846 | ether = netdev_priv(dev); | ||
847 | |||
848 | if (dev->flags & IFF_PROMISC) | ||
849 | rx_mode = CAMCMR_AUP | CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; | ||
850 | else if ((dev->flags & IFF_ALLMULTI) || dev->mc_list) | ||
851 | rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP; | ||
852 | else | ||
853 | rx_mode = CAMCMR_ECMP | CAMCMR_ABP; | ||
854 | __raw_writel(rx_mode, ether->reg + REG_CAMCMR); | ||
855 | } | ||
856 | |||
857 | static int w90p910_ether_ioctl(struct net_device *dev, | ||
858 | struct ifreq *ifr, int cmd) | ||
859 | { | ||
860 | struct w90p910_ether *ether = netdev_priv(dev); | ||
861 | struct mii_ioctl_data *data = if_mii(ifr); | ||
862 | |||
863 | return generic_mii_ioctl(ðer->mii, data, cmd, NULL); | ||
864 | } | ||
865 | |||
866 | static void w90p910_get_drvinfo(struct net_device *dev, | ||
867 | struct ethtool_drvinfo *info) | ||
868 | { | ||
869 | strcpy(info->driver, DRV_MODULE_NAME); | ||
870 | strcpy(info->version, DRV_MODULE_VERSION); | ||
871 | } | ||
872 | |||
873 | static int w90p910_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
874 | { | ||
875 | struct w90p910_ether *ether = netdev_priv(dev); | ||
876 | return mii_ethtool_gset(ðer->mii, cmd); | ||
877 | } | ||
878 | |||
879 | static int w90p910_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
880 | { | ||
881 | struct w90p910_ether *ether = netdev_priv(dev); | ||
882 | return mii_ethtool_sset(ðer->mii, cmd); | ||
883 | } | ||
884 | |||
885 | static int w90p910_nway_reset(struct net_device *dev) | ||
886 | { | ||
887 | struct w90p910_ether *ether = netdev_priv(dev); | ||
888 | return mii_nway_restart(ðer->mii); | ||
889 | } | ||
890 | |||
891 | static u32 w90p910_get_link(struct net_device *dev) | ||
892 | { | ||
893 | struct w90p910_ether *ether = netdev_priv(dev); | ||
894 | return mii_link_ok(ðer->mii); | ||
895 | } | ||
896 | |||
897 | static const struct ethtool_ops w90p910_ether_ethtool_ops = { | ||
898 | .get_settings = w90p910_get_settings, | ||
899 | .set_settings = w90p910_set_settings, | ||
900 | .get_drvinfo = w90p910_get_drvinfo, | ||
901 | .nway_reset = w90p910_nway_reset, | ||
902 | .get_link = w90p910_get_link, | ||
903 | }; | ||
904 | |||
905 | static const struct net_device_ops w90p910_ether_netdev_ops = { | ||
906 | .ndo_open = w90p910_ether_open, | ||
907 | .ndo_stop = w90p910_ether_close, | ||
908 | .ndo_start_xmit = w90p910_ether_start_xmit, | ||
909 | .ndo_get_stats = w90p910_ether_stats, | ||
910 | .ndo_set_multicast_list = w90p910_ether_set_multicast_list, | ||
911 | .ndo_set_mac_address = set_mac_address, | ||
912 | .ndo_do_ioctl = w90p910_ether_ioctl, | ||
913 | .ndo_validate_addr = eth_validate_addr, | ||
914 | .ndo_change_mtu = eth_change_mtu, | ||
915 | }; | ||
916 | |||
917 | static void __init get_mac_address(struct net_device *dev) | ||
918 | { | ||
919 | struct w90p910_ether *ether = netdev_priv(dev); | ||
920 | struct platform_device *pdev; | ||
921 | char addr[6]; | ||
922 | |||
923 | pdev = ether->pdev; | ||
924 | |||
925 | addr[0] = 0x00; | ||
926 | addr[1] = 0x02; | ||
927 | addr[2] = 0xac; | ||
928 | addr[3] = 0x55; | ||
929 | addr[4] = 0x88; | ||
930 | addr[5] = 0xa8; | ||
931 | |||
932 | if (is_valid_ether_addr(addr)) | ||
933 | memcpy(dev->dev_addr, &addr, 0x06); | ||
934 | else | ||
935 | dev_err(&pdev->dev, "invalid mac address\n"); | ||
936 | } | ||
937 | |||
938 | static int w90p910_ether_setup(struct net_device *dev) | ||
939 | { | ||
940 | struct w90p910_ether *ether = netdev_priv(dev); | ||
941 | |||
942 | ether_setup(dev); | ||
943 | dev->netdev_ops = &w90p910_ether_netdev_ops; | ||
944 | dev->ethtool_ops = &w90p910_ether_ethtool_ops; | ||
945 | |||
946 | dev->tx_queue_len = 16; | ||
947 | dev->dma = 0x0; | ||
948 | dev->watchdog_timeo = TX_TIMEOUT; | ||
949 | |||
950 | get_mac_address(dev); | ||
951 | |||
952 | spin_lock_init(ðer->lock); | ||
953 | |||
954 | ether->cur_tx = 0x0; | ||
955 | ether->cur_rx = 0x0; | ||
956 | ether->finish_tx = 0x0; | ||
957 | ether->linkflag = 0x0; | ||
958 | ether->mii.phy_id = 0x01; | ||
959 | ether->mii.phy_id_mask = 0x1f; | ||
960 | ether->mii.reg_num_mask = 0x1f; | ||
961 | ether->mii.dev = dev; | ||
962 | ether->mii.mdio_read = w90p910_mdio_read; | ||
963 | ether->mii.mdio_write = w90p910_mdio_write; | ||
964 | |||
965 | setup_timer(ðer->check_timer, w90p910_check_link, | ||
966 | (unsigned long)dev); | ||
967 | |||
968 | return 0; | ||
969 | } | ||
970 | |||
971 | static int __devinit w90p910_ether_probe(struct platform_device *pdev) | ||
972 | { | ||
973 | struct w90p910_ether *ether; | ||
974 | struct net_device *dev; | ||
975 | struct resource *res; | ||
976 | int error; | ||
977 | |||
978 | dev = alloc_etherdev(sizeof(struct w90p910_ether)); | ||
979 | if (!dev) | ||
980 | return -ENOMEM; | ||
981 | |||
982 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
983 | if (res == NULL) { | ||
984 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
985 | error = -ENXIO; | ||
986 | goto failed_free; | ||
987 | } | ||
988 | |||
989 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
990 | if (res == NULL) { | ||
991 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
992 | error = -EBUSY; | ||
993 | goto failed_free; | ||
994 | } | ||
995 | |||
996 | ether = netdev_priv(dev); | ||
997 | |||
998 | ether->reg = ioremap(res->start, resource_size(res)); | ||
999 | if (ether->reg == NULL) { | ||
1000 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
1001 | error = -ENXIO; | ||
1002 | goto failed_free_mem; | ||
1003 | } | ||
1004 | |||
1005 | ether->txirq = platform_get_irq(pdev, 0); | ||
1006 | if (ether->txirq < 0) { | ||
1007 | dev_err(&pdev->dev, "failed to get ether tx irq\n"); | ||
1008 | error = -ENXIO; | ||
1009 | goto failed_free_io; | ||
1010 | } | ||
1011 | |||
1012 | ether->rxirq = platform_get_irq(pdev, 1); | ||
1013 | if (ether->rxirq < 0) { | ||
1014 | dev_err(&pdev->dev, "failed to get ether rx irq\n"); | ||
1015 | error = -ENXIO; | ||
1016 | goto failed_free_txirq; | ||
1017 | } | ||
1018 | |||
1019 | platform_set_drvdata(pdev, dev); | ||
1020 | |||
1021 | ether->clk = clk_get(&pdev->dev, NULL); | ||
1022 | if (IS_ERR(ether->clk)) { | ||
1023 | dev_err(&pdev->dev, "failed to get ether clock\n"); | ||
1024 | error = PTR_ERR(ether->clk); | ||
1025 | goto failed_free_rxirq; | ||
1026 | } | ||
1027 | |||
1028 | ether->rmiiclk = clk_get(&pdev->dev, "RMII"); | ||
1029 | if (IS_ERR(ether->rmiiclk)) { | ||
1030 | dev_err(&pdev->dev, "failed to get ether clock\n"); | ||
1031 | error = PTR_ERR(ether->rmiiclk); | ||
1032 | goto failed_put_clk; | ||
1033 | } | ||
1034 | |||
1035 | ether->pdev = pdev; | ||
1036 | |||
1037 | w90p910_ether_setup(dev); | ||
1038 | |||
1039 | error = register_netdev(dev); | ||
1040 | if (error != 0) { | ||
1041 | dev_err(&pdev->dev, "Regiter EMC w90p910 FAILED\n"); | ||
1042 | error = -ENODEV; | ||
1043 | goto failed_put_rmiiclk; | ||
1044 | } | ||
1045 | |||
1046 | return 0; | ||
1047 | failed_put_rmiiclk: | ||
1048 | clk_put(ether->rmiiclk); | ||
1049 | failed_put_clk: | ||
1050 | clk_put(ether->clk); | ||
1051 | failed_free_rxirq: | ||
1052 | free_irq(ether->rxirq, pdev); | ||
1053 | platform_set_drvdata(pdev, NULL); | ||
1054 | failed_free_txirq: | ||
1055 | free_irq(ether->txirq, pdev); | ||
1056 | failed_free_io: | ||
1057 | iounmap(ether->reg); | ||
1058 | failed_free_mem: | ||
1059 | release_mem_region(res->start, resource_size(res)); | ||
1060 | failed_free: | ||
1061 | free_netdev(dev); | ||
1062 | return error; | ||
1063 | } | ||
1064 | |||
1065 | static int __devexit w90p910_ether_remove(struct platform_device *pdev) | ||
1066 | { | ||
1067 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1068 | struct w90p910_ether *ether = netdev_priv(dev); | ||
1069 | |||
1070 | unregister_netdev(dev); | ||
1071 | clk_put(ether->rmiiclk); | ||
1072 | clk_put(ether->clk); | ||
1073 | del_timer_sync(ðer->check_timer); | ||
1074 | platform_set_drvdata(pdev, NULL); | ||
1075 | free_netdev(dev); | ||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | static struct platform_driver w90p910_ether_driver = { | ||
1080 | .probe = w90p910_ether_probe, | ||
1081 | .remove = __devexit_p(w90p910_ether_remove), | ||
1082 | .driver = { | ||
1083 | .name = "w90p910-emc", | ||
1084 | .owner = THIS_MODULE, | ||
1085 | }, | ||
1086 | }; | ||
1087 | |||
1088 | static int __init w90p910_ether_init(void) | ||
1089 | { | ||
1090 | return platform_driver_register(&w90p910_ether_driver); | ||
1091 | } | ||
1092 | |||
1093 | static void __exit w90p910_ether_exit(void) | ||
1094 | { | ||
1095 | platform_driver_unregister(&w90p910_ether_driver); | ||
1096 | } | ||
1097 | |||
1098 | module_init(w90p910_ether_init); | ||
1099 | module_exit(w90p910_ether_exit); | ||
1100 | |||
1101 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | ||
1102 | MODULE_DESCRIPTION("w90p910 MAC driver!"); | ||
1103 | MODULE_LICENSE("GPL"); | ||
1104 | MODULE_ALIAS("platform:w90p910-emc"); | ||
1105 | |||
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index e1658ef3fcdf..2a1120ad2e74 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h | |||
@@ -188,14 +188,14 @@ struct atl1c_tpd_ext_desc { | |||
188 | #define RRS_HDS_TYPE_DATA 2 | 188 | #define RRS_HDS_TYPE_DATA 2 |
189 | 189 | ||
190 | #define RRS_IS_NO_HDS_TYPE(flag) \ | 190 | #define RRS_IS_NO_HDS_TYPE(flag) \ |
191 | (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0) | 191 | ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0) |
192 | 192 | ||
193 | #define RRS_IS_HDS_HEAD(flag) \ | 193 | #define RRS_IS_HDS_HEAD(flag) \ |
194 | (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ | 194 | ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \ |
195 | RRS_HDS_TYPE_HEAD) | 195 | RRS_HDS_TYPE_HEAD) |
196 | 196 | ||
197 | #define RRS_IS_HDS_DATA(flag) \ | 197 | #define RRS_IS_HDS_DATA(flag) \ |
198 | (((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \ | 198 | ((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \ |
199 | RRS_HDS_TYPE_DATA) | 199 | RRS_HDS_TYPE_DATA) |
200 | 200 | ||
201 | /* rrs word 3 bit 0:31 */ | 201 | /* rrs word 3 bit 0:31 */ |
@@ -245,7 +245,7 @@ struct atl1c_tpd_ext_desc { | |||
245 | #define RRS_PACKET_TYPE_802_3 1 | 245 | #define RRS_PACKET_TYPE_802_3 1 |
246 | #define RRS_PACKET_TYPE_ETH 0 | 246 | #define RRS_PACKET_TYPE_ETH 0 |
247 | #define RRS_PACKET_IS_ETH(word) \ | 247 | #define RRS_PACKET_IS_ETH(word) \ |
248 | (((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \ | 248 | ((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \ |
249 | RRS_PACKET_TYPE_ETH) | 249 | RRS_PACKET_TYPE_ETH) |
250 | #define RRS_RXD_IS_VALID(word) \ | 250 | #define RRS_RXD_IS_VALID(word) \ |
251 | ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1) | 251 | ((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1) |
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index cd547a205fb9..a383122679de 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
@@ -1689,7 +1689,7 @@ static void atl1c_clean_rx_irq(struct atl1c_adapter *adapter, u8 que, | |||
1689 | if (likely(RRS_RXD_IS_VALID(rrs->word3))) { | 1689 | if (likely(RRS_RXD_IS_VALID(rrs->word3))) { |
1690 | rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) & | 1690 | rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) & |
1691 | RRS_RX_RFD_CNT_MASK; | 1691 | RRS_RX_RFD_CNT_MASK; |
1692 | if (unlikely(rfd_num) != 1) | 1692 | if (unlikely(rfd_num != 1)) |
1693 | /* TODO support mul rfd*/ | 1693 | /* TODO support mul rfd*/ |
1694 | if (netif_msg_rx_err(adapter)) | 1694 | if (netif_msg_rx_err(adapter)) |
1695 | dev_warn(&pdev->dev, | 1695 | dev_warn(&pdev->dev, |
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index c734b1983ec1..204db961029e 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c | |||
@@ -2071,7 +2071,7 @@ static int atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
2071 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) | 2071 | if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) |
2072 | return -EOPNOTSUPP; | 2072 | return -EOPNOTSUPP; |
2073 | 2073 | ||
2074 | if (wol->wolopts & (WAKE_MCAST|WAKE_BCAST|WAKE_MCAST)) | 2074 | if (wol->wolopts & (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)) |
2075 | return -EOPNOTSUPP; | 2075 | return -EOPNOTSUPP; |
2076 | 2076 | ||
2077 | /* these settings will always override what we currently have */ | 2077 | /* these settings will always override what we currently have */ |
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index ed648acef7cf..2ee581a2cdec 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -4212,13 +4212,14 @@ static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port) | |||
4212 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | 4212 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, |
4213 | u8 *version, u16 len) | 4213 | u8 *version, u16 len) |
4214 | { | 4214 | { |
4215 | struct bnx2x *bp = params->bp; | 4215 | struct bnx2x *bp; |
4216 | u32 ext_phy_type = 0; | 4216 | u32 ext_phy_type = 0; |
4217 | u32 spirom_ver = 0; | 4217 | u32 spirom_ver = 0; |
4218 | u8 status = 0 ; | 4218 | u8 status = 0 ; |
4219 | 4219 | ||
4220 | if (version == NULL || params == NULL) | 4220 | if (version == NULL || params == NULL) |
4221 | return -EINVAL; | 4221 | return -EINVAL; |
4222 | bp = params->bp; | ||
4222 | 4223 | ||
4223 | spirom_ver = REG_RD(bp, params->shmem_base + | 4224 | spirom_ver = REG_RD(bp, params->shmem_base + |
4224 | offsetof(struct shmem_region, | 4225 | offsetof(struct shmem_region, |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d927f71af8a3..aa1be1feceed 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1459,8 +1459,16 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1459 | * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond | 1459 | * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond |
1460 | */ | 1460 | */ |
1461 | if (bond->slave_cnt == 0) { | 1461 | if (bond->slave_cnt == 0) { |
1462 | if (slave_dev->type != ARPHRD_ETHER) | 1462 | if (bond_dev->type != slave_dev->type) { |
1463 | bond_setup_by_slave(bond_dev, slave_dev); | 1463 | dev_close(bond_dev); |
1464 | pr_debug("%s: change device type from %d to %d\n", | ||
1465 | bond_dev->name, bond_dev->type, slave_dev->type); | ||
1466 | if (slave_dev->type != ARPHRD_ETHER) | ||
1467 | bond_setup_by_slave(bond_dev, slave_dev); | ||
1468 | else | ||
1469 | ether_setup(bond_dev); | ||
1470 | dev_open(bond_dev); | ||
1471 | } | ||
1464 | } else if (bond_dev->type != slave_dev->type) { | 1472 | } else if (bond_dev->type != slave_dev->type) { |
1465 | pr_err(DRV_NAME ": %s ether type (%d) is different " | 1473 | pr_err(DRV_NAME ": %s ether type (%d) is different " |
1466 | "from other slaves (%d), can not enslave it.\n", | 1474 | "from other slaves (%d), can not enslave it.\n", |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 574daddc21bf..9e4283aff828 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -346,7 +346,7 @@ void can_restart(unsigned long data) | |||
346 | skb = dev_alloc_skb(sizeof(struct can_frame)); | 346 | skb = dev_alloc_skb(sizeof(struct can_frame)); |
347 | if (skb == NULL) { | 347 | if (skb == NULL) { |
348 | err = -ENOMEM; | 348 | err = -ENOMEM; |
349 | goto out; | 349 | goto restart; |
350 | } | 350 | } |
351 | skb->dev = dev; | 351 | skb->dev = dev; |
352 | skb->protocol = htons(ETH_P_CAN); | 352 | skb->protocol = htons(ETH_P_CAN); |
@@ -361,13 +361,13 @@ void can_restart(unsigned long data) | |||
361 | stats->rx_packets++; | 361 | stats->rx_packets++; |
362 | stats->rx_bytes += cf->can_dlc; | 362 | stats->rx_bytes += cf->can_dlc; |
363 | 363 | ||
364 | restart: | ||
364 | dev_dbg(dev->dev.parent, "restarted\n"); | 365 | dev_dbg(dev->dev.parent, "restarted\n"); |
365 | priv->can_stats.restarts++; | 366 | priv->can_stats.restarts++; |
366 | 367 | ||
367 | /* Now restart the device */ | 368 | /* Now restart the device */ |
368 | err = priv->do_set_mode(dev, CAN_MODE_START); | 369 | err = priv->do_set_mode(dev, CAN_MODE_START); |
369 | 370 | ||
370 | out: | ||
371 | netif_carrier_on(dev); | 371 | netif_carrier_on(dev); |
372 | if (err) | 372 | if (err) |
373 | dev_err(dev->dev.parent, "Error %d during restart", err); | 373 | dev_err(dev->dev.parent, "Error %d during restart", err); |
@@ -473,6 +473,10 @@ int open_candev(struct net_device *dev) | |||
473 | return -EINVAL; | 473 | return -EINVAL; |
474 | } | 474 | } |
475 | 475 | ||
476 | /* Switch carrier on if device was stopped while in bus-off state */ | ||
477 | if (!netif_carrier_ok(dev)) | ||
478 | netif_carrier_on(dev); | ||
479 | |||
476 | setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev); | 480 | setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev); |
477 | 481 | ||
478 | return 0; | 482 | return 0; |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 571f133a8fec..08ebee79d8a6 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -63,7 +63,6 @@ | |||
63 | #include <linux/can.h> | 63 | #include <linux/can.h> |
64 | #include <linux/can/dev.h> | 64 | #include <linux/can/dev.h> |
65 | #include <linux/can/error.h> | 65 | #include <linux/can/error.h> |
66 | #include <linux/can/dev.h> | ||
67 | 66 | ||
68 | #include "sja1000.h" | 67 | #include "sja1000.h" |
69 | 68 | ||
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 3eee666a9cd2..55445f980f9c 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -1524,6 +1524,7 @@ static void net_timeout(struct net_device *dev) | |||
1524 | static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | 1524 | static int net_send_packet(struct sk_buff *skb, struct net_device *dev) |
1525 | { | 1525 | { |
1526 | struct net_local *lp = netdev_priv(dev); | 1526 | struct net_local *lp = netdev_priv(dev); |
1527 | unsigned long flags; | ||
1527 | 1528 | ||
1528 | if (net_debug > 3) { | 1529 | if (net_debug > 3) { |
1529 | printk("%s: sent %d byte packet of type %x\n", | 1530 | printk("%s: sent %d byte packet of type %x\n", |
@@ -1535,7 +1536,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
1535 | ask the chip to start transmitting before the | 1536 | ask the chip to start transmitting before the |
1536 | whole packet has been completely uploaded. */ | 1537 | whole packet has been completely uploaded. */ |
1537 | 1538 | ||
1538 | spin_lock_irq(&lp->lock); | 1539 | spin_lock_irqsave(&lp->lock, flags); |
1539 | netif_stop_queue(dev); | 1540 | netif_stop_queue(dev); |
1540 | 1541 | ||
1541 | /* initiate a transmit sequence */ | 1542 | /* initiate a transmit sequence */ |
@@ -1549,13 +1550,13 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
1549 | * we're waiting for TxOk, so return 1 and requeue this packet. | 1550 | * we're waiting for TxOk, so return 1 and requeue this packet. |
1550 | */ | 1551 | */ |
1551 | 1552 | ||
1552 | spin_unlock_irq(&lp->lock); | 1553 | spin_unlock_irqrestore(&lp->lock, flags); |
1553 | if (net_debug) printk("cs89x0: Tx buffer not free!\n"); | 1554 | if (net_debug) printk("cs89x0: Tx buffer not free!\n"); |
1554 | return NETDEV_TX_BUSY; | 1555 | return NETDEV_TX_BUSY; |
1555 | } | 1556 | } |
1556 | /* Write the contents of the packet */ | 1557 | /* Write the contents of the packet */ |
1557 | writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); | 1558 | writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); |
1558 | spin_unlock_irq(&lp->lock); | 1559 | spin_unlock_irqrestore(&lp->lock, flags); |
1559 | lp->stats.tx_bytes += skb->len; | 1560 | lp->stats.tx_bytes += skb->len; |
1560 | dev->trans_start = jiffies; | 1561 | dev->trans_start = jiffies; |
1561 | dev_kfree_skb (skb); | 1562 | dev_kfree_skb (skb); |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index efa680f4b8dd..41b648a67fec 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -1897,6 +1897,9 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
1897 | 1897 | ||
1898 | if (ioread8(&nic->csr->scb.status) & rus_no_res) | 1898 | if (ioread8(&nic->csr->scb.status) & rus_no_res) |
1899 | nic->ru_running = RU_SUSPENDED; | 1899 | nic->ru_running = RU_SUSPENDED; |
1900 | pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, | ||
1901 | sizeof(struct rfd), | ||
1902 | PCI_DMA_BIDIRECTIONAL); | ||
1900 | return -ENODATA; | 1903 | return -ENODATA; |
1901 | } | 1904 | } |
1902 | 1905 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 147c4b088fb3..e8d46cc1bec2 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -3080,7 +3080,9 @@ static const struct net_device_ops ehea_netdev_ops = { | |||
3080 | .ndo_poll_controller = ehea_netpoll, | 3080 | .ndo_poll_controller = ehea_netpoll, |
3081 | #endif | 3081 | #endif |
3082 | .ndo_get_stats = ehea_get_stats, | 3082 | .ndo_get_stats = ehea_get_stats, |
3083 | .ndo_change_mtu = eth_change_mtu, | ||
3083 | .ndo_set_mac_address = ehea_set_mac_addr, | 3084 | .ndo_set_mac_address = ehea_set_mac_addr, |
3085 | .ndo_validate_addr = eth_validate_addr, | ||
3084 | .ndo_set_multicast_list = ehea_set_multicast_list, | 3086 | .ndo_set_multicast_list = ehea_set_multicast_list, |
3085 | .ndo_change_mtu = ehea_change_mtu, | 3087 | .ndo_change_mtu = ehea_change_mtu, |
3086 | .ndo_vlan_rx_register = ehea_vlan_rx_register, | 3088 | .ndo_vlan_rx_register = ehea_vlan_rx_register, |
diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 0f19b743749b..d4b98074b1b7 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c | |||
@@ -1642,6 +1642,7 @@ static const struct net_device_ops fec_netdev_ops = { | |||
1642 | .ndo_stop = fec_enet_close, | 1642 | .ndo_stop = fec_enet_close, |
1643 | .ndo_start_xmit = fec_enet_start_xmit, | 1643 | .ndo_start_xmit = fec_enet_start_xmit, |
1644 | .ndo_set_multicast_list = set_multicast_list, | 1644 | .ndo_set_multicast_list = set_multicast_list, |
1645 | .ndo_change_mtu = eth_change_mtu, | ||
1645 | .ndo_validate_addr = eth_validate_addr, | 1646 | .ndo_validate_addr = eth_validate_addr, |
1646 | .ndo_tx_timeout = fec_timeout, | 1647 | .ndo_tx_timeout = fec_timeout, |
1647 | .ndo_set_mac_address = fec_set_mac_address, | 1648 | .ndo_set_mac_address = fec_set_mac_address, |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 4ae1d259fced..43d813ed9f45 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -156,6 +156,8 @@ static const struct net_device_ops gfar_netdev_ops = { | |||
156 | .ndo_tx_timeout = gfar_timeout, | 156 | .ndo_tx_timeout = gfar_timeout, |
157 | .ndo_do_ioctl = gfar_ioctl, | 157 | .ndo_do_ioctl = gfar_ioctl, |
158 | .ndo_vlan_rx_register = gfar_vlan_rx_register, | 158 | .ndo_vlan_rx_register = gfar_vlan_rx_register, |
159 | .ndo_set_mac_address = eth_mac_addr, | ||
160 | .ndo_validate_addr = eth_validate_addr, | ||
159 | #ifdef CONFIG_NET_POLL_CONTROLLER | 161 | #ifdef CONFIG_NET_POLL_CONTROLLER |
160 | .ndo_poll_controller = gfar_netpoll, | 162 | .ndo_poll_controller = gfar_netpoll, |
161 | #endif | 163 | #endif |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 155160052c8b..981ab530e9ac 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * devices like TTY. It interfaces between a raw TTY and the | 3 | * devices like TTY. It interfaces between a raw TTY and the |
4 | * kernel's AX.25 protocol layers. | 4 | * kernel's AX.25 protocol layers. |
5 | * | 5 | * |
6 | * Authors: Andreas Könsgen <ajk@iehk.rwth-aachen.de> | 6 | * Authors: Andreas Könsgen <ajk@comnets.uni-bremen.de> |
7 | * Ralf Baechle DL5RB <ralf@linux-mips.org> | 7 | * Ralf Baechle DL5RB <ralf@linux-mips.org> |
8 | * | 8 | * |
9 | * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by | 9 | * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by |
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c index 1d5379de6900..8d76cb89dbd6 100644 --- a/drivers/net/ibm_newemac/rgmii.c +++ b/drivers/net/ibm_newemac/rgmii.c | |||
@@ -188,11 +188,12 @@ void rgmii_put_mdio(struct of_device *ofdev, int input) | |||
188 | void rgmii_detach(struct of_device *ofdev, int input) | 188 | void rgmii_detach(struct of_device *ofdev, int input) |
189 | { | 189 | { |
190 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | 190 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); |
191 | struct rgmii_regs __iomem *p = dev->base; | 191 | struct rgmii_regs __iomem *p; |
192 | |||
193 | mutex_lock(&dev->lock); | ||
194 | 192 | ||
195 | BUG_ON(!dev || dev->users == 0); | 193 | BUG_ON(!dev || dev->users == 0); |
194 | p = dev->base; | ||
195 | |||
196 | mutex_lock(&dev->lock); | ||
196 | 197 | ||
197 | RGMII_DBG(dev, "detach(%d)" NL, input); | 198 | RGMII_DBG(dev, "detach(%d)" NL, input); |
198 | 199 | ||
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index be480292aba1..adb09d32625d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -127,14 +127,48 @@ static void igb_restore_vlan(struct igb_adapter *); | |||
127 | static void igb_ping_all_vfs(struct igb_adapter *); | 127 | static void igb_ping_all_vfs(struct igb_adapter *); |
128 | static void igb_msg_task(struct igb_adapter *); | 128 | static void igb_msg_task(struct igb_adapter *); |
129 | static int igb_rcv_msg_from_vf(struct igb_adapter *, u32); | 129 | static int igb_rcv_msg_from_vf(struct igb_adapter *, u32); |
130 | static inline void igb_set_rah_pool(struct e1000_hw *, int , int); | ||
131 | static void igb_set_mc_list_pools(struct igb_adapter *, int, u16); | 130 | static void igb_set_mc_list_pools(struct igb_adapter *, int, u16); |
132 | static void igb_vmm_control(struct igb_adapter *); | 131 | static void igb_vmm_control(struct igb_adapter *); |
133 | static inline void igb_set_vmolr(struct e1000_hw *, int); | ||
134 | static inline int igb_set_vf_rlpml(struct igb_adapter *, int, int); | ||
135 | static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); | 132 | static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); |
136 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); | 133 | static void igb_restore_vf_multicasts(struct igb_adapter *adapter); |
137 | 134 | ||
135 | static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn) | ||
136 | { | ||
137 | u32 reg_data; | ||
138 | |||
139 | reg_data = rd32(E1000_VMOLR(vfn)); | ||
140 | reg_data |= E1000_VMOLR_BAM | /* Accept broadcast */ | ||
141 | E1000_VMOLR_ROPE | /* Accept packets matched in UTA */ | ||
142 | E1000_VMOLR_ROMPE | /* Accept packets matched in MTA */ | ||
143 | E1000_VMOLR_AUPE | /* Accept untagged packets */ | ||
144 | E1000_VMOLR_STRVLAN; /* Strip vlan tags */ | ||
145 | wr32(E1000_VMOLR(vfn), reg_data); | ||
146 | } | ||
147 | |||
148 | static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size, | ||
149 | int vfn) | ||
150 | { | ||
151 | struct e1000_hw *hw = &adapter->hw; | ||
152 | u32 vmolr; | ||
153 | |||
154 | vmolr = rd32(E1000_VMOLR(vfn)); | ||
155 | vmolr &= ~E1000_VMOLR_RLPML_MASK; | ||
156 | vmolr |= size | E1000_VMOLR_LPE; | ||
157 | wr32(E1000_VMOLR(vfn), vmolr); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry) | ||
163 | { | ||
164 | u32 reg_data; | ||
165 | |||
166 | reg_data = rd32(E1000_RAH(entry)); | ||
167 | reg_data &= ~E1000_RAH_POOL_MASK; | ||
168 | reg_data |= E1000_RAH_POOL_1 << pool;; | ||
169 | wr32(E1000_RAH(entry), reg_data); | ||
170 | } | ||
171 | |||
138 | #ifdef CONFIG_PM | 172 | #ifdef CONFIG_PM |
139 | static int igb_suspend(struct pci_dev *, pm_message_t); | 173 | static int igb_suspend(struct pci_dev *, pm_message_t); |
140 | static int igb_resume(struct pci_dev *); | 174 | static int igb_resume(struct pci_dev *); |
@@ -5418,43 +5452,6 @@ static void igb_io_resume(struct pci_dev *pdev) | |||
5418 | igb_get_hw_control(adapter); | 5452 | igb_get_hw_control(adapter); |
5419 | } | 5453 | } |
5420 | 5454 | ||
5421 | static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn) | ||
5422 | { | ||
5423 | u32 reg_data; | ||
5424 | |||
5425 | reg_data = rd32(E1000_VMOLR(vfn)); | ||
5426 | reg_data |= E1000_VMOLR_BAM | /* Accept broadcast */ | ||
5427 | E1000_VMOLR_ROPE | /* Accept packets matched in UTA */ | ||
5428 | E1000_VMOLR_ROMPE | /* Accept packets matched in MTA */ | ||
5429 | E1000_VMOLR_AUPE | /* Accept untagged packets */ | ||
5430 | E1000_VMOLR_STRVLAN; /* Strip vlan tags */ | ||
5431 | wr32(E1000_VMOLR(vfn), reg_data); | ||
5432 | } | ||
5433 | |||
5434 | static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size, | ||
5435 | int vfn) | ||
5436 | { | ||
5437 | struct e1000_hw *hw = &adapter->hw; | ||
5438 | u32 vmolr; | ||
5439 | |||
5440 | vmolr = rd32(E1000_VMOLR(vfn)); | ||
5441 | vmolr &= ~E1000_VMOLR_RLPML_MASK; | ||
5442 | vmolr |= size | E1000_VMOLR_LPE; | ||
5443 | wr32(E1000_VMOLR(vfn), vmolr); | ||
5444 | |||
5445 | return 0; | ||
5446 | } | ||
5447 | |||
5448 | static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry) | ||
5449 | { | ||
5450 | u32 reg_data; | ||
5451 | |||
5452 | reg_data = rd32(E1000_RAH(entry)); | ||
5453 | reg_data &= ~E1000_RAH_POOL_MASK; | ||
5454 | reg_data |= E1000_RAH_POOL_1 << pool;; | ||
5455 | wr32(E1000_RAH(entry), reg_data); | ||
5456 | } | ||
5457 | |||
5458 | static void igb_set_mc_list_pools(struct igb_adapter *adapter, | 5455 | static void igb_set_mc_list_pools(struct igb_adapter *adapter, |
5459 | int entry_count, u16 total_rar_filters) | 5456 | int entry_count, u16 total_rar_filters) |
5460 | { | 5457 | { |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index d53aa9582137..20f9bc626688 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
34 | #include <linux/smp_lock.h> | ||
35 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
36 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
37 | 36 | ||
diff --git a/drivers/net/isa-skeleton.c b/drivers/net/isa-skeleton.c index 73585fd8f29f..d12377b84358 100644 --- a/drivers/net/isa-skeleton.c +++ b/drivers/net/isa-skeleton.c | |||
@@ -430,7 +430,8 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
430 | * hardware interrupt handler. Queue flow control is | 430 | * hardware interrupt handler. Queue flow control is |
431 | * thus managed under this lock as well. | 431 | * thus managed under this lock as well. |
432 | */ | 432 | */ |
433 | spin_lock_irq(&np->lock); | 433 | unsigned long flags; |
434 | spin_lock_irqsave(&np->lock, flags); | ||
434 | 435 | ||
435 | add_to_tx_ring(np, skb, length); | 436 | add_to_tx_ring(np, skb, length); |
436 | dev->trans_start = jiffies; | 437 | dev->trans_start = jiffies; |
@@ -446,7 +447,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
446 | * is when the transmit statistics are updated. | 447 | * is when the transmit statistics are updated. |
447 | */ | 448 | */ |
448 | 449 | ||
449 | spin_unlock_irq(&np->lock); | 450 | spin_unlock_irqrestore(&np->lock, flags); |
450 | #else | 451 | #else |
451 | /* This is the case for older hardware which takes | 452 | /* This is the case for older hardware which takes |
452 | * a single transmit buffer at a time, and it is | 453 | * a single transmit buffer at a time, and it is |
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 7c5978ad929a..da2c8514b8d0 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -106,8 +106,6 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) | |||
106 | { | 106 | { |
107 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 107 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
108 | 108 | ||
109 | DPRINTK(DRV, INFO, "Get DCB Admin Mode.\n"); | ||
110 | |||
111 | return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); | 109 | return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); |
112 | } | 110 | } |
113 | 111 | ||
@@ -116,8 +114,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) | |||
116 | u8 err = 0; | 114 | u8 err = 0; |
117 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 115 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
118 | 116 | ||
119 | DPRINTK(DRV, INFO, "Set DCB Admin Mode.\n"); | ||
120 | |||
121 | if (state > 0) { | 117 | if (state > 0) { |
122 | /* Turn on DCB */ | 118 | /* Turn on DCB */ |
123 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) | 119 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) |
@@ -175,6 +171,8 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, | |||
175 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 171 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
176 | int i, j; | 172 | int i, j; |
177 | 173 | ||
174 | memset(perm_addr, 0xff, MAX_ADDR_LEN); | ||
175 | |||
178 | for (i = 0; i < netdev->addr_len; i++) | 176 | for (i = 0; i < netdev->addr_len; i++) |
179 | perm_addr[i] = adapter->hw.mac.perm_addr[i]; | 177 | perm_addr[i] = adapter->hw.mac.perm_addr[i]; |
180 | 178 | ||
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index d12106b47bf2..2f286091394d 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c | |||
@@ -229,6 +229,7 @@ static int __init jazz_sonic_probe(struct platform_device *pdev) | |||
229 | lp = netdev_priv(dev); | 229 | lp = netdev_priv(dev); |
230 | lp->device = &pdev->dev; | 230 | lp->device = &pdev->dev; |
231 | SET_NETDEV_DEV(dev, &pdev->dev); | 231 | SET_NETDEV_DEV(dev, &pdev->dev); |
232 | platform_set_drvdata(pdev, dev); | ||
232 | 233 | ||
233 | netdev_boot_setup_check(dev); | 234 | netdev_boot_setup_check(dev); |
234 | 235 | ||
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c new file mode 100644 index 000000000000..9a1dea60c1c4 --- /dev/null +++ b/drivers/net/ks8851.c | |||
@@ -0,0 +1,1322 @@ | |||
1 | /* drivers/net/ks8651.c | ||
2 | * | ||
3 | * Copyright 2009 Simtec Electronics | ||
4 | * http://www.simtec.co.uk/ | ||
5 | * Ben Dooks <ben@simtec.co.uk> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #define DEBUG | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/netdevice.h> | ||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/ethtool.h> | ||
19 | #include <linux/cache.h> | ||
20 | #include <linux/crc32.h> | ||
21 | #include <linux/mii.h> | ||
22 | |||
23 | #include <linux/spi/spi.h> | ||
24 | |||
25 | #include "ks8851.h" | ||
26 | |||
27 | /** | ||
28 | * struct ks8851_rxctrl - KS8851 driver rx control | ||
29 | * @mchash: Multicast hash-table data. | ||
30 | * @rxcr1: KS_RXCR1 register setting | ||
31 | * @rxcr2: KS_RXCR2 register setting | ||
32 | * | ||
33 | * Representation of the settings needs to control the receive filtering | ||
34 | * such as the multicast hash-filter and the receive register settings. This | ||
35 | * is used to make the job of working out if the receive settings change and | ||
36 | * then issuing the new settings to the worker that will send the necessary | ||
37 | * commands. | ||
38 | */ | ||
39 | struct ks8851_rxctrl { | ||
40 | u16 mchash[4]; | ||
41 | u16 rxcr1; | ||
42 | u16 rxcr2; | ||
43 | }; | ||
44 | |||
45 | /** | ||
46 | * union ks8851_tx_hdr - tx header data | ||
47 | * @txb: The header as bytes | ||
48 | * @txw: The header as 16bit, little-endian words | ||
49 | * | ||
50 | * A dual representation of the tx header data to allow | ||
51 | * access to individual bytes, and to allow 16bit accesses | ||
52 | * with 16bit alignment. | ||
53 | */ | ||
54 | union ks8851_tx_hdr { | ||
55 | u8 txb[6]; | ||
56 | __le16 txw[3]; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * struct ks8851_net - KS8851 driver private data | ||
61 | * @netdev: The network device we're bound to | ||
62 | * @spidev: The spi device we're bound to. | ||
63 | * @lock: Lock to ensure that the device is not accessed when busy. | ||
64 | * @statelock: Lock on this structure for tx list. | ||
65 | * @mii: The MII state information for the mii calls. | ||
66 | * @rxctrl: RX settings for @rxctrl_work. | ||
67 | * @tx_work: Work queue for tx packets | ||
68 | * @irq_work: Work queue for servicing interrupts | ||
69 | * @rxctrl_work: Work queue for updating RX mode and multicast lists | ||
70 | * @txq: Queue of packets for transmission. | ||
71 | * @spi_msg1: pre-setup SPI transfer with one message, @spi_xfer1. | ||
72 | * @spi_msg2: pre-setup SPI transfer with two messages, @spi_xfer2. | ||
73 | * @txh: Space for generating packet TX header in DMA-able data | ||
74 | * @rxd: Space for receiving SPI data, in DMA-able space. | ||
75 | * @txd: Space for transmitting SPI data, in DMA-able space. | ||
76 | * @msg_enable: The message flags controlling driver output (see ethtool). | ||
77 | * @fid: Incrementing frame id tag. | ||
78 | * @rc_ier: Cached copy of KS_IER. | ||
79 | * @rc_rxqcr: Cached copy of KS_RXQCR. | ||
80 | * | ||
81 | * The @lock ensures that the chip is protected when certain operations are | ||
82 | * in progress. When the read or write packet transfer is in progress, most | ||
83 | * of the chip registers are not ccessible until the transfer is finished and | ||
84 | * the DMA has been de-asserted. | ||
85 | * | ||
86 | * The @statelock is used to protect information in the structure which may | ||
87 | * need to be accessed via several sources, such as the network driver layer | ||
88 | * or one of the work queues. | ||
89 | * | ||
90 | * We align the buffers we may use for rx/tx to ensure that if the SPI driver | ||
91 | * wants to DMA map them, it will not have any problems with data the driver | ||
92 | * modifies. | ||
93 | */ | ||
94 | struct ks8851_net { | ||
95 | struct net_device *netdev; | ||
96 | struct spi_device *spidev; | ||
97 | struct mutex lock; | ||
98 | spinlock_t statelock; | ||
99 | |||
100 | union ks8851_tx_hdr txh ____cacheline_aligned; | ||
101 | u8 rxd[8]; | ||
102 | u8 txd[8]; | ||
103 | |||
104 | u32 msg_enable ____cacheline_aligned; | ||
105 | u16 tx_space; | ||
106 | u8 fid; | ||
107 | |||
108 | u16 rc_ier; | ||
109 | u16 rc_rxqcr; | ||
110 | |||
111 | struct mii_if_info mii; | ||
112 | struct ks8851_rxctrl rxctrl; | ||
113 | |||
114 | struct work_struct tx_work; | ||
115 | struct work_struct irq_work; | ||
116 | struct work_struct rxctrl_work; | ||
117 | |||
118 | struct sk_buff_head txq; | ||
119 | |||
120 | struct spi_message spi_msg1; | ||
121 | struct spi_message spi_msg2; | ||
122 | struct spi_transfer spi_xfer1; | ||
123 | struct spi_transfer spi_xfer2[2]; | ||
124 | }; | ||
125 | |||
126 | static int msg_enable; | ||
127 | |||
128 | #define ks_info(_ks, _msg...) dev_info(&(_ks)->spidev->dev, _msg) | ||
129 | #define ks_warn(_ks, _msg...) dev_warn(&(_ks)->spidev->dev, _msg) | ||
130 | #define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->spidev->dev, _msg) | ||
131 | #define ks_err(_ks, _msg...) dev_err(&(_ks)->spidev->dev, _msg) | ||
132 | |||
133 | /* shift for byte-enable data */ | ||
134 | #define BYTE_EN(_x) ((_x) << 2) | ||
135 | |||
136 | /* turn register number and byte-enable mask into data for start of packet */ | ||
137 | #define MK_OP(_byteen, _reg) (BYTE_EN(_byteen) | (_reg) << (8+2) | (_reg) >> 6) | ||
138 | |||
139 | /* SPI register read/write calls. | ||
140 | * | ||
141 | * All these calls issue SPI transactions to access the chip's registers. They | ||
142 | * all require that the necessary lock is held to prevent accesses when the | ||
143 | * chip is busy transfering packet data (RX/TX FIFO accesses). | ||
144 | */ | ||
145 | |||
146 | /** | ||
147 | * ks8851_wrreg16 - write 16bit register value to chip | ||
148 | * @ks: The chip state | ||
149 | * @reg: The register address | ||
150 | * @val: The value to write | ||
151 | * | ||
152 | * Issue a write to put the value @val into the register specified in @reg. | ||
153 | */ | ||
154 | static void ks8851_wrreg16(struct ks8851_net *ks, unsigned reg, unsigned val) | ||
155 | { | ||
156 | struct spi_transfer *xfer = &ks->spi_xfer1; | ||
157 | struct spi_message *msg = &ks->spi_msg1; | ||
158 | __le16 txb[2]; | ||
159 | int ret; | ||
160 | |||
161 | txb[0] = cpu_to_le16(MK_OP(reg & 2 ? 0xC : 0x03, reg) | KS_SPIOP_WR); | ||
162 | txb[1] = cpu_to_le16(val); | ||
163 | |||
164 | xfer->tx_buf = txb; | ||
165 | xfer->rx_buf = NULL; | ||
166 | xfer->len = 4; | ||
167 | |||
168 | ret = spi_sync(ks->spidev, msg); | ||
169 | if (ret < 0) | ||
170 | ks_err(ks, "spi_sync() failed\n"); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * ks8851_rx_1msg - select whether to use one or two messages for spi read | ||
175 | * @ks: The device structure | ||
176 | * | ||
177 | * Return whether to generate a single message with a tx and rx buffer | ||
178 | * supplied to spi_sync(), or alternatively send the tx and rx buffers | ||
179 | * as separate messages. | ||
180 | * | ||
181 | * Depending on the hardware in use, a single message may be more efficient | ||
182 | * on interrupts or work done by the driver. | ||
183 | * | ||
184 | * This currently always returns true until we add some per-device data passed | ||
185 | * from the platform code to specify which mode is better. | ||
186 | */ | ||
187 | static inline bool ks8851_rx_1msg(struct ks8851_net *ks) | ||
188 | { | ||
189 | return true; | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * ks8851_rdreg - issue read register command and return the data | ||
194 | * @ks: The device state | ||
195 | * @op: The register address and byte enables in message format. | ||
196 | * @rxb: The RX buffer to return the result into | ||
197 | * @rxl: The length of data expected. | ||
198 | * | ||
199 | * This is the low level read call that issues the necessary spi message(s) | ||
200 | * to read data from the register specified in @op. | ||
201 | */ | ||
202 | static void ks8851_rdreg(struct ks8851_net *ks, unsigned op, | ||
203 | u8 *rxb, unsigned rxl) | ||
204 | { | ||
205 | struct spi_transfer *xfer; | ||
206 | struct spi_message *msg; | ||
207 | __le16 *txb = (__le16 *)ks->txd; | ||
208 | u8 *trx = ks->rxd; | ||
209 | int ret; | ||
210 | |||
211 | txb[0] = cpu_to_le16(op | KS_SPIOP_RD); | ||
212 | |||
213 | if (ks8851_rx_1msg(ks)) { | ||
214 | msg = &ks->spi_msg1; | ||
215 | xfer = &ks->spi_xfer1; | ||
216 | |||
217 | xfer->tx_buf = txb; | ||
218 | xfer->rx_buf = trx; | ||
219 | xfer->len = rxl + 2; | ||
220 | } else { | ||
221 | msg = &ks->spi_msg2; | ||
222 | xfer = ks->spi_xfer2; | ||
223 | |||
224 | xfer->tx_buf = txb; | ||
225 | xfer->rx_buf = NULL; | ||
226 | xfer->len = 2; | ||
227 | |||
228 | xfer++; | ||
229 | xfer->tx_buf = NULL; | ||
230 | xfer->rx_buf = trx; | ||
231 | xfer->len = rxl; | ||
232 | } | ||
233 | |||
234 | ret = spi_sync(ks->spidev, msg); | ||
235 | if (ret < 0) | ||
236 | ks_err(ks, "read: spi_sync() failed\n"); | ||
237 | else if (ks8851_rx_1msg(ks)) | ||
238 | memcpy(rxb, trx + 2, rxl); | ||
239 | else | ||
240 | memcpy(rxb, trx, rxl); | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * ks8851_rdreg8 - read 8 bit register from device | ||
245 | * @ks: The chip information | ||
246 | * @reg: The register address | ||
247 | * | ||
248 | * Read a 8bit register from the chip, returning the result | ||
249 | */ | ||
250 | static unsigned ks8851_rdreg8(struct ks8851_net *ks, unsigned reg) | ||
251 | { | ||
252 | u8 rxb[1]; | ||
253 | |||
254 | ks8851_rdreg(ks, MK_OP(1 << (reg & 3), reg), rxb, 1); | ||
255 | return rxb[0]; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * ks8851_rdreg16 - read 16 bit register from device | ||
260 | * @ks: The chip information | ||
261 | * @reg: The register address | ||
262 | * | ||
263 | * Read a 16bit register from the chip, returning the result | ||
264 | */ | ||
265 | static unsigned ks8851_rdreg16(struct ks8851_net *ks, unsigned reg) | ||
266 | { | ||
267 | __le16 rx = 0; | ||
268 | |||
269 | ks8851_rdreg(ks, MK_OP(reg & 2 ? 0xC : 0x3, reg), (u8 *)&rx, 2); | ||
270 | return le16_to_cpu(rx); | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * ks8851_rdreg32 - read 32 bit register from device | ||
275 | * @ks: The chip information | ||
276 | * @reg: The register address | ||
277 | * | ||
278 | * Read a 32bit register from the chip. | ||
279 | * | ||
280 | * Note, this read requires the address be aligned to 4 bytes. | ||
281 | */ | ||
282 | static unsigned ks8851_rdreg32(struct ks8851_net *ks, unsigned reg) | ||
283 | { | ||
284 | __le32 rx = 0; | ||
285 | |||
286 | WARN_ON(reg & 3); | ||
287 | |||
288 | ks8851_rdreg(ks, MK_OP(0xf, reg), (u8 *)&rx, 4); | ||
289 | return le32_to_cpu(rx); | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * ks8851_soft_reset - issue one of the soft reset to the device | ||
294 | * @ks: The device state. | ||
295 | * @op: The bit(s) to set in the GRR | ||
296 | * | ||
297 | * Issue the relevant soft-reset command to the device's GRR register | ||
298 | * specified by @op. | ||
299 | * | ||
300 | * Note, the delays are in there as a caution to ensure that the reset | ||
301 | * has time to take effect and then complete. Since the datasheet does | ||
302 | * not currently specify the exact sequence, we have chosen something | ||
303 | * that seems to work with our device. | ||
304 | */ | ||
305 | static void ks8851_soft_reset(struct ks8851_net *ks, unsigned op) | ||
306 | { | ||
307 | ks8851_wrreg16(ks, KS_GRR, op); | ||
308 | mdelay(1); /* wait a short time to effect reset */ | ||
309 | ks8851_wrreg16(ks, KS_GRR, 0); | ||
310 | mdelay(1); /* wait for condition to clear */ | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * ks8851_write_mac_addr - write mac address to device registers | ||
315 | * @dev: The network device | ||
316 | * | ||
317 | * Update the KS8851 MAC address registers from the address in @dev. | ||
318 | * | ||
319 | * This call assumes that the chip is not running, so there is no need to | ||
320 | * shutdown the RXQ process whilst setting this. | ||
321 | */ | ||
322 | static int ks8851_write_mac_addr(struct net_device *dev) | ||
323 | { | ||
324 | struct ks8851_net *ks = netdev_priv(dev); | ||
325 | u16 *mcp = (u16 *)dev->dev_addr; | ||
326 | |||
327 | mutex_lock(&ks->lock); | ||
328 | |||
329 | ks8851_wrreg16(ks, KS_MARL, mcp[0]); | ||
330 | ks8851_wrreg16(ks, KS_MARM, mcp[1]); | ||
331 | ks8851_wrreg16(ks, KS_MARH, mcp[2]); | ||
332 | |||
333 | mutex_unlock(&ks->lock); | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | /** | ||
339 | * ks8851_init_mac - initialise the mac address | ||
340 | * @ks: The device structure | ||
341 | * | ||
342 | * Get or create the initial mac address for the device and then set that | ||
343 | * into the station address register. Currently we assume that the device | ||
344 | * does not have a valid mac address in it, and so we use random_ether_addr() | ||
345 | * to create a new one. | ||
346 | * | ||
347 | * In future, the driver should check to see if the device has an EEPROM | ||
348 | * attached and whether that has a valid ethernet address in it. | ||
349 | */ | ||
350 | static void ks8851_init_mac(struct ks8851_net *ks) | ||
351 | { | ||
352 | struct net_device *dev = ks->netdev; | ||
353 | |||
354 | random_ether_addr(dev->dev_addr); | ||
355 | ks8851_write_mac_addr(dev); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * ks8851_irq - device interrupt handler | ||
360 | * @irq: Interrupt number passed from the IRQ hnalder. | ||
361 | * @pw: The private word passed to register_irq(), our struct ks8851_net. | ||
362 | * | ||
363 | * Disable the interrupt from happening again until we've processed the | ||
364 | * current status by scheduling ks8851_irq_work(). | ||
365 | */ | ||
366 | static irqreturn_t ks8851_irq(int irq, void *pw) | ||
367 | { | ||
368 | struct ks8851_net *ks = pw; | ||
369 | |||
370 | disable_irq_nosync(irq); | ||
371 | schedule_work(&ks->irq_work); | ||
372 | return IRQ_HANDLED; | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * ks8851_rdfifo - read data from the receive fifo | ||
377 | * @ks: The device state. | ||
378 | * @buff: The buffer address | ||
379 | * @len: The length of the data to read | ||
380 | * | ||
381 | * Issue an RXQ FIFO read command and read the @len ammount of data from | ||
382 | * the FIFO into the buffer specified by @buff. | ||
383 | */ | ||
384 | static void ks8851_rdfifo(struct ks8851_net *ks, u8 *buff, unsigned len) | ||
385 | { | ||
386 | struct spi_transfer *xfer = ks->spi_xfer2; | ||
387 | struct spi_message *msg = &ks->spi_msg2; | ||
388 | u8 txb[1]; | ||
389 | int ret; | ||
390 | |||
391 | if (netif_msg_rx_status(ks)) | ||
392 | ks_dbg(ks, "%s: %d@%p\n", __func__, len, buff); | ||
393 | |||
394 | /* set the operation we're issuing */ | ||
395 | txb[0] = KS_SPIOP_RXFIFO; | ||
396 | |||
397 | xfer->tx_buf = txb; | ||
398 | xfer->rx_buf = NULL; | ||
399 | xfer->len = 1; | ||
400 | |||
401 | xfer++; | ||
402 | xfer->rx_buf = buff; | ||
403 | xfer->tx_buf = NULL; | ||
404 | xfer->len = len; | ||
405 | |||
406 | ret = spi_sync(ks->spidev, msg); | ||
407 | if (ret < 0) | ||
408 | ks_err(ks, "%s: spi_sync() failed\n", __func__); | ||
409 | } | ||
410 | |||
411 | /** | ||
412 | * ks8851_dbg_dumpkkt - dump initial packet contents to debug | ||
413 | * @ks: The device state | ||
414 | * @rxpkt: The data for the received packet | ||
415 | * | ||
416 | * Dump the initial data from the packet to dev_dbg(). | ||
417 | */ | ||
418 | static void ks8851_dbg_dumpkkt(struct ks8851_net *ks, u8 *rxpkt) | ||
419 | { | ||
420 | ks_dbg(ks, "pkt %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", | ||
421 | rxpkt[4], rxpkt[5], rxpkt[6], rxpkt[7], | ||
422 | rxpkt[8], rxpkt[9], rxpkt[10], rxpkt[11], | ||
423 | rxpkt[12], rxpkt[13], rxpkt[14], rxpkt[15]); | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * ks8851_rx_pkts - receive packets from the host | ||
428 | * @ks: The device information. | ||
429 | * | ||
430 | * This is called from the IRQ work queue when the system detects that there | ||
431 | * are packets in the receive queue. Find out how many packets there are and | ||
432 | * read them from the FIFO. | ||
433 | */ | ||
434 | static void ks8851_rx_pkts(struct ks8851_net *ks) | ||
435 | { | ||
436 | struct sk_buff *skb; | ||
437 | unsigned rxfc; | ||
438 | unsigned rxlen; | ||
439 | unsigned rxstat; | ||
440 | u32 rxh; | ||
441 | u8 *rxpkt; | ||
442 | |||
443 | rxfc = ks8851_rdreg8(ks, KS_RXFC); | ||
444 | |||
445 | if (netif_msg_rx_status(ks)) | ||
446 | ks_dbg(ks, "%s: %d packets\n", __func__, rxfc); | ||
447 | |||
448 | /* Currently we're issuing a read per packet, but we could possibly | ||
449 | * improve the code by issuing a single read, getting the receive | ||
450 | * header, allocating the packet and then reading the packet data | ||
451 | * out in one go. | ||
452 | * | ||
453 | * This form of operation would require us to hold the SPI bus' | ||
454 | * chipselect low during the entie transaction to avoid any | ||
455 | * reset to the data stream comming from the chip. | ||
456 | */ | ||
457 | |||
458 | for (; rxfc != 0; rxfc--) { | ||
459 | rxh = ks8851_rdreg32(ks, KS_RXFHSR); | ||
460 | rxstat = rxh & 0xffff; | ||
461 | rxlen = rxh >> 16; | ||
462 | |||
463 | if (netif_msg_rx_status(ks)) | ||
464 | ks_dbg(ks, "rx: stat 0x%04x, len 0x%04x\n", | ||
465 | rxstat, rxlen); | ||
466 | |||
467 | /* the length of the packet includes the 32bit CRC */ | ||
468 | |||
469 | /* set dma read address */ | ||
470 | ks8851_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI | 0x00); | ||
471 | |||
472 | /* start the packet dma process, and set auto-dequeue rx */ | ||
473 | ks8851_wrreg16(ks, KS_RXQCR, | ||
474 | ks->rc_rxqcr | RXQCR_SDA | RXQCR_ADRFE); | ||
475 | |||
476 | if (rxlen > 0) { | ||
477 | skb = netdev_alloc_skb(ks->netdev, rxlen + 2 + 8); | ||
478 | if (!skb) { | ||
479 | /* todo - dump frame and move on */ | ||
480 | } | ||
481 | |||
482 | /* two bytes to ensure ip is aligned, and four bytes | ||
483 | * for the status header and 4 bytes of garbage */ | ||
484 | skb_reserve(skb, 2 + 4 + 4); | ||
485 | |||
486 | rxpkt = skb_put(skb, rxlen - 4) - 8; | ||
487 | |||
488 | /* align the packet length to 4 bytes, and add 4 bytes | ||
489 | * as we're getting the rx status header as well */ | ||
490 | ks8851_rdfifo(ks, rxpkt, ALIGN(rxlen, 4) + 8); | ||
491 | |||
492 | if (netif_msg_pktdata(ks)) | ||
493 | ks8851_dbg_dumpkkt(ks, rxpkt); | ||
494 | |||
495 | skb->protocol = eth_type_trans(skb, ks->netdev); | ||
496 | netif_rx(skb); | ||
497 | |||
498 | ks->netdev->stats.rx_packets++; | ||
499 | ks->netdev->stats.rx_bytes += rxlen - 4; | ||
500 | } | ||
501 | |||
502 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
503 | } | ||
504 | } | ||
505 | |||
506 | /** | ||
507 | * ks8851_irq_work - work queue handler for dealing with interrupt requests | ||
508 | * @work: The work structure that was scheduled by schedule_work() | ||
509 | * | ||
510 | * This is the handler invoked when the ks8851_irq() is called to find out | ||
511 | * what happened, as we cannot allow ourselves to sleep whilst waiting for | ||
512 | * anything other process has the chip's lock. | ||
513 | * | ||
514 | * Read the interrupt status, work out what needs to be done and then clear | ||
515 | * any of the interrupts that are not needed. | ||
516 | */ | ||
517 | static void ks8851_irq_work(struct work_struct *work) | ||
518 | { | ||
519 | struct ks8851_net *ks = container_of(work, struct ks8851_net, irq_work); | ||
520 | unsigned status; | ||
521 | unsigned handled = 0; | ||
522 | |||
523 | mutex_lock(&ks->lock); | ||
524 | |||
525 | status = ks8851_rdreg16(ks, KS_ISR); | ||
526 | |||
527 | if (netif_msg_intr(ks)) | ||
528 | dev_dbg(&ks->spidev->dev, "%s: status 0x%04x\n", | ||
529 | __func__, status); | ||
530 | |||
531 | if (status & IRQ_LCI) { | ||
532 | /* should do something about checking link status */ | ||
533 | handled |= IRQ_LCI; | ||
534 | } | ||
535 | |||
536 | if (status & IRQ_LDI) { | ||
537 | u16 pmecr = ks8851_rdreg16(ks, KS_PMECR); | ||
538 | pmecr &= ~PMECR_WKEVT_MASK; | ||
539 | ks8851_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK); | ||
540 | |||
541 | handled |= IRQ_LDI; | ||
542 | } | ||
543 | |||
544 | if (status & IRQ_RXPSI) | ||
545 | handled |= IRQ_RXPSI; | ||
546 | |||
547 | if (status & IRQ_TXI) { | ||
548 | handled |= IRQ_TXI; | ||
549 | |||
550 | /* no lock here, tx queue should have been stopped */ | ||
551 | |||
552 | /* update our idea of how much tx space is available to the | ||
553 | * system */ | ||
554 | ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR); | ||
555 | |||
556 | if (netif_msg_intr(ks)) | ||
557 | ks_dbg(ks, "%s: txspace %d\n", __func__, ks->tx_space); | ||
558 | } | ||
559 | |||
560 | if (status & IRQ_RXI) | ||
561 | handled |= IRQ_RXI; | ||
562 | |||
563 | if (status & IRQ_SPIBEI) { | ||
564 | dev_err(&ks->spidev->dev, "%s: spi bus error\n", __func__); | ||
565 | handled |= IRQ_SPIBEI; | ||
566 | } | ||
567 | |||
568 | ks8851_wrreg16(ks, KS_ISR, handled); | ||
569 | |||
570 | if (status & IRQ_RXI) { | ||
571 | /* the datasheet says to disable the rx interrupt during | ||
572 | * packet read-out, however we're masking the interrupt | ||
573 | * from the device so do not bother masking just the RX | ||
574 | * from the device. */ | ||
575 | |||
576 | ks8851_rx_pkts(ks); | ||
577 | } | ||
578 | |||
579 | /* if something stopped the rx process, probably due to wanting | ||
580 | * to change the rx settings, then do something about restarting | ||
581 | * it. */ | ||
582 | if (status & IRQ_RXPSI) { | ||
583 | struct ks8851_rxctrl *rxc = &ks->rxctrl; | ||
584 | |||
585 | /* update the multicast hash table */ | ||
586 | ks8851_wrreg16(ks, KS_MAHTR0, rxc->mchash[0]); | ||
587 | ks8851_wrreg16(ks, KS_MAHTR1, rxc->mchash[1]); | ||
588 | ks8851_wrreg16(ks, KS_MAHTR2, rxc->mchash[2]); | ||
589 | ks8851_wrreg16(ks, KS_MAHTR3, rxc->mchash[3]); | ||
590 | |||
591 | ks8851_wrreg16(ks, KS_RXCR2, rxc->rxcr2); | ||
592 | ks8851_wrreg16(ks, KS_RXCR1, rxc->rxcr1); | ||
593 | } | ||
594 | |||
595 | mutex_unlock(&ks->lock); | ||
596 | |||
597 | if (status & IRQ_TXI) | ||
598 | netif_wake_queue(ks->netdev); | ||
599 | |||
600 | enable_irq(ks->netdev->irq); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * calc_txlen - calculate size of message to send packet | ||
605 | * @len: Lenght of data | ||
606 | * | ||
607 | * Returns the size of the TXFIFO message needed to send | ||
608 | * this packet. | ||
609 | */ | ||
610 | static inline unsigned calc_txlen(unsigned len) | ||
611 | { | ||
612 | return ALIGN(len + 4, 4); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * ks8851_wrpkt - write packet to TX FIFO | ||
617 | * @ks: The device state. | ||
618 | * @txp: The sk_buff to transmit. | ||
619 | * @irq: IRQ on completion of the packet. | ||
620 | * | ||
621 | * Send the @txp to the chip. This means creating the relevant packet header | ||
622 | * specifying the length of the packet and the other information the chip | ||
623 | * needs, such as IRQ on completion. Send the header and the packet data to | ||
624 | * the device. | ||
625 | */ | ||
626 | static void ks8851_wrpkt(struct ks8851_net *ks, struct sk_buff *txp, bool irq) | ||
627 | { | ||
628 | struct spi_transfer *xfer = ks->spi_xfer2; | ||
629 | struct spi_message *msg = &ks->spi_msg2; | ||
630 | unsigned fid = 0; | ||
631 | int ret; | ||
632 | |||
633 | if (netif_msg_tx_queued(ks)) | ||
634 | dev_dbg(&ks->spidev->dev, "%s: skb %p, %d@%p, irq %d\n", | ||
635 | __func__, txp, txp->len, txp->data, irq); | ||
636 | |||
637 | fid = ks->fid++; | ||
638 | fid &= TXFR_TXFID_MASK; | ||
639 | |||
640 | if (irq) | ||
641 | fid |= TXFR_TXIC; /* irq on completion */ | ||
642 | |||
643 | /* start header at txb[1] to align txw entries */ | ||
644 | ks->txh.txb[1] = KS_SPIOP_TXFIFO; | ||
645 | ks->txh.txw[1] = cpu_to_le16(fid); | ||
646 | ks->txh.txw[2] = cpu_to_le16(txp->len); | ||
647 | |||
648 | xfer->tx_buf = &ks->txh.txb[1]; | ||
649 | xfer->rx_buf = NULL; | ||
650 | xfer->len = 5; | ||
651 | |||
652 | xfer++; | ||
653 | xfer->tx_buf = txp->data; | ||
654 | xfer->rx_buf = NULL; | ||
655 | xfer->len = ALIGN(txp->len, 4); | ||
656 | |||
657 | ret = spi_sync(ks->spidev, msg); | ||
658 | if (ret < 0) | ||
659 | ks_err(ks, "%s: spi_sync() failed\n", __func__); | ||
660 | } | ||
661 | |||
662 | /** | ||
663 | * ks8851_done_tx - update and then free skbuff after transmitting | ||
664 | * @ks: The device state | ||
665 | * @txb: The buffer transmitted | ||
666 | */ | ||
667 | static void ks8851_done_tx(struct ks8851_net *ks, struct sk_buff *txb) | ||
668 | { | ||
669 | struct net_device *dev = ks->netdev; | ||
670 | |||
671 | dev->stats.tx_bytes += txb->len; | ||
672 | dev->stats.tx_packets++; | ||
673 | |||
674 | dev_kfree_skb(txb); | ||
675 | } | ||
676 | |||
677 | /** | ||
678 | * ks8851_tx_work - process tx packet(s) | ||
679 | * @work: The work strucutre what was scheduled. | ||
680 | * | ||
681 | * This is called when a number of packets have been scheduled for | ||
682 | * transmission and need to be sent to the device. | ||
683 | */ | ||
684 | static void ks8851_tx_work(struct work_struct *work) | ||
685 | { | ||
686 | struct ks8851_net *ks = container_of(work, struct ks8851_net, tx_work); | ||
687 | struct sk_buff *txb; | ||
688 | bool last = false; | ||
689 | |||
690 | mutex_lock(&ks->lock); | ||
691 | |||
692 | while (!last) { | ||
693 | txb = skb_dequeue(&ks->txq); | ||
694 | last = skb_queue_empty(&ks->txq); | ||
695 | |||
696 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); | ||
697 | ks8851_wrpkt(ks, txb, last); | ||
698 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
699 | ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); | ||
700 | |||
701 | ks8851_done_tx(ks, txb); | ||
702 | } | ||
703 | |||
704 | mutex_unlock(&ks->lock); | ||
705 | } | ||
706 | |||
707 | /** | ||
708 | * ks8851_set_powermode - set power mode of the device | ||
709 | * @ks: The device state | ||
710 | * @pwrmode: The power mode value to write to KS_PMECR. | ||
711 | * | ||
712 | * Change the power mode of the chip. | ||
713 | */ | ||
714 | static void ks8851_set_powermode(struct ks8851_net *ks, unsigned pwrmode) | ||
715 | { | ||
716 | unsigned pmecr; | ||
717 | |||
718 | if (netif_msg_hw(ks)) | ||
719 | ks_dbg(ks, "setting power mode %d\n", pwrmode); | ||
720 | |||
721 | pmecr = ks8851_rdreg16(ks, KS_PMECR); | ||
722 | pmecr &= ~PMECR_PM_MASK; | ||
723 | pmecr |= pwrmode; | ||
724 | |||
725 | ks8851_wrreg16(ks, KS_PMECR, pmecr); | ||
726 | } | ||
727 | |||
728 | /** | ||
729 | * ks8851_net_open - open network device | ||
730 | * @dev: The network device being opened. | ||
731 | * | ||
732 | * Called when the network device is marked active, such as a user executing | ||
733 | * 'ifconfig up' on the device. | ||
734 | */ | ||
735 | static int ks8851_net_open(struct net_device *dev) | ||
736 | { | ||
737 | struct ks8851_net *ks = netdev_priv(dev); | ||
738 | |||
739 | /* lock the card, even if we may not actually be doing anything | ||
740 | * else at the moment */ | ||
741 | mutex_lock(&ks->lock); | ||
742 | |||
743 | if (netif_msg_ifup(ks)) | ||
744 | ks_dbg(ks, "opening %s\n", dev->name); | ||
745 | |||
746 | /* bring chip out of any power saving mode it was in */ | ||
747 | ks8851_set_powermode(ks, PMECR_PM_NORMAL); | ||
748 | |||
749 | /* issue a soft reset to the RX/TX QMU to put it into a known | ||
750 | * state. */ | ||
751 | ks8851_soft_reset(ks, GRR_QMU); | ||
752 | |||
753 | /* setup transmission parameters */ | ||
754 | |||
755 | ks8851_wrreg16(ks, KS_TXCR, (TXCR_TXE | /* enable transmit process */ | ||
756 | TXCR_TXPE | /* pad to min length */ | ||
757 | TXCR_TXCRC | /* add CRC */ | ||
758 | TXCR_TXFCE)); /* enable flow control */ | ||
759 | |||
760 | /* auto-increment tx data, reset tx pointer */ | ||
761 | ks8851_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI); | ||
762 | |||
763 | /* setup receiver control */ | ||
764 | |||
765 | ks8851_wrreg16(ks, KS_RXCR1, (RXCR1_RXPAFMA | /* from mac filter */ | ||
766 | RXCR1_RXFCE | /* enable flow control */ | ||
767 | RXCR1_RXBE | /* broadcast enable */ | ||
768 | RXCR1_RXUE | /* unicast enable */ | ||
769 | RXCR1_RXE)); /* enable rx block */ | ||
770 | |||
771 | /* transfer entire frames out in one go */ | ||
772 | ks8851_wrreg16(ks, KS_RXCR2, RXCR2_SRDBL_FRAME); | ||
773 | |||
774 | /* set receive counter timeouts */ | ||
775 | ks8851_wrreg16(ks, KS_RXDTTR, 1000); /* 1ms after first frame to IRQ */ | ||
776 | ks8851_wrreg16(ks, KS_RXDBCTR, 4096); /* >4Kbytes in buffer to IRQ */ | ||
777 | ks8851_wrreg16(ks, KS_RXFCTR, 10); /* 10 frames to IRQ */ | ||
778 | |||
779 | ks->rc_rxqcr = (RXQCR_RXFCTE | /* IRQ on frame count exceeded */ | ||
780 | RXQCR_RXDBCTE | /* IRQ on byte count exceeded */ | ||
781 | RXQCR_RXDTTE); /* IRQ on time exceeded */ | ||
782 | |||
783 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | ||
784 | |||
785 | /* clear then enable interrupts */ | ||
786 | |||
787 | #define STD_IRQ (IRQ_LCI | /* Link Change */ \ | ||
788 | IRQ_TXI | /* TX done */ \ | ||
789 | IRQ_RXI | /* RX done */ \ | ||
790 | IRQ_SPIBEI | /* SPI bus error */ \ | ||
791 | IRQ_TXPSI | /* TX process stop */ \ | ||
792 | IRQ_RXPSI) /* RX process stop */ | ||
793 | |||
794 | ks->rc_ier = STD_IRQ; | ||
795 | ks8851_wrreg16(ks, KS_ISR, STD_IRQ); | ||
796 | ks8851_wrreg16(ks, KS_IER, STD_IRQ); | ||
797 | |||
798 | netif_start_queue(ks->netdev); | ||
799 | |||
800 | if (netif_msg_ifup(ks)) | ||
801 | ks_dbg(ks, "network device %s up\n", dev->name); | ||
802 | |||
803 | mutex_unlock(&ks->lock); | ||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | /** | ||
808 | * ks8851_net_stop - close network device | ||
809 | * @dev: The device being closed. | ||
810 | * | ||
811 | * Called to close down a network device which has been active. Cancell any | ||
812 | * work, shutdown the RX and TX process and then place the chip into a low | ||
813 | * power state whilst it is not being used. | ||
814 | */ | ||
815 | static int ks8851_net_stop(struct net_device *dev) | ||
816 | { | ||
817 | struct ks8851_net *ks = netdev_priv(dev); | ||
818 | |||
819 | if (netif_msg_ifdown(ks)) | ||
820 | ks_info(ks, "%s: shutting down\n", dev->name); | ||
821 | |||
822 | netif_stop_queue(dev); | ||
823 | |||
824 | mutex_lock(&ks->lock); | ||
825 | |||
826 | /* stop any outstanding work */ | ||
827 | flush_work(&ks->irq_work); | ||
828 | flush_work(&ks->tx_work); | ||
829 | flush_work(&ks->rxctrl_work); | ||
830 | |||
831 | /* turn off the IRQs and ack any outstanding */ | ||
832 | ks8851_wrreg16(ks, KS_IER, 0x0000); | ||
833 | ks8851_wrreg16(ks, KS_ISR, 0xffff); | ||
834 | |||
835 | /* shutdown RX process */ | ||
836 | ks8851_wrreg16(ks, KS_RXCR1, 0x0000); | ||
837 | |||
838 | /* shutdown TX process */ | ||
839 | ks8851_wrreg16(ks, KS_TXCR, 0x0000); | ||
840 | |||
841 | /* set powermode to soft power down to save power */ | ||
842 | ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); | ||
843 | |||
844 | /* ensure any queued tx buffers are dumped */ | ||
845 | while (!skb_queue_empty(&ks->txq)) { | ||
846 | struct sk_buff *txb = skb_dequeue(&ks->txq); | ||
847 | |||
848 | if (netif_msg_ifdown(ks)) | ||
849 | ks_dbg(ks, "%s: freeing txb %p\n", __func__, txb); | ||
850 | |||
851 | dev_kfree_skb(txb); | ||
852 | } | ||
853 | |||
854 | mutex_unlock(&ks->lock); | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | /** | ||
859 | * ks8851_start_xmit - transmit packet | ||
860 | * @skb: The buffer to transmit | ||
861 | * @dev: The device used to transmit the packet. | ||
862 | * | ||
863 | * Called by the network layer to transmit the @skb. Queue the packet for | ||
864 | * the device and schedule the necessary work to transmit the packet when | ||
865 | * it is free. | ||
866 | * | ||
867 | * We do this to firstly avoid sleeping with the network device locked, | ||
868 | * and secondly so we can round up more than one packet to transmit which | ||
869 | * means we can try and avoid generating too many transmit done interrupts. | ||
870 | */ | ||
871 | static int ks8851_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
872 | { | ||
873 | struct ks8851_net *ks = netdev_priv(dev); | ||
874 | unsigned needed = calc_txlen(skb->len); | ||
875 | int ret = NETDEV_TX_OK; | ||
876 | |||
877 | if (netif_msg_tx_queued(ks)) | ||
878 | ks_dbg(ks, "%s: skb %p, %d@%p\n", __func__, | ||
879 | skb, skb->len, skb->data); | ||
880 | |||
881 | spin_lock(&ks->statelock); | ||
882 | |||
883 | if (needed > ks->tx_space) { | ||
884 | netif_stop_queue(dev); | ||
885 | ret = NETDEV_TX_BUSY; | ||
886 | } else { | ||
887 | ks->tx_space -= needed; | ||
888 | skb_queue_tail(&ks->txq, skb); | ||
889 | } | ||
890 | |||
891 | spin_unlock(&ks->statelock); | ||
892 | schedule_work(&ks->tx_work); | ||
893 | |||
894 | return ret; | ||
895 | } | ||
896 | |||
897 | /** | ||
898 | * ks8851_rxctrl_work - work handler to change rx mode | ||
899 | * @work: The work structure this belongs to. | ||
900 | * | ||
901 | * Lock the device and issue the necessary changes to the receive mode from | ||
902 | * the network device layer. This is done so that we can do this without | ||
903 | * having to sleep whilst holding the network device lock. | ||
904 | * | ||
905 | * Since the recommendation from Micrel is that the RXQ is shutdown whilst the | ||
906 | * receive parameters are programmed, we issue a write to disable the RXQ and | ||
907 | * then wait for the interrupt handler to be triggered once the RXQ shutdown is | ||
908 | * complete. The interrupt handler then writes the new values into the chip. | ||
909 | */ | ||
910 | static void ks8851_rxctrl_work(struct work_struct *work) | ||
911 | { | ||
912 | struct ks8851_net *ks = container_of(work, struct ks8851_net, rxctrl_work); | ||
913 | |||
914 | mutex_lock(&ks->lock); | ||
915 | |||
916 | /* need to shutdown RXQ before modifying filter parameters */ | ||
917 | ks8851_wrreg16(ks, KS_RXCR1, 0x00); | ||
918 | |||
919 | mutex_unlock(&ks->lock); | ||
920 | } | ||
921 | |||
922 | static void ks8851_set_rx_mode(struct net_device *dev) | ||
923 | { | ||
924 | struct ks8851_net *ks = netdev_priv(dev); | ||
925 | struct ks8851_rxctrl rxctrl; | ||
926 | |||
927 | memset(&rxctrl, 0, sizeof(rxctrl)); | ||
928 | |||
929 | if (dev->flags & IFF_PROMISC) { | ||
930 | /* interface to receive everything */ | ||
931 | |||
932 | rxctrl.rxcr1 = RXCR1_RXAE | RXCR1_RXINVF; | ||
933 | } else if (dev->flags & IFF_ALLMULTI) { | ||
934 | /* accept all multicast packets */ | ||
935 | |||
936 | rxctrl.rxcr1 = (RXCR1_RXME | RXCR1_RXAE | | ||
937 | RXCR1_RXPAFMA | RXCR1_RXMAFMA); | ||
938 | } else if (dev->flags & IFF_MULTICAST && dev->mc_count > 0) { | ||
939 | struct dev_mc_list *mcptr = dev->mc_list; | ||
940 | u32 crc; | ||
941 | int i; | ||
942 | |||
943 | /* accept some multicast */ | ||
944 | |||
945 | for (i = dev->mc_count; i > 0; i--) { | ||
946 | crc = ether_crc(ETH_ALEN, mcptr->dmi_addr); | ||
947 | crc >>= (32 - 6); /* get top six bits */ | ||
948 | |||
949 | rxctrl.mchash[crc >> 4] |= (1 << (crc & 0xf)); | ||
950 | mcptr = mcptr->next; | ||
951 | } | ||
952 | |||
953 | rxctrl.rxcr1 = RXCR1_RXME | RXCR1_RXAE | RXCR1_RXPAFMA; | ||
954 | } else { | ||
955 | /* just accept broadcast / unicast */ | ||
956 | rxctrl.rxcr1 = RXCR1_RXPAFMA; | ||
957 | } | ||
958 | |||
959 | rxctrl.rxcr1 |= (RXCR1_RXUE | /* unicast enable */ | ||
960 | RXCR1_RXBE | /* broadcast enable */ | ||
961 | RXCR1_RXE | /* RX process enable */ | ||
962 | RXCR1_RXFCE); /* enable flow control */ | ||
963 | |||
964 | rxctrl.rxcr2 |= RXCR2_SRDBL_FRAME; | ||
965 | |||
966 | /* schedule work to do the actual set of the data if needed */ | ||
967 | |||
968 | spin_lock(&ks->statelock); | ||
969 | |||
970 | if (memcmp(&rxctrl, &ks->rxctrl, sizeof(rxctrl)) != 0) { | ||
971 | memcpy(&ks->rxctrl, &rxctrl, sizeof(ks->rxctrl)); | ||
972 | schedule_work(&ks->rxctrl_work); | ||
973 | } | ||
974 | |||
975 | spin_unlock(&ks->statelock); | ||
976 | } | ||
977 | |||
978 | static int ks8851_set_mac_address(struct net_device *dev, void *addr) | ||
979 | { | ||
980 | struct sockaddr *sa = addr; | ||
981 | |||
982 | if (netif_running(dev)) | ||
983 | return -EBUSY; | ||
984 | |||
985 | if (!is_valid_ether_addr(sa->sa_data)) | ||
986 | return -EADDRNOTAVAIL; | ||
987 | |||
988 | memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); | ||
989 | return ks8851_write_mac_addr(dev); | ||
990 | } | ||
991 | |||
992 | static int ks8851_net_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
993 | { | ||
994 | struct ks8851_net *ks = netdev_priv(dev); | ||
995 | |||
996 | if (!netif_running(dev)) | ||
997 | return -EINVAL; | ||
998 | |||
999 | return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL); | ||
1000 | } | ||
1001 | |||
1002 | static const struct net_device_ops ks8851_netdev_ops = { | ||
1003 | .ndo_open = ks8851_net_open, | ||
1004 | .ndo_stop = ks8851_net_stop, | ||
1005 | .ndo_do_ioctl = ks8851_net_ioctl, | ||
1006 | .ndo_start_xmit = ks8851_start_xmit, | ||
1007 | .ndo_set_mac_address = ks8851_set_mac_address, | ||
1008 | .ndo_set_rx_mode = ks8851_set_rx_mode, | ||
1009 | .ndo_change_mtu = eth_change_mtu, | ||
1010 | .ndo_validate_addr = eth_validate_addr, | ||
1011 | }; | ||
1012 | |||
1013 | /* ethtool support */ | ||
1014 | |||
1015 | static void ks8851_get_drvinfo(struct net_device *dev, | ||
1016 | struct ethtool_drvinfo *di) | ||
1017 | { | ||
1018 | strlcpy(di->driver, "KS8851", sizeof(di->driver)); | ||
1019 | strlcpy(di->version, "1.00", sizeof(di->version)); | ||
1020 | strlcpy(di->bus_info, dev_name(dev->dev.parent), sizeof(di->bus_info)); | ||
1021 | } | ||
1022 | |||
1023 | static u32 ks8851_get_msglevel(struct net_device *dev) | ||
1024 | { | ||
1025 | struct ks8851_net *ks = netdev_priv(dev); | ||
1026 | return ks->msg_enable; | ||
1027 | } | ||
1028 | |||
1029 | static void ks8851_set_msglevel(struct net_device *dev, u32 to) | ||
1030 | { | ||
1031 | struct ks8851_net *ks = netdev_priv(dev); | ||
1032 | ks->msg_enable = to; | ||
1033 | } | ||
1034 | |||
1035 | static int ks8851_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1036 | { | ||
1037 | struct ks8851_net *ks = netdev_priv(dev); | ||
1038 | return mii_ethtool_gset(&ks->mii, cmd); | ||
1039 | } | ||
1040 | |||
1041 | static int ks8851_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1042 | { | ||
1043 | struct ks8851_net *ks = netdev_priv(dev); | ||
1044 | return mii_ethtool_sset(&ks->mii, cmd); | ||
1045 | } | ||
1046 | |||
1047 | static u32 ks8851_get_link(struct net_device *dev) | ||
1048 | { | ||
1049 | struct ks8851_net *ks = netdev_priv(dev); | ||
1050 | return mii_link_ok(&ks->mii); | ||
1051 | } | ||
1052 | |||
1053 | static int ks8851_nway_reset(struct net_device *dev) | ||
1054 | { | ||
1055 | struct ks8851_net *ks = netdev_priv(dev); | ||
1056 | return mii_nway_restart(&ks->mii); | ||
1057 | } | ||
1058 | |||
1059 | static const struct ethtool_ops ks8851_ethtool_ops = { | ||
1060 | .get_drvinfo = ks8851_get_drvinfo, | ||
1061 | .get_msglevel = ks8851_get_msglevel, | ||
1062 | .set_msglevel = ks8851_set_msglevel, | ||
1063 | .get_settings = ks8851_get_settings, | ||
1064 | .set_settings = ks8851_set_settings, | ||
1065 | .get_link = ks8851_get_link, | ||
1066 | .nway_reset = ks8851_nway_reset, | ||
1067 | }; | ||
1068 | |||
1069 | /* MII interface controls */ | ||
1070 | |||
1071 | /** | ||
1072 | * ks8851_phy_reg - convert MII register into a KS8851 register | ||
1073 | * @reg: MII register number. | ||
1074 | * | ||
1075 | * Return the KS8851 register number for the corresponding MII PHY register | ||
1076 | * if possible. Return zero if the MII register has no direct mapping to the | ||
1077 | * KS8851 register set. | ||
1078 | */ | ||
1079 | static int ks8851_phy_reg(int reg) | ||
1080 | { | ||
1081 | switch (reg) { | ||
1082 | case MII_BMCR: | ||
1083 | return KS_P1MBCR; | ||
1084 | case MII_BMSR: | ||
1085 | return KS_P1MBSR; | ||
1086 | case MII_PHYSID1: | ||
1087 | return KS_PHY1ILR; | ||
1088 | case MII_PHYSID2: | ||
1089 | return KS_PHY1IHR; | ||
1090 | case MII_ADVERTISE: | ||
1091 | return KS_P1ANAR; | ||
1092 | case MII_LPA: | ||
1093 | return KS_P1ANLPR; | ||
1094 | } | ||
1095 | |||
1096 | return 0x0; | ||
1097 | } | ||
1098 | |||
1099 | /** | ||
1100 | * ks8851_phy_read - MII interface PHY register read. | ||
1101 | * @dev: The network device the PHY is on. | ||
1102 | * @phy_addr: Address of PHY (ignored as we only have one) | ||
1103 | * @reg: The register to read. | ||
1104 | * | ||
1105 | * This call reads data from the PHY register specified in @reg. Since the | ||
1106 | * device does not support all the MII registers, the non-existant values | ||
1107 | * are always returned as zero. | ||
1108 | * | ||
1109 | * We return zero for unsupported registers as the MII code does not check | ||
1110 | * the value returned for any error status, and simply returns it to the | ||
1111 | * caller. The mii-tool that the driver was tested with takes any -ve error | ||
1112 | * as real PHY capabilities, thus displaying incorrect data to the user. | ||
1113 | */ | ||
1114 | static int ks8851_phy_read(struct net_device *dev, int phy_addr, int reg) | ||
1115 | { | ||
1116 | struct ks8851_net *ks = netdev_priv(dev); | ||
1117 | int ksreg; | ||
1118 | int result; | ||
1119 | |||
1120 | ksreg = ks8851_phy_reg(reg); | ||
1121 | if (!ksreg) | ||
1122 | return 0x0; /* no error return allowed, so use zero */ | ||
1123 | |||
1124 | mutex_lock(&ks->lock); | ||
1125 | result = ks8851_rdreg16(ks, ksreg); | ||
1126 | mutex_unlock(&ks->lock); | ||
1127 | |||
1128 | return result; | ||
1129 | } | ||
1130 | |||
1131 | static void ks8851_phy_write(struct net_device *dev, | ||
1132 | int phy, int reg, int value) | ||
1133 | { | ||
1134 | struct ks8851_net *ks = netdev_priv(dev); | ||
1135 | int ksreg; | ||
1136 | |||
1137 | ksreg = ks8851_phy_reg(reg); | ||
1138 | if (ksreg) { | ||
1139 | mutex_lock(&ks->lock); | ||
1140 | ks8851_wrreg16(ks, ksreg, value); | ||
1141 | mutex_unlock(&ks->lock); | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | /** | ||
1146 | * ks8851_read_selftest - read the selftest memory info. | ||
1147 | * @ks: The device state | ||
1148 | * | ||
1149 | * Read and check the TX/RX memory selftest information. | ||
1150 | */ | ||
1151 | static int ks8851_read_selftest(struct ks8851_net *ks) | ||
1152 | { | ||
1153 | unsigned both_done = MBIR_TXMBF | MBIR_RXMBF; | ||
1154 | int ret = 0; | ||
1155 | unsigned rd; | ||
1156 | |||
1157 | rd = ks8851_rdreg16(ks, KS_MBIR); | ||
1158 | |||
1159 | if ((rd & both_done) != both_done) { | ||
1160 | ks_warn(ks, "Memory selftest not finished\n"); | ||
1161 | return 0; | ||
1162 | } | ||
1163 | |||
1164 | if (rd & MBIR_TXMBFA) { | ||
1165 | ks_err(ks, "TX memory selftest fail\n"); | ||
1166 | ret |= 1; | ||
1167 | } | ||
1168 | |||
1169 | if (rd & MBIR_RXMBFA) { | ||
1170 | ks_err(ks, "RX memory selftest fail\n"); | ||
1171 | ret |= 2; | ||
1172 | } | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | |||
1177 | /* driver bus management functions */ | ||
1178 | |||
1179 | static int __devinit ks8851_probe(struct spi_device *spi) | ||
1180 | { | ||
1181 | struct net_device *ndev; | ||
1182 | struct ks8851_net *ks; | ||
1183 | int ret; | ||
1184 | |||
1185 | ndev = alloc_etherdev(sizeof(struct ks8851_net)); | ||
1186 | if (!ndev) { | ||
1187 | dev_err(&spi->dev, "failed to alloc ethernet device\n"); | ||
1188 | return -ENOMEM; | ||
1189 | } | ||
1190 | |||
1191 | spi->bits_per_word = 8; | ||
1192 | |||
1193 | ks = netdev_priv(ndev); | ||
1194 | |||
1195 | ks->netdev = ndev; | ||
1196 | ks->spidev = spi; | ||
1197 | ks->tx_space = 6144; | ||
1198 | |||
1199 | mutex_init(&ks->lock); | ||
1200 | spin_lock_init(&ks->statelock); | ||
1201 | |||
1202 | INIT_WORK(&ks->tx_work, ks8851_tx_work); | ||
1203 | INIT_WORK(&ks->irq_work, ks8851_irq_work); | ||
1204 | INIT_WORK(&ks->rxctrl_work, ks8851_rxctrl_work); | ||
1205 | |||
1206 | /* initialise pre-made spi transfer messages */ | ||
1207 | |||
1208 | spi_message_init(&ks->spi_msg1); | ||
1209 | spi_message_add_tail(&ks->spi_xfer1, &ks->spi_msg1); | ||
1210 | |||
1211 | spi_message_init(&ks->spi_msg2); | ||
1212 | spi_message_add_tail(&ks->spi_xfer2[0], &ks->spi_msg2); | ||
1213 | spi_message_add_tail(&ks->spi_xfer2[1], &ks->spi_msg2); | ||
1214 | |||
1215 | /* setup mii state */ | ||
1216 | ks->mii.dev = ndev; | ||
1217 | ks->mii.phy_id = 1, | ||
1218 | ks->mii.phy_id_mask = 1; | ||
1219 | ks->mii.reg_num_mask = 0xf; | ||
1220 | ks->mii.mdio_read = ks8851_phy_read; | ||
1221 | ks->mii.mdio_write = ks8851_phy_write; | ||
1222 | |||
1223 | dev_info(&spi->dev, "message enable is %d\n", msg_enable); | ||
1224 | |||
1225 | /* set the default message enable */ | ||
1226 | ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV | | ||
1227 | NETIF_MSG_PROBE | | ||
1228 | NETIF_MSG_LINK)); | ||
1229 | |||
1230 | skb_queue_head_init(&ks->txq); | ||
1231 | |||
1232 | SET_ETHTOOL_OPS(ndev, &ks8851_ethtool_ops); | ||
1233 | SET_NETDEV_DEV(ndev, &spi->dev); | ||
1234 | |||
1235 | dev_set_drvdata(&spi->dev, ks); | ||
1236 | |||
1237 | ndev->if_port = IF_PORT_100BASET; | ||
1238 | ndev->netdev_ops = &ks8851_netdev_ops; | ||
1239 | ndev->irq = spi->irq; | ||
1240 | |||
1241 | /* simple check for a valid chip being connected to the bus */ | ||
1242 | |||
1243 | if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { | ||
1244 | dev_err(&spi->dev, "failed to read device ID\n"); | ||
1245 | ret = -ENODEV; | ||
1246 | goto err_id; | ||
1247 | } | ||
1248 | |||
1249 | ks8851_read_selftest(ks); | ||
1250 | ks8851_init_mac(ks); | ||
1251 | |||
1252 | ret = request_irq(spi->irq, ks8851_irq, IRQF_TRIGGER_LOW, | ||
1253 | ndev->name, ks); | ||
1254 | if (ret < 0) { | ||
1255 | dev_err(&spi->dev, "failed to get irq\n"); | ||
1256 | goto err_irq; | ||
1257 | } | ||
1258 | |||
1259 | ret = register_netdev(ndev); | ||
1260 | if (ret) { | ||
1261 | dev_err(&spi->dev, "failed to register network device\n"); | ||
1262 | goto err_netdev; | ||
1263 | } | ||
1264 | |||
1265 | dev_info(&spi->dev, "revision %d, MAC %pM, IRQ %d\n", | ||
1266 | CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), | ||
1267 | ndev->dev_addr, ndev->irq); | ||
1268 | |||
1269 | return 0; | ||
1270 | |||
1271 | |||
1272 | err_netdev: | ||
1273 | free_irq(ndev->irq, ndev); | ||
1274 | |||
1275 | err_id: | ||
1276 | err_irq: | ||
1277 | free_netdev(ndev); | ||
1278 | return ret; | ||
1279 | } | ||
1280 | |||
1281 | static int __devexit ks8851_remove(struct spi_device *spi) | ||
1282 | { | ||
1283 | struct ks8851_net *priv = dev_get_drvdata(&spi->dev); | ||
1284 | |||
1285 | if (netif_msg_drv(priv)) | ||
1286 | dev_info(&spi->dev, "remove"); | ||
1287 | |||
1288 | unregister_netdev(priv->netdev); | ||
1289 | free_irq(spi->irq, priv); | ||
1290 | free_netdev(priv->netdev); | ||
1291 | |||
1292 | return 0; | ||
1293 | } | ||
1294 | |||
1295 | static struct spi_driver ks8851_driver = { | ||
1296 | .driver = { | ||
1297 | .name = "ks8851", | ||
1298 | .owner = THIS_MODULE, | ||
1299 | }, | ||
1300 | .probe = ks8851_probe, | ||
1301 | .remove = __devexit_p(ks8851_remove), | ||
1302 | }; | ||
1303 | |||
1304 | static int __init ks8851_init(void) | ||
1305 | { | ||
1306 | return spi_register_driver(&ks8851_driver); | ||
1307 | } | ||
1308 | |||
1309 | static void __exit ks8851_exit(void) | ||
1310 | { | ||
1311 | spi_unregister_driver(&ks8851_driver); | ||
1312 | } | ||
1313 | |||
1314 | module_init(ks8851_init); | ||
1315 | module_exit(ks8851_exit); | ||
1316 | |||
1317 | MODULE_DESCRIPTION("KS8851 Network driver"); | ||
1318 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
1319 | MODULE_LICENSE("GPL"); | ||
1320 | |||
1321 | module_param_named(message, msg_enable, int, 0); | ||
1322 | MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)"); | ||
diff --git a/drivers/net/ks8851.h b/drivers/net/ks8851.h new file mode 100644 index 000000000000..85abe147afbf --- /dev/null +++ b/drivers/net/ks8851.h | |||
@@ -0,0 +1,296 @@ | |||
1 | /* drivers/net/ks8851.h | ||
2 | * | ||
3 | * Copyright 2009 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * KS8851 register definitions | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #define KS_CCR 0x08 | ||
14 | #define CCR_EEPROM (1 << 9) | ||
15 | #define CCR_SPI (1 << 8) | ||
16 | #define CCR_32PIN (1 << 0) | ||
17 | |||
18 | /* MAC address registers */ | ||
19 | #define KS_MARL 0x10 | ||
20 | #define KS_MARM 0x12 | ||
21 | #define KS_MARH 0x14 | ||
22 | |||
23 | #define KS_OBCR 0x20 | ||
24 | #define OBCR_ODS_16mA (1 << 6) | ||
25 | |||
26 | #define KS_EEPCR 0x22 | ||
27 | #define EEPCR_EESA (1 << 4) | ||
28 | #define EEPCR_EESB (1 << 3) | ||
29 | #define EEPCR_EEDO (1 << 2) | ||
30 | #define EEPCR_EESCK (1 << 1) | ||
31 | #define EEPCR_EECS (1 << 0) | ||
32 | |||
33 | #define KS_MBIR 0x24 | ||
34 | #define MBIR_TXMBF (1 << 12) | ||
35 | #define MBIR_TXMBFA (1 << 11) | ||
36 | #define MBIR_RXMBF (1 << 4) | ||
37 | #define MBIR_RXMBFA (1 << 3) | ||
38 | |||
39 | #define KS_GRR 0x26 | ||
40 | #define GRR_QMU (1 << 1) | ||
41 | #define GRR_GSR (1 << 0) | ||
42 | |||
43 | #define KS_WFCR 0x2A | ||
44 | #define WFCR_MPRXE (1 << 7) | ||
45 | #define WFCR_WF3E (1 << 3) | ||
46 | #define WFCR_WF2E (1 << 2) | ||
47 | #define WFCR_WF1E (1 << 1) | ||
48 | #define WFCR_WF0E (1 << 0) | ||
49 | |||
50 | #define KS_WF0CRC0 0x30 | ||
51 | #define KS_WF0CRC1 0x32 | ||
52 | #define KS_WF0BM0 0x34 | ||
53 | #define KS_WF0BM1 0x36 | ||
54 | #define KS_WF0BM2 0x38 | ||
55 | #define KS_WF0BM3 0x3A | ||
56 | |||
57 | #define KS_WF1CRC0 0x40 | ||
58 | #define KS_WF1CRC1 0x42 | ||
59 | #define KS_WF1BM0 0x44 | ||
60 | #define KS_WF1BM1 0x46 | ||
61 | #define KS_WF1BM2 0x48 | ||
62 | #define KS_WF1BM3 0x4A | ||
63 | |||
64 | #define KS_WF2CRC0 0x50 | ||
65 | #define KS_WF2CRC1 0x52 | ||
66 | #define KS_WF2BM0 0x54 | ||
67 | #define KS_WF2BM1 0x56 | ||
68 | #define KS_WF2BM2 0x58 | ||
69 | #define KS_WF2BM3 0x5A | ||
70 | |||
71 | #define KS_WF3CRC0 0x60 | ||
72 | #define KS_WF3CRC1 0x62 | ||
73 | #define KS_WF3BM0 0x64 | ||
74 | #define KS_WF3BM1 0x66 | ||
75 | #define KS_WF3BM2 0x68 | ||
76 | #define KS_WF3BM3 0x6A | ||
77 | |||
78 | #define KS_TXCR 0x70 | ||
79 | #define TXCR_TCGICMP (1 << 8) | ||
80 | #define TXCR_TCGUDP (1 << 7) | ||
81 | #define TXCR_TCGTCP (1 << 6) | ||
82 | #define TXCR_TCGIP (1 << 5) | ||
83 | #define TXCR_FTXQ (1 << 4) | ||
84 | #define TXCR_TXFCE (1 << 3) | ||
85 | #define TXCR_TXPE (1 << 2) | ||
86 | #define TXCR_TXCRC (1 << 1) | ||
87 | #define TXCR_TXE (1 << 0) | ||
88 | |||
89 | #define KS_TXSR 0x72 | ||
90 | #define TXSR_TXLC (1 << 13) | ||
91 | #define TXSR_TXMC (1 << 12) | ||
92 | #define TXSR_TXFID_MASK (0x3f << 0) | ||
93 | #define TXSR_TXFID_SHIFT (0) | ||
94 | #define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f) | ||
95 | |||
96 | #define KS_RXCR1 0x74 | ||
97 | #define RXCR1_FRXQ (1 << 15) | ||
98 | #define RXCR1_RXUDPFCC (1 << 14) | ||
99 | #define RXCR1_RXTCPFCC (1 << 13) | ||
100 | #define RXCR1_RXIPFCC (1 << 12) | ||
101 | #define RXCR1_RXPAFMA (1 << 11) | ||
102 | #define RXCR1_RXFCE (1 << 10) | ||
103 | #define RXCR1_RXEFE (1 << 9) | ||
104 | #define RXCR1_RXMAFMA (1 << 8) | ||
105 | #define RXCR1_RXBE (1 << 7) | ||
106 | #define RXCR1_RXME (1 << 6) | ||
107 | #define RXCR1_RXUE (1 << 5) | ||
108 | #define RXCR1_RXAE (1 << 4) | ||
109 | #define RXCR1_RXINVF (1 << 1) | ||
110 | #define RXCR1_RXE (1 << 0) | ||
111 | |||
112 | #define KS_RXCR2 0x76 | ||
113 | #define RXCR2_SRDBL_MASK (0x7 << 5) | ||
114 | #define RXCR2_SRDBL_SHIFT (5) | ||
115 | #define RXCR2_SRDBL_4B (0x0 << 5) | ||
116 | #define RXCR2_SRDBL_8B (0x1 << 5) | ||
117 | #define RXCR2_SRDBL_16B (0x2 << 5) | ||
118 | #define RXCR2_SRDBL_32B (0x3 << 5) | ||
119 | #define RXCR2_SRDBL_FRAME (0x4 << 5) | ||
120 | #define RXCR2_IUFFP (1 << 4) | ||
121 | #define RXCR2_RXIUFCEZ (1 << 3) | ||
122 | #define RXCR2_UDPLFE (1 << 2) | ||
123 | #define RXCR2_RXICMPFCC (1 << 1) | ||
124 | #define RXCR2_RXSAF (1 << 0) | ||
125 | |||
126 | #define KS_TXMIR 0x78 | ||
127 | |||
128 | #define KS_RXFHSR 0x7C | ||
129 | #define RXFSHR_RXFV (1 << 15) | ||
130 | #define RXFSHR_RXICMPFCS (1 << 13) | ||
131 | #define RXFSHR_RXIPFCS (1 << 12) | ||
132 | #define RXFSHR_RXTCPFCS (1 << 11) | ||
133 | #define RXFSHR_RXUDPFCS (1 << 10) | ||
134 | #define RXFSHR_RXBF (1 << 7) | ||
135 | #define RXFSHR_RXMF (1 << 6) | ||
136 | #define RXFSHR_RXUF (1 << 5) | ||
137 | #define RXFSHR_RXMR (1 << 4) | ||
138 | #define RXFSHR_RXFT (1 << 3) | ||
139 | #define RXFSHR_RXFTL (1 << 2) | ||
140 | #define RXFSHR_RXRF (1 << 1) | ||
141 | #define RXFSHR_RXCE (1 << 0) | ||
142 | |||
143 | #define KS_RXFHBCR 0x7E | ||
144 | #define KS_TXQCR 0x80 | ||
145 | #define TXQCR_AETFE (1 << 2) | ||
146 | #define TXQCR_TXQMAM (1 << 1) | ||
147 | #define TXQCR_METFE (1 << 0) | ||
148 | |||
149 | #define KS_RXQCR 0x82 | ||
150 | #define RXQCR_RXDTTS (1 << 12) | ||
151 | #define RXQCR_RXDBCTS (1 << 11) | ||
152 | #define RXQCR_RXFCTS (1 << 10) | ||
153 | #define RXQCR_RXIPHTOE (1 << 9) | ||
154 | #define RXQCR_RXDTTE (1 << 7) | ||
155 | #define RXQCR_RXDBCTE (1 << 6) | ||
156 | #define RXQCR_RXFCTE (1 << 5) | ||
157 | #define RXQCR_ADRFE (1 << 4) | ||
158 | #define RXQCR_SDA (1 << 3) | ||
159 | #define RXQCR_RRXEF (1 << 0) | ||
160 | |||
161 | #define KS_TXFDPR 0x84 | ||
162 | #define TXFDPR_TXFPAI (1 << 14) | ||
163 | #define TXFDPR_TXFP_MASK (0x7ff << 0) | ||
164 | #define TXFDPR_TXFP_SHIFT (0) | ||
165 | |||
166 | #define KS_RXFDPR 0x86 | ||
167 | #define RXFDPR_RXFPAI (1 << 14) | ||
168 | |||
169 | #define KS_RXDTTR 0x8C | ||
170 | #define KS_RXDBCTR 0x8E | ||
171 | |||
172 | #define KS_IER 0x90 | ||
173 | #define KS_ISR 0x92 | ||
174 | #define IRQ_LCI (1 << 15) | ||
175 | #define IRQ_TXI (1 << 14) | ||
176 | #define IRQ_RXI (1 << 13) | ||
177 | #define IRQ_RXOI (1 << 11) | ||
178 | #define IRQ_TXPSI (1 << 9) | ||
179 | #define IRQ_RXPSI (1 << 8) | ||
180 | #define IRQ_TXSAI (1 << 6) | ||
181 | #define IRQ_RXWFDI (1 << 5) | ||
182 | #define IRQ_RXMPDI (1 << 4) | ||
183 | #define IRQ_LDI (1 << 3) | ||
184 | #define IRQ_EDI (1 << 2) | ||
185 | #define IRQ_SPIBEI (1 << 1) | ||
186 | #define IRQ_DEDI (1 << 0) | ||
187 | |||
188 | #define KS_RXFCTR 0x9C | ||
189 | #define KS_RXFC 0x9D | ||
190 | #define RXFCTR_RXFC_MASK (0xff << 8) | ||
191 | #define RXFCTR_RXFC_SHIFT (8) | ||
192 | #define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff) | ||
193 | #define RXFCTR_RXFCT_MASK (0xff << 0) | ||
194 | #define RXFCTR_RXFCT_SHIFT (0) | ||
195 | |||
196 | #define KS_TXNTFSR 0x9E | ||
197 | |||
198 | #define KS_MAHTR0 0xA0 | ||
199 | #define KS_MAHTR1 0xA2 | ||
200 | #define KS_MAHTR2 0xA4 | ||
201 | #define KS_MAHTR3 0xA6 | ||
202 | |||
203 | #define KS_FCLWR 0xB0 | ||
204 | #define KS_FCHWR 0xB2 | ||
205 | #define KS_FCOWR 0xB4 | ||
206 | |||
207 | #define KS_CIDER 0xC0 | ||
208 | #define CIDER_ID 0x8870 | ||
209 | #define CIDER_REV_MASK (0x7 << 1) | ||
210 | #define CIDER_REV_SHIFT (1) | ||
211 | #define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7) | ||
212 | |||
213 | #define KS_CGCR 0xC6 | ||
214 | |||
215 | #define KS_IACR 0xC8 | ||
216 | #define IACR_RDEN (1 << 12) | ||
217 | #define IACR_TSEL_MASK (0x3 << 10) | ||
218 | #define IACR_TSEL_SHIFT (10) | ||
219 | #define IACR_TSEL_MIB (0x3 << 10) | ||
220 | #define IACR_ADDR_MASK (0x1f << 0) | ||
221 | #define IACR_ADDR_SHIFT (0) | ||
222 | |||
223 | #define KS_IADLR 0xD0 | ||
224 | #define KS_IAHDR 0xD2 | ||
225 | |||
226 | #define KS_PMECR 0xD4 | ||
227 | #define PMECR_PME_DELAY (1 << 14) | ||
228 | #define PMECR_PME_POL (1 << 12) | ||
229 | #define PMECR_WOL_WAKEUP (1 << 11) | ||
230 | #define PMECR_WOL_MAGICPKT (1 << 10) | ||
231 | #define PMECR_WOL_LINKUP (1 << 9) | ||
232 | #define PMECR_WOL_ENERGY (1 << 8) | ||
233 | #define PMECR_AUTO_WAKE_EN (1 << 7) | ||
234 | #define PMECR_WAKEUP_NORMAL (1 << 6) | ||
235 | #define PMECR_WKEVT_MASK (0xf << 2) | ||
236 | #define PMECR_WKEVT_SHIFT (2) | ||
237 | #define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf) | ||
238 | #define PMECR_WKEVT_ENERGY (0x1 << 2) | ||
239 | #define PMECR_WKEVT_LINK (0x2 << 2) | ||
240 | #define PMECR_WKEVT_MAGICPKT (0x4 << 2) | ||
241 | #define PMECR_WKEVT_FRAME (0x8 << 2) | ||
242 | #define PMECR_PM_MASK (0x3 << 0) | ||
243 | #define PMECR_PM_SHIFT (0) | ||
244 | #define PMECR_PM_NORMAL (0x0 << 0) | ||
245 | #define PMECR_PM_ENERGY (0x1 << 0) | ||
246 | #define PMECR_PM_SOFTDOWN (0x2 << 0) | ||
247 | #define PMECR_PM_POWERSAVE (0x3 << 0) | ||
248 | |||
249 | /* Standard MII PHY data */ | ||
250 | #define KS_P1MBCR 0xE4 | ||
251 | #define KS_P1MBSR 0xE6 | ||
252 | #define KS_PHY1ILR 0xE8 | ||
253 | #define KS_PHY1IHR 0xEA | ||
254 | #define KS_P1ANAR 0xEC | ||
255 | #define KS_P1ANLPR 0xEE | ||
256 | |||
257 | #define KS_P1SCLMD 0xF4 | ||
258 | #define P1SCLMD_LEDOFF (1 << 15) | ||
259 | #define P1SCLMD_TXIDS (1 << 14) | ||
260 | #define P1SCLMD_RESTARTAN (1 << 13) | ||
261 | #define P1SCLMD_DISAUTOMDIX (1 << 10) | ||
262 | #define P1SCLMD_FORCEMDIX (1 << 9) | ||
263 | #define P1SCLMD_AUTONEGEN (1 << 7) | ||
264 | #define P1SCLMD_FORCE100 (1 << 6) | ||
265 | #define P1SCLMD_FORCEFDX (1 << 5) | ||
266 | #define P1SCLMD_ADV_FLOW (1 << 4) | ||
267 | #define P1SCLMD_ADV_100BT_FDX (1 << 3) | ||
268 | #define P1SCLMD_ADV_100BT_HDX (1 << 2) | ||
269 | #define P1SCLMD_ADV_10BT_FDX (1 << 1) | ||
270 | #define P1SCLMD_ADV_10BT_HDX (1 << 0) | ||
271 | |||
272 | #define KS_P1CR 0xF6 | ||
273 | #define P1CR_HP_MDIX (1 << 15) | ||
274 | #define P1CR_REV_POL (1 << 13) | ||
275 | #define P1CR_OP_100M (1 << 10) | ||
276 | #define P1CR_OP_FDX (1 << 9) | ||
277 | #define P1CR_OP_MDI (1 << 7) | ||
278 | #define P1CR_AN_DONE (1 << 6) | ||
279 | #define P1CR_LINK_GOOD (1 << 5) | ||
280 | #define P1CR_PNTR_FLOW (1 << 4) | ||
281 | #define P1CR_PNTR_100BT_FDX (1 << 3) | ||
282 | #define P1CR_PNTR_100BT_HDX (1 << 2) | ||
283 | #define P1CR_PNTR_10BT_FDX (1 << 1) | ||
284 | #define P1CR_PNTR_10BT_HDX (1 << 0) | ||
285 | |||
286 | /* TX Frame control */ | ||
287 | |||
288 | #define TXFR_TXIC (1 << 15) | ||
289 | #define TXFR_TXFID_MASK (0x3f << 0) | ||
290 | #define TXFR_TXFID_SHIFT (0) | ||
291 | |||
292 | /* SPI frame opcodes */ | ||
293 | #define KS_SPIOP_RD (0x00) | ||
294 | #define KS_SPIOP_WR (0x40) | ||
295 | #define KS_SPIOP_RXFIFO (0x80) | ||
296 | #define KS_SPIOP_TXFIFO (0xC0) | ||
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index acd143da161d..61eabcac734c 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -179,7 +179,7 @@ static const struct net_device_ops macsonic_netdev_ops = { | |||
179 | .ndo_set_mac_address = eth_mac_addr, | 179 | .ndo_set_mac_address = eth_mac_addr, |
180 | }; | 180 | }; |
181 | 181 | ||
182 | static int __init macsonic_init(struct net_device *dev) | 182 | static int __devinit macsonic_init(struct net_device *dev) |
183 | { | 183 | { |
184 | struct sonic_local* lp = netdev_priv(dev); | 184 | struct sonic_local* lp = netdev_priv(dev); |
185 | 185 | ||
@@ -223,7 +223,7 @@ static int __init macsonic_init(struct net_device *dev) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev) | 226 | static int __devinit mac_onboard_sonic_ethernet_addr(struct net_device *dev) |
227 | { | 227 | { |
228 | struct sonic_local *lp = netdev_priv(dev); | 228 | struct sonic_local *lp = netdev_priv(dev); |
229 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; | 229 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; |
@@ -288,7 +288,7 @@ static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev) | |||
288 | } else return 0; | 288 | } else return 0; |
289 | } | 289 | } |
290 | 290 | ||
291 | static int __init mac_onboard_sonic_probe(struct net_device *dev) | 291 | static int __devinit mac_onboard_sonic_probe(struct net_device *dev) |
292 | { | 292 | { |
293 | /* Bwahahaha */ | 293 | /* Bwahahaha */ |
294 | static int once_is_more_than_enough; | 294 | static int once_is_more_than_enough; |
@@ -409,7 +409,7 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev) | |||
409 | return macsonic_init(dev); | 409 | return macsonic_init(dev); |
410 | } | 410 | } |
411 | 411 | ||
412 | static int __init mac_nubus_sonic_ethernet_addr(struct net_device *dev, | 412 | static int __devinit mac_nubus_sonic_ethernet_addr(struct net_device *dev, |
413 | unsigned long prom_addr, | 413 | unsigned long prom_addr, |
414 | int id) | 414 | int id) |
415 | { | 415 | { |
@@ -424,7 +424,7 @@ static int __init mac_nubus_sonic_ethernet_addr(struct net_device *dev, | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | static int __init macsonic_ident(struct nubus_dev *ndev) | 427 | static int __devinit macsonic_ident(struct nubus_dev *ndev) |
428 | { | 428 | { |
429 | if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC && | 429 | if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC && |
430 | ndev->dr_sw == NUBUS_DRSW_SONIC_LC) | 430 | ndev->dr_sw == NUBUS_DRSW_SONIC_LC) |
@@ -449,7 +449,7 @@ static int __init macsonic_ident(struct nubus_dev *ndev) | |||
449 | return -1; | 449 | return -1; |
450 | } | 450 | } |
451 | 451 | ||
452 | static int __init mac_nubus_sonic_probe(struct net_device *dev) | 452 | static int __devinit mac_nubus_sonic_probe(struct net_device *dev) |
453 | { | 453 | { |
454 | static int slots; | 454 | static int slots; |
455 | struct nubus_dev* ndev = NULL; | 455 | struct nubus_dev* ndev = NULL; |
@@ -562,7 +562,7 @@ static int __init mac_nubus_sonic_probe(struct net_device *dev) | |||
562 | return macsonic_init(dev); | 562 | return macsonic_init(dev); |
563 | } | 563 | } |
564 | 564 | ||
565 | static int __init mac_sonic_probe(struct platform_device *pdev) | 565 | static int __devinit mac_sonic_probe(struct platform_device *pdev) |
566 | { | 566 | { |
567 | struct net_device *dev; | 567 | struct net_device *dev; |
568 | struct sonic_local *lp; | 568 | struct sonic_local *lp; |
@@ -575,6 +575,7 @@ static int __init mac_sonic_probe(struct platform_device *pdev) | |||
575 | lp = netdev_priv(dev); | 575 | lp = netdev_priv(dev); |
576 | lp->device = &pdev->dev; | 576 | lp->device = &pdev->dev; |
577 | SET_NETDEV_DEV(dev, &pdev->dev); | 577 | SET_NETDEV_DEV(dev, &pdev->dev); |
578 | platform_set_drvdata(pdev, dev); | ||
578 | 579 | ||
579 | /* This will catch fatal stuff like -ENOMEM as well as success */ | 580 | /* This will catch fatal stuff like -ENOMEM as well as success */ |
580 | err = mac_onboard_sonic_probe(dev); | 581 | err = mac_onboard_sonic_probe(dev); |
diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c index 2845a0560b84..65ec77dc31f5 100644 --- a/drivers/net/mlx4/cmd.c +++ b/drivers/net/mlx4/cmd.c | |||
@@ -80,7 +80,9 @@ enum { | |||
80 | /* Bad management packet (silently discarded): */ | 80 | /* Bad management packet (silently discarded): */ |
81 | CMD_STAT_BAD_PKT = 0x30, | 81 | CMD_STAT_BAD_PKT = 0x30, |
82 | /* More outstanding CQEs in CQ than new CQ size: */ | 82 | /* More outstanding CQEs in CQ than new CQ size: */ |
83 | CMD_STAT_BAD_SIZE = 0x40 | 83 | CMD_STAT_BAD_SIZE = 0x40, |
84 | /* Multi Function device support required: */ | ||
85 | CMD_STAT_MULTI_FUNC_REQ = 0x50, | ||
84 | }; | 86 | }; |
85 | 87 | ||
86 | enum { | 88 | enum { |
@@ -128,6 +130,7 @@ static int mlx4_status_to_errno(u8 status) | |||
128 | [CMD_STAT_LAM_NOT_PRE] = -EAGAIN, | 130 | [CMD_STAT_LAM_NOT_PRE] = -EAGAIN, |
129 | [CMD_STAT_BAD_PKT] = -EINVAL, | 131 | [CMD_STAT_BAD_PKT] = -EINVAL, |
130 | [CMD_STAT_BAD_SIZE] = -ENOMEM, | 132 | [CMD_STAT_BAD_SIZE] = -ENOMEM, |
133 | [CMD_STAT_MULTI_FUNC_REQ] = -EACCES, | ||
131 | }; | 134 | }; |
132 | 135 | ||
133 | if (status >= ARRAY_SIZE(trans_table) || | 136 | if (status >= ARRAY_SIZE(trans_table) || |
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index 091f99052c91..86467b444ac6 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c | |||
@@ -220,7 +220,7 @@ static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
220 | { | 220 | { |
221 | cmd->autoneg = AUTONEG_DISABLE; | 221 | cmd->autoneg = AUTONEG_DISABLE; |
222 | cmd->supported = SUPPORTED_10000baseT_Full; | 222 | cmd->supported = SUPPORTED_10000baseT_Full; |
223 | cmd->advertising = SUPPORTED_10000baseT_Full; | 223 | cmd->advertising = ADVERTISED_1000baseT_Full; |
224 | if (netif_carrier_ok(dev)) { | 224 | if (netif_carrier_ok(dev)) { |
225 | cmd->speed = SPEED_10000; | 225 | cmd->speed = SPEED_10000; |
226 | cmd->duplex = DUPLEX_FULL; | 226 | cmd->duplex = DUPLEX_FULL; |
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 018348c01193..dac621b1e9fc 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c | |||
@@ -729,7 +729,10 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
729 | 729 | ||
730 | err = mlx4_QUERY_FW(dev); | 730 | err = mlx4_QUERY_FW(dev); |
731 | if (err) { | 731 | if (err) { |
732 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | 732 | if (err == -EACCES) |
733 | mlx4_info(dev, "non-primary physical function, skipping.\n"); | ||
734 | else | ||
735 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | ||
733 | return err; | 736 | return err; |
734 | } | 737 | } |
735 | 738 | ||
@@ -1285,6 +1288,7 @@ static struct pci_device_id mlx4_pci_table[] = { | |||
1285 | { PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ | 1288 | { PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon" EN 10GigE PCIe gen2 */ |
1286 | { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ | 1289 | { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ |
1287 | { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ | 1290 | { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ |
1291 | { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ | ||
1288 | { 0, } | 1292 | { 0, } |
1289 | }; | 1293 | }; |
1290 | 1294 | ||
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index e1cdba752e09..f86e05047d19 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -210,6 +210,7 @@ | |||
210 | #define NETXEN_CTX_SIGNATURE 0xdee0 | 210 | #define NETXEN_CTX_SIGNATURE 0xdee0 |
211 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 | 211 | #define NETXEN_CTX_SIGNATURE_V2 0x0002dee0 |
212 | #define NETXEN_CTX_RESET 0xbad0 | 212 | #define NETXEN_CTX_RESET 0xbad0 |
213 | #define NETXEN_CTX_D3_RESET 0xacc0 | ||
213 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) | 214 | #define NETXEN_RCV_PRODUCER(ringid) (ringid) |
214 | 215 | ||
215 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 | 216 | #define PHAN_PEG_RCV_INITIALIZED 0xff01 |
@@ -773,6 +774,8 @@ struct nx_host_tx_ring { | |||
773 | u32 crb_cmd_consumer; | 774 | u32 crb_cmd_consumer; |
774 | u32 num_desc; | 775 | u32 num_desc; |
775 | 776 | ||
777 | struct netdev_queue *txq; | ||
778 | |||
776 | struct netxen_cmd_buffer *cmd_buf_arr; | 779 | struct netxen_cmd_buffer *cmd_buf_arr; |
777 | struct cmd_desc_type0 *desc_head; | 780 | struct cmd_desc_type0 *desc_head; |
778 | dma_addr_t phys_addr; | 781 | dma_addr_t phys_addr; |
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index 4754f5cffad0..9f8ae4719e2f 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c | |||
@@ -684,10 +684,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) | |||
684 | goto err_out_free; | 684 | goto err_out_free; |
685 | } else { | 685 | } else { |
686 | err = netxen_init_old_ctx(adapter); | 686 | err = netxen_init_old_ctx(adapter); |
687 | if (err) { | 687 | if (err) |
688 | netxen_free_hw_resources(adapter); | 688 | goto err_out_free; |
689 | return err; | ||
690 | } | ||
691 | } | 689 | } |
692 | 690 | ||
693 | return 0; | 691 | return 0; |
@@ -708,15 +706,18 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) | |||
708 | int port = adapter->portnum; | 706 | int port = adapter->portnum; |
709 | 707 | ||
710 | if (adapter->fw_major >= 4) { | 708 | if (adapter->fw_major >= 4) { |
711 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
712 | nx_fw_cmd_destroy_rx_ctx(adapter); | 709 | nx_fw_cmd_destroy_rx_ctx(adapter); |
710 | nx_fw_cmd_destroy_tx_ctx(adapter); | ||
713 | } else { | 711 | } else { |
714 | netxen_api_lock(adapter); | 712 | netxen_api_lock(adapter); |
715 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), | 713 | NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port), |
716 | NETXEN_CTX_RESET | port); | 714 | NETXEN_CTX_D3_RESET | port); |
717 | netxen_api_unlock(adapter); | 715 | netxen_api_unlock(adapter); |
718 | } | 716 | } |
719 | 717 | ||
718 | /* Allow dma queues to drain after context reset */ | ||
719 | msleep(20); | ||
720 | |||
720 | recv_ctx = &adapter->recv_ctx; | 721 | recv_ctx = &adapter->recv_ctx; |
721 | 722 | ||
722 | if (recv_ctx->hwctx != NULL) { | 723 | if (recv_ctx->hwctx != NULL) { |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index ce3b89d2cbb6..b9123d445c96 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -461,13 +461,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
461 | i = 0; | 461 | i = 0; |
462 | 462 | ||
463 | tx_ring = adapter->tx_ring; | 463 | tx_ring = adapter->tx_ring; |
464 | netif_tx_lock_bh(adapter->netdev); | 464 | __netif_tx_lock_bh(tx_ring->txq); |
465 | 465 | ||
466 | producer = tx_ring->producer; | 466 | producer = tx_ring->producer; |
467 | consumer = tx_ring->sw_consumer; | 467 | consumer = tx_ring->sw_consumer; |
468 | 468 | ||
469 | if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) { | 469 | if (nr_desc >= netxen_tx_avail(tx_ring)) { |
470 | netif_tx_unlock_bh(adapter->netdev); | 470 | netif_tx_stop_queue(tx_ring->txq); |
471 | __netif_tx_unlock_bh(tx_ring->txq); | ||
471 | return -EBUSY; | 472 | return -EBUSY; |
472 | } | 473 | } |
473 | 474 | ||
@@ -490,7 +491,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, | |||
490 | 491 | ||
491 | netxen_nic_update_cmd_producer(adapter, tx_ring); | 492 | netxen_nic_update_cmd_producer(adapter, tx_ring); |
492 | 493 | ||
493 | netif_tx_unlock_bh(adapter->netdev); | 494 | __netif_tx_unlock_bh(tx_ring->txq); |
494 | 495 | ||
495 | return 0; | 496 | return 0; |
496 | } | 497 | } |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index b899bd51fcd8..5d3343ef3d86 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -214,6 +214,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) | |||
214 | adapter->tx_ring = tx_ring; | 214 | adapter->tx_ring = tx_ring; |
215 | 215 | ||
216 | tx_ring->num_desc = adapter->num_txd; | 216 | tx_ring->num_desc = adapter->num_txd; |
217 | tx_ring->txq = netdev_get_tx_queue(netdev, 0); | ||
217 | 218 | ||
218 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); | 219 | cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring)); |
219 | if (cmd_buf_arr == NULL) { | 220 | if (cmd_buf_arr == NULL) { |
@@ -1400,10 +1401,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) | |||
1400 | smp_mb(); | 1401 | smp_mb(); |
1401 | 1402 | ||
1402 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { | 1403 | if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { |
1403 | netif_tx_lock(netdev); | 1404 | __netif_tx_lock(tx_ring->txq, smp_processor_id()); |
1404 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) | 1405 | if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) |
1405 | netif_wake_queue(netdev); | 1406 | netif_wake_queue(netdev); |
1406 | netif_tx_unlock(netdev); | 1407 | __netif_tx_unlock(tx_ring->txq); |
1407 | } | 1408 | } |
1408 | } | 1409 | } |
1409 | /* | 1410 | /* |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 27539ddf94c4..637ac8b89bac 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -215,9 +215,9 @@ netxen_napi_disable(struct netxen_adapter *adapter) | |||
215 | 215 | ||
216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
217 | sds_ring = &recv_ctx->sds_rings[ring]; | 217 | sds_ring = &recv_ctx->sds_rings[ring]; |
218 | napi_disable(&sds_ring->napi); | ||
219 | netxen_nic_disable_int(sds_ring); | 218 | netxen_nic_disable_int(sds_ring); |
220 | synchronize_irq(sds_ring->irq); | 219 | napi_synchronize(&sds_ring->napi); |
220 | napi_disable(&sds_ring->napi); | ||
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
@@ -833,11 +833,11 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
833 | 833 | ||
834 | adapter->ahw.linkup = 0; | 834 | adapter->ahw.linkup = 0; |
835 | 835 | ||
836 | netxen_napi_enable(adapter); | ||
837 | |||
838 | if (adapter->max_sds_rings > 1) | 836 | if (adapter->max_sds_rings > 1) |
839 | netxen_config_rss(adapter, 1); | 837 | netxen_config_rss(adapter, 1); |
840 | 838 | ||
839 | netxen_napi_enable(adapter); | ||
840 | |||
841 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) | 841 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) |
842 | netxen_linkevent_request(adapter, 1); | 842 | netxen_linkevent_request(adapter, 1); |
843 | else | 843 | else |
@@ -851,8 +851,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
851 | static void | 851 | static void |
852 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | 852 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) |
853 | { | 853 | { |
854 | spin_lock(&adapter->tx_clean_lock); | ||
854 | netif_carrier_off(netdev); | 855 | netif_carrier_off(netdev); |
855 | netif_stop_queue(netdev); | 856 | netif_tx_disable(netdev); |
856 | 857 | ||
857 | if (adapter->stop_port) | 858 | if (adapter->stop_port) |
858 | adapter->stop_port(adapter); | 859 | adapter->stop_port(adapter); |
@@ -863,9 +864,10 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | |||
863 | netxen_napi_disable(adapter); | 864 | netxen_napi_disable(adapter); |
864 | 865 | ||
865 | netxen_release_tx_buffers(adapter); | 866 | netxen_release_tx_buffers(adapter); |
867 | spin_unlock(&adapter->tx_clean_lock); | ||
866 | 868 | ||
867 | FLUSH_SCHEDULED_WORK(); | ||
868 | del_timer_sync(&adapter->watchdog_timer); | 869 | del_timer_sync(&adapter->watchdog_timer); |
870 | FLUSH_SCHEDULED_WORK(); | ||
869 | } | 871 | } |
870 | 872 | ||
871 | 873 | ||
@@ -943,8 +945,8 @@ err_out_free_sw: | |||
943 | static void | 945 | static void |
944 | netxen_nic_detach(struct netxen_adapter *adapter) | 946 | netxen_nic_detach(struct netxen_adapter *adapter) |
945 | { | 947 | { |
946 | netxen_release_rx_buffers(adapter); | ||
947 | netxen_free_hw_resources(adapter); | 948 | netxen_free_hw_resources(adapter); |
949 | netxen_release_rx_buffers(adapter); | ||
948 | netxen_nic_free_irq(adapter); | 950 | netxen_nic_free_irq(adapter); |
949 | netxen_free_sw_resources(adapter); | 951 | netxen_free_sw_resources(adapter); |
950 | 952 | ||
@@ -1533,10 +1535,12 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1533 | printk(KERN_ALERT | 1535 | printk(KERN_ALERT |
1534 | "%s: Device temperature %d degrees C exceeds" | 1536 | "%s: Device temperature %d degrees C exceeds" |
1535 | " maximum allowed. Hardware has been shut down.\n", | 1537 | " maximum allowed. Hardware has been shut down.\n", |
1536 | netxen_nic_driver_name, temp_val); | 1538 | netdev->name, temp_val); |
1539 | |||
1540 | netif_device_detach(netdev); | ||
1541 | netxen_nic_down(adapter, netdev); | ||
1542 | netxen_nic_detach(adapter); | ||
1537 | 1543 | ||
1538 | netif_carrier_off(netdev); | ||
1539 | netif_stop_queue(netdev); | ||
1540 | rv = 1; | 1544 | rv = 1; |
1541 | } else if (temp_state == NX_TEMP_WARN) { | 1545 | } else if (temp_state == NX_TEMP_WARN) { |
1542 | if (adapter->temp == NX_TEMP_NORMAL) { | 1546 | if (adapter->temp == NX_TEMP_NORMAL) { |
@@ -1544,13 +1548,13 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1544 | "%s: Device temperature %d degrees C " | 1548 | "%s: Device temperature %d degrees C " |
1545 | "exceeds operating range." | 1549 | "exceeds operating range." |
1546 | " Immediate action needed.\n", | 1550 | " Immediate action needed.\n", |
1547 | netxen_nic_driver_name, temp_val); | 1551 | netdev->name, temp_val); |
1548 | } | 1552 | } |
1549 | } else { | 1553 | } else { |
1550 | if (adapter->temp == NX_TEMP_WARN) { | 1554 | if (adapter->temp == NX_TEMP_WARN) { |
1551 | printk(KERN_INFO | 1555 | printk(KERN_INFO |
1552 | "%s: Device temperature is now %d degrees C" | 1556 | "%s: Device temperature is now %d degrees C" |
1553 | " in normal range.\n", netxen_nic_driver_name, | 1557 | " in normal range.\n", netdev->name, |
1554 | temp_val); | 1558 | temp_val); |
1555 | } | 1559 | } |
1556 | } | 1560 | } |
@@ -1623,7 +1627,7 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1623 | struct netxen_adapter *adapter = | 1627 | struct netxen_adapter *adapter = |
1624 | container_of(work, struct netxen_adapter, watchdog_task); | 1628 | container_of(work, struct netxen_adapter, watchdog_task); |
1625 | 1629 | ||
1626 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | 1630 | if (netxen_nic_check_temp(adapter)) |
1627 | return; | 1631 | return; |
1628 | 1632 | ||
1629 | if (!adapter->has_link_events) | 1633 | if (!adapter->has_link_events) |
@@ -1645,6 +1649,9 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1645 | struct netxen_adapter *adapter = | 1649 | struct netxen_adapter *adapter = |
1646 | container_of(work, struct netxen_adapter, tx_timeout_task); | 1650 | container_of(work, struct netxen_adapter, tx_timeout_task); |
1647 | 1651 | ||
1652 | if (!netif_running(adapter->netdev)) | ||
1653 | return; | ||
1654 | |||
1648 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1655 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1649 | netxen_nic_driver_name, adapter->netdev->name); | 1656 | netxen_nic_driver_name, adapter->netdev->name); |
1650 | 1657 | ||
@@ -1757,7 +1764,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
1757 | 1764 | ||
1758 | if ((work_done < budget) && tx_complete) { | 1765 | if ((work_done < budget) && tx_complete) { |
1759 | napi_complete(&sds_ring->napi); | 1766 | napi_complete(&sds_ring->napi); |
1760 | netxen_nic_enable_int(sds_ring); | 1767 | if (netif_running(adapter->netdev)) |
1768 | netxen_nic_enable_int(sds_ring); | ||
1761 | } | 1769 | } |
1762 | 1770 | ||
1763 | return work_done; | 1771 | return work_done; |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index ec7cf5ac4f05..690b9c76d34e 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -156,6 +156,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev); | |||
156 | static int el3_rx(struct net_device *dev); | 156 | static int el3_rx(struct net_device *dev); |
157 | static int el3_close(struct net_device *dev); | 157 | static int el3_close(struct net_device *dev); |
158 | static void el3_tx_timeout(struct net_device *dev); | 158 | static void el3_tx_timeout(struct net_device *dev); |
159 | static void set_rx_mode(struct net_device *dev); | ||
159 | static void set_multicast_list(struct net_device *dev); | 160 | static void set_multicast_list(struct net_device *dev); |
160 | static const struct ethtool_ops netdev_ethtool_ops; | 161 | static const struct ethtool_ops netdev_ethtool_ops; |
161 | 162 | ||
@@ -488,8 +489,7 @@ static void tc589_reset(struct net_device *dev) | |||
488 | /* Switch to register set 1 for normal use. */ | 489 | /* Switch to register set 1 for normal use. */ |
489 | EL3WINDOW(1); | 490 | EL3WINDOW(1); |
490 | 491 | ||
491 | /* Accept b-cast and phys addr only. */ | 492 | set_rx_mode(dev); |
492 | outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); | ||
493 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ | 493 | outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ |
494 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ | 494 | outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ |
495 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ | 495 | outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ |
@@ -700,7 +700,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) | |||
700 | if (fifo_diag & 0x2000) { | 700 | if (fifo_diag & 0x2000) { |
701 | /* Rx underrun */ | 701 | /* Rx underrun */ |
702 | tc589_wait_for_completion(dev, RxReset); | 702 | tc589_wait_for_completion(dev, RxReset); |
703 | set_multicast_list(dev); | 703 | set_rx_mode(dev); |
704 | outw(RxEnable, ioaddr + EL3_CMD); | 704 | outw(RxEnable, ioaddr + EL3_CMD); |
705 | } | 705 | } |
706 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); | 706 | outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); |
@@ -905,14 +905,11 @@ static int el3_rx(struct net_device *dev) | |||
905 | return 0; | 905 | return 0; |
906 | } | 906 | } |
907 | 907 | ||
908 | static void set_multicast_list(struct net_device *dev) | 908 | static void set_rx_mode(struct net_device *dev) |
909 | { | 909 | { |
910 | struct el3_private *lp = netdev_priv(dev); | ||
911 | struct pcmcia_device *link = lp->p_dev; | ||
912 | unsigned int ioaddr = dev->base_addr; | 910 | unsigned int ioaddr = dev->base_addr; |
913 | u16 opts = SetRxFilter | RxStation | RxBroadcast; | 911 | u16 opts = SetRxFilter | RxStation | RxBroadcast; |
914 | 912 | ||
915 | if (!pcmcia_dev_present(link)) return; | ||
916 | if (dev->flags & IFF_PROMISC) | 913 | if (dev->flags & IFF_PROMISC) |
917 | opts |= RxMulticast | RxProm; | 914 | opts |= RxMulticast | RxProm; |
918 | else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) | 915 | else if (dev->mc_count || (dev->flags & IFF_ALLMULTI)) |
@@ -920,6 +917,16 @@ static void set_multicast_list(struct net_device *dev) | |||
920 | outw(opts, ioaddr + EL3_CMD); | 917 | outw(opts, ioaddr + EL3_CMD); |
921 | } | 918 | } |
922 | 919 | ||
920 | static void set_multicast_list(struct net_device *dev) | ||
921 | { | ||
922 | struct el3_private *priv = netdev_priv(dev); | ||
923 | unsigned long flags; | ||
924 | |||
925 | spin_lock_irqsave(&priv->lock, flags); | ||
926 | set_rx_mode(dev); | ||
927 | spin_unlock_irqrestore(&priv->lock, flags); | ||
928 | } | ||
929 | |||
923 | static int el3_close(struct net_device *dev) | 930 | static int el3_close(struct net_device *dev) |
924 | { | 931 | { |
925 | struct el3_private *lp = netdev_priv(dev); | 932 | struct el3_private *lp = netdev_priv(dev); |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index eba937c46376..b10fedd82143 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -134,8 +134,10 @@ int phy_scan_fixups(struct phy_device *phydev) | |||
134 | 134 | ||
135 | err = fixup->run(phydev); | 135 | err = fixup->run(phydev); |
136 | 136 | ||
137 | if (err < 0) | 137 | if (err < 0) { |
138 | mutex_unlock(&phy_fixup_lock); | ||
138 | return err; | 139 | return err; |
140 | } | ||
139 | } | 141 | } |
140 | } | 142 | } |
141 | mutex_unlock(&phy_fixup_lock); | 143 | mutex_unlock(&phy_fixup_lock); |
diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 7a62f781fef2..2ca8b0d84ee2 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c | |||
@@ -270,6 +270,9 @@ static const struct net_device_ops plip_netdev_ops = { | |||
270 | .ndo_stop = plip_close, | 270 | .ndo_stop = plip_close, |
271 | .ndo_start_xmit = plip_tx_packet, | 271 | .ndo_start_xmit = plip_tx_packet, |
272 | .ndo_do_ioctl = plip_ioctl, | 272 | .ndo_do_ioctl = plip_ioctl, |
273 | .ndo_change_mtu = eth_change_mtu, | ||
274 | .ndo_set_mac_address = eth_mac_addr, | ||
275 | .ndo_validate_addr = eth_validate_addr, | ||
273 | }; | 276 | }; |
274 | 277 | ||
275 | /* Entry point of PLIP driver. | 278 | /* Entry point of PLIP driver. |
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 17c116bb332c..6de8399d6dd9 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c | |||
@@ -356,6 +356,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
356 | if (!skb_queue_empty(&ap->rqueue)) | 356 | if (!skb_queue_empty(&ap->rqueue)) |
357 | tasklet_schedule(&ap->tsk); | 357 | tasklet_schedule(&ap->tsk); |
358 | ap_put(ap); | 358 | ap_put(ap); |
359 | tty_unthrottle(tty); | ||
359 | } | 360 | } |
360 | 361 | ||
361 | static void | 362 | static void |
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index aa3d39f38e22..d2fa2db13586 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c | |||
@@ -397,6 +397,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, | |||
397 | if (!skb_queue_empty(&ap->rqueue)) | 397 | if (!skb_queue_empty(&ap->rqueue)) |
398 | tasklet_schedule(&ap->tsk); | 398 | tasklet_schedule(&ap->tsk); |
399 | sp_put(ap); | 399 | sp_put(ap); |
400 | tty_unthrottle(tty); | ||
400 | } | 401 | } |
401 | 402 | ||
402 | static void | 403 | static void |
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index d1a5fb4d6acb..a3932c9f3406 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c | |||
@@ -1411,6 +1411,7 @@ static const struct net_device_ops gelic_netdevice_ops = { | |||
1411 | .ndo_set_multicast_list = gelic_net_set_multi, | 1411 | .ndo_set_multicast_list = gelic_net_set_multi, |
1412 | .ndo_change_mtu = gelic_net_change_mtu, | 1412 | .ndo_change_mtu = gelic_net_change_mtu, |
1413 | .ndo_tx_timeout = gelic_net_tx_timeout, | 1413 | .ndo_tx_timeout = gelic_net_tx_timeout, |
1414 | .ndo_set_mac_address = eth_mac_addr, | ||
1414 | .ndo_validate_addr = eth_validate_addr, | 1415 | .ndo_validate_addr = eth_validate_addr, |
1415 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1416 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1416 | .ndo_poll_controller = gelic_net_poll_controller, | 1417 | .ndo_poll_controller = gelic_net_poll_controller, |
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index b6b3ca9bdb21..6932b08d746b 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c | |||
@@ -2707,6 +2707,7 @@ static const struct net_device_ops gelic_wl_netdevice_ops = { | |||
2707 | .ndo_set_multicast_list = gelic_net_set_multi, | 2707 | .ndo_set_multicast_list = gelic_net_set_multi, |
2708 | .ndo_change_mtu = gelic_net_change_mtu, | 2708 | .ndo_change_mtu = gelic_net_change_mtu, |
2709 | .ndo_tx_timeout = gelic_net_tx_timeout, | 2709 | .ndo_tx_timeout = gelic_net_tx_timeout, |
2710 | .ndo_set_mac_address = eth_mac_addr, | ||
2710 | .ndo_validate_addr = eth_validate_addr, | 2711 | .ndo_validate_addr = eth_validate_addr, |
2711 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2712 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2712 | .ndo_poll_controller = gelic_net_poll_controller, | 2713 | .ndo_poll_controller = gelic_net_poll_controller, |
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 18821f217e19..e3156c97bb58 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c | |||
@@ -1593,6 +1593,7 @@ out: | |||
1593 | static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = { | 1593 | static struct pci_device_id sc92031_pci_device_id_table[] __devinitdata = { |
1594 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) }, | 1594 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x2031) }, |
1595 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) }, | 1595 | { PCI_DEVICE(PCI_VENDOR_ID_SILAN, 0x8139) }, |
1596 | { PCI_DEVICE(0x1088, 0x2031) }, | ||
1596 | { 0, } | 1597 | { 0, } |
1597 | }; | 1598 | }; |
1598 | MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table); | 1599 | MODULE_DEVICE_TABLE(pci, sc92031_pci_device_id_table); |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index daf961ab68bc..3550c5dcd93c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1151,14 +1151,7 @@ stopped: | |||
1151 | 1151 | ||
1152 | /* reset the Rx prefetch unit */ | 1152 | /* reset the Rx prefetch unit */ |
1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); | 1153 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); |
1154 | 1154 | mmiowb(); | |
1155 | /* Reset the RAM Buffer receive queue */ | ||
1156 | sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_RST_SET); | ||
1157 | |||
1158 | /* Reset Rx MAC FIFO */ | ||
1159 | sky2_write8(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), GMF_RST_SET); | ||
1160 | |||
1161 | sky2_read8(hw, B0_CTST); | ||
1162 | } | 1155 | } |
1163 | 1156 | ||
1164 | /* Clean out receive buffer area, assumes receiver hardware stopped */ | 1157 | /* Clean out receive buffer area, assumes receiver hardware stopped */ |
@@ -1825,12 +1818,6 @@ static int sky2_down(struct net_device *dev) | |||
1825 | if (netif_msg_ifdown(sky2)) | 1818 | if (netif_msg_ifdown(sky2)) |
1826 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 1819 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
1827 | 1820 | ||
1828 | /* Disable port IRQ */ | ||
1829 | imask = sky2_read32(hw, B0_IMSK); | ||
1830 | imask &= ~portirq_msk[port]; | ||
1831 | sky2_write32(hw, B0_IMSK, imask); | ||
1832 | sky2_read32(hw, B0_IMSK); | ||
1833 | |||
1834 | /* Force flow control off */ | 1821 | /* Force flow control off */ |
1835 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); | 1822 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); |
1836 | 1823 | ||
@@ -1870,8 +1857,6 @@ static int sky2_down(struct net_device *dev) | |||
1870 | 1857 | ||
1871 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); | 1858 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); |
1872 | 1859 | ||
1873 | sky2_rx_stop(sky2); | ||
1874 | |||
1875 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1860 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1876 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1861 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1877 | 1862 | ||
@@ -1881,6 +1866,14 @@ static int sky2_down(struct net_device *dev) | |||
1881 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); | 1866 | sky2_write32(hw, STAT_ISR_TIMER_CNT, 0); |
1882 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); | 1867 | sky2_read8(hw, STAT_ISR_TIMER_CTRL); |
1883 | 1868 | ||
1869 | sky2_rx_stop(sky2); | ||
1870 | |||
1871 | /* Disable port IRQ */ | ||
1872 | imask = sky2_read32(hw, B0_IMSK); | ||
1873 | imask &= ~portirq_msk[port]; | ||
1874 | sky2_write32(hw, B0_IMSK, imask); | ||
1875 | sky2_read32(hw, B0_IMSK); | ||
1876 | |||
1884 | synchronize_irq(hw->pdev->irq); | 1877 | synchronize_irq(hw->pdev->irq); |
1885 | napi_synchronize(&hw->napi); | 1878 | napi_synchronize(&hw->napi); |
1886 | 1879 | ||
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index fdcbaf8dfa73..1c70e999cc50 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1774,6 +1774,7 @@ static const struct net_device_ops smc_netdev_ops = { | |||
1774 | .ndo_start_xmit = smc_hard_start_xmit, | 1774 | .ndo_start_xmit = smc_hard_start_xmit, |
1775 | .ndo_tx_timeout = smc_timeout, | 1775 | .ndo_tx_timeout = smc_timeout, |
1776 | .ndo_set_multicast_list = smc_set_multicast_list, | 1776 | .ndo_set_multicast_list = smc_set_multicast_list, |
1777 | .ndo_change_mtu = eth_change_mtu, | ||
1777 | .ndo_validate_addr = eth_validate_addr, | 1778 | .ndo_validate_addr = eth_validate_addr, |
1778 | .ndo_set_mac_address = eth_mac_addr, | 1779 | .ndo_set_mac_address = eth_mac_addr, |
1779 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1780 | #ifdef CONFIG_NET_POLL_CONTROLLER |
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 66067f9d91c0..94b6d2658ddc 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c | |||
@@ -1779,6 +1779,7 @@ static const struct net_device_ops smsc911x_netdev_ops = { | |||
1779 | .ndo_get_stats = smsc911x_get_stats, | 1779 | .ndo_get_stats = smsc911x_get_stats, |
1780 | .ndo_set_multicast_list = smsc911x_set_multicast_list, | 1780 | .ndo_set_multicast_list = smsc911x_set_multicast_list, |
1781 | .ndo_do_ioctl = smsc911x_do_ioctl, | 1781 | .ndo_do_ioctl = smsc911x_do_ioctl, |
1782 | .ndo_change_mtu = eth_change_mtu, | ||
1782 | .ndo_validate_addr = eth_validate_addr, | 1783 | .ndo_validate_addr = eth_validate_addr, |
1783 | .ndo_set_mac_address = smsc911x_set_mac_address, | 1784 | .ndo_set_mac_address = smsc911x_set_mac_address, |
1784 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1785 | #ifdef CONFIG_NET_POLL_CONTROLLER |
diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index a82fb2aca4cb..f1e5e4542c2a 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c | |||
@@ -1016,7 +1016,9 @@ static const struct net_device_ops vnet_ops = { | |||
1016 | .ndo_open = vnet_open, | 1016 | .ndo_open = vnet_open, |
1017 | .ndo_stop = vnet_close, | 1017 | .ndo_stop = vnet_close, |
1018 | .ndo_set_multicast_list = vnet_set_rx_mode, | 1018 | .ndo_set_multicast_list = vnet_set_rx_mode, |
1019 | .ndo_change_mtu = eth_change_mtu, | ||
1019 | .ndo_set_mac_address = vnet_set_mac_addr, | 1020 | .ndo_set_mac_address = vnet_set_mac_addr, |
1021 | .ndo_validate_addr = eth_validate_addr, | ||
1020 | .ndo_tx_timeout = vnet_tx_timeout, | 1022 | .ndo_tx_timeout = vnet_tx_timeout, |
1021 | .ndo_change_mtu = vnet_change_mtu, | 1023 | .ndo_change_mtu = vnet_change_mtu, |
1022 | .ndo_start_xmit = vnet_start_xmit, | 1024 | .ndo_start_xmit = vnet_start_xmit, |
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index a906d3998131..c47237c2d638 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -369,4 +369,12 @@ config USB_NET_INT51X1 | |||
369 | (Powerline Communications) solution with an Intellon | 369 | (Powerline Communications) solution with an Intellon |
370 | INT51x1/INT5200 chip, like the "devolo dLan duo". | 370 | INT51x1/INT5200 chip, like the "devolo dLan duo". |
371 | 371 | ||
372 | config USB_CDC_PHONET | ||
373 | tristate "CDC Phonet support" | ||
374 | depends on PHONET | ||
375 | help | ||
376 | Choose this option to support the Phonet interface to a Nokia | ||
377 | cellular modem, as found on most Nokia handsets with the | ||
378 | "PC suite" USB profile. | ||
379 | |||
372 | endmenu | 380 | endmenu |
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b870b0b1cbe0..e17afb78f372 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile | |||
@@ -21,4 +21,5 @@ obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o | |||
21 | obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o | 21 | obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o |
22 | obj-$(CONFIG_USB_USBNET) += usbnet.o | 22 | obj-$(CONFIG_USB_USBNET) += usbnet.o |
23 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o | 23 | obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o |
24 | obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o | ||
24 | 25 | ||
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c new file mode 100644 index 000000000000..792af72da8ac --- /dev/null +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -0,0 +1,461 @@ | |||
1 | /* | ||
2 | * phonet.c -- USB CDC Phonet host driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved. | ||
5 | * | ||
6 | * Author: Rémi Denis-Courmont | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Â See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/usb.h> | ||
26 | #include <linux/usb/cdc.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/if_arp.h> | ||
29 | #include <linux/if_phonet.h> | ||
30 | |||
31 | #define PN_MEDIA_USB 0x1B | ||
32 | |||
33 | static const unsigned rxq_size = 17; | ||
34 | |||
35 | struct usbpn_dev { | ||
36 | struct net_device *dev; | ||
37 | |||
38 | struct usb_interface *intf, *data_intf; | ||
39 | struct usb_device *usb; | ||
40 | unsigned int tx_pipe, rx_pipe; | ||
41 | u8 active_setting; | ||
42 | u8 disconnected; | ||
43 | |||
44 | unsigned tx_queue; | ||
45 | spinlock_t tx_lock; | ||
46 | |||
47 | spinlock_t rx_lock; | ||
48 | struct sk_buff *rx_skb; | ||
49 | struct urb *urbs[0]; | ||
50 | }; | ||
51 | |||
52 | static void tx_complete(struct urb *req); | ||
53 | static void rx_complete(struct urb *req); | ||
54 | |||
55 | /* | ||
56 | * Network device callbacks | ||
57 | */ | ||
58 | static int usbpn_xmit(struct sk_buff *skb, struct net_device *dev) | ||
59 | { | ||
60 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
61 | struct urb *req = NULL; | ||
62 | unsigned long flags; | ||
63 | int err; | ||
64 | |||
65 | if (skb->protocol != htons(ETH_P_PHONET)) | ||
66 | goto drop; | ||
67 | |||
68 | req = usb_alloc_urb(0, GFP_ATOMIC); | ||
69 | if (!req) | ||
70 | goto drop; | ||
71 | usb_fill_bulk_urb(req, pnd->usb, pnd->tx_pipe, skb->data, skb->len, | ||
72 | tx_complete, skb); | ||
73 | req->transfer_flags = URB_ZERO_PACKET; | ||
74 | err = usb_submit_urb(req, GFP_ATOMIC); | ||
75 | if (err) { | ||
76 | usb_free_urb(req); | ||
77 | goto drop; | ||
78 | } | ||
79 | |||
80 | spin_lock_irqsave(&pnd->tx_lock, flags); | ||
81 | pnd->tx_queue++; | ||
82 | if (pnd->tx_queue >= dev->tx_queue_len) | ||
83 | netif_stop_queue(dev); | ||
84 | spin_unlock_irqrestore(&pnd->tx_lock, flags); | ||
85 | return 0; | ||
86 | |||
87 | drop: | ||
88 | dev_kfree_skb(skb); | ||
89 | dev->stats.tx_dropped++; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static void tx_complete(struct urb *req) | ||
94 | { | ||
95 | struct sk_buff *skb = req->context; | ||
96 | struct net_device *dev = skb->dev; | ||
97 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
98 | |||
99 | switch (req->status) { | ||
100 | case 0: | ||
101 | dev->stats.tx_bytes += skb->len; | ||
102 | break; | ||
103 | |||
104 | case -ENOENT: | ||
105 | case -ECONNRESET: | ||
106 | case -ESHUTDOWN: | ||
107 | dev->stats.tx_aborted_errors++; | ||
108 | default: | ||
109 | dev->stats.tx_errors++; | ||
110 | dev_dbg(&dev->dev, "TX error (%d)\n", req->status); | ||
111 | } | ||
112 | dev->stats.tx_packets++; | ||
113 | |||
114 | spin_lock(&pnd->tx_lock); | ||
115 | pnd->tx_queue--; | ||
116 | netif_wake_queue(dev); | ||
117 | spin_unlock(&pnd->tx_lock); | ||
118 | |||
119 | dev_kfree_skb_any(skb); | ||
120 | usb_free_urb(req); | ||
121 | } | ||
122 | |||
123 | static int rx_submit(struct usbpn_dev *pnd, struct urb *req, gfp_t gfp_flags) | ||
124 | { | ||
125 | struct net_device *dev = pnd->dev; | ||
126 | struct page *page; | ||
127 | int err; | ||
128 | |||
129 | page = __netdev_alloc_page(dev, gfp_flags); | ||
130 | if (!page) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | usb_fill_bulk_urb(req, pnd->usb, pnd->rx_pipe, page_address(page), | ||
134 | PAGE_SIZE, rx_complete, dev); | ||
135 | req->transfer_flags = 0; | ||
136 | err = usb_submit_urb(req, gfp_flags); | ||
137 | if (unlikely(err)) { | ||
138 | dev_dbg(&dev->dev, "RX submit error (%d)\n", err); | ||
139 | netdev_free_page(dev, page); | ||
140 | } | ||
141 | return err; | ||
142 | } | ||
143 | |||
144 | static void rx_complete(struct urb *req) | ||
145 | { | ||
146 | struct net_device *dev = req->context; | ||
147 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
148 | struct page *page = virt_to_page(req->transfer_buffer); | ||
149 | struct sk_buff *skb; | ||
150 | unsigned long flags; | ||
151 | |||
152 | switch (req->status) { | ||
153 | case 0: | ||
154 | spin_lock_irqsave(&pnd->rx_lock, flags); | ||
155 | skb = pnd->rx_skb; | ||
156 | if (!skb) { | ||
157 | skb = pnd->rx_skb = netdev_alloc_skb(dev, 12); | ||
158 | if (likely(skb)) { | ||
159 | /* Can't use pskb_pull() on page in IRQ */ | ||
160 | memcpy(skb_put(skb, 1), page_address(page), 1); | ||
161 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | ||
162 | page, 1, req->actual_length); | ||
163 | page = NULL; | ||
164 | } | ||
165 | } else { | ||
166 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | ||
167 | page, 0, req->actual_length); | ||
168 | page = NULL; | ||
169 | } | ||
170 | if (req->actual_length < PAGE_SIZE) | ||
171 | pnd->rx_skb = NULL; /* Last fragment */ | ||
172 | else | ||
173 | skb = NULL; | ||
174 | spin_unlock_irqrestore(&pnd->rx_lock, flags); | ||
175 | if (skb) { | ||
176 | skb->protocol = htons(ETH_P_PHONET); | ||
177 | skb_reset_mac_header(skb); | ||
178 | __skb_pull(skb, 1); | ||
179 | skb->dev = dev; | ||
180 | dev->stats.rx_packets++; | ||
181 | dev->stats.rx_bytes += skb->len; | ||
182 | |||
183 | netif_rx(skb); | ||
184 | } | ||
185 | goto resubmit; | ||
186 | |||
187 | case -ENOENT: | ||
188 | case -ECONNRESET: | ||
189 | case -ESHUTDOWN: | ||
190 | req = NULL; | ||
191 | break; | ||
192 | |||
193 | case -EOVERFLOW: | ||
194 | dev->stats.rx_over_errors++; | ||
195 | dev_dbg(&dev->dev, "RX overflow\n"); | ||
196 | break; | ||
197 | |||
198 | case -EILSEQ: | ||
199 | dev->stats.rx_crc_errors++; | ||
200 | break; | ||
201 | } | ||
202 | |||
203 | dev->stats.rx_errors++; | ||
204 | resubmit: | ||
205 | if (page) | ||
206 | netdev_free_page(dev, page); | ||
207 | if (req) | ||
208 | rx_submit(pnd, req, GFP_ATOMIC); | ||
209 | } | ||
210 | |||
211 | static int usbpn_close(struct net_device *dev); | ||
212 | |||
213 | static int usbpn_open(struct net_device *dev) | ||
214 | { | ||
215 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
216 | int err; | ||
217 | unsigned i; | ||
218 | unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; | ||
219 | |||
220 | err = usb_set_interface(pnd->usb, num, pnd->active_setting); | ||
221 | if (err) | ||
222 | return err; | ||
223 | |||
224 | for (i = 0; i < rxq_size; i++) { | ||
225 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); | ||
226 | |||
227 | if (!req || rx_submit(pnd, req, GFP_KERNEL)) { | ||
228 | usbpn_close(dev); | ||
229 | return -ENOMEM; | ||
230 | } | ||
231 | pnd->urbs[i] = req; | ||
232 | } | ||
233 | |||
234 | netif_wake_queue(dev); | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static int usbpn_close(struct net_device *dev) | ||
239 | { | ||
240 | struct usbpn_dev *pnd = netdev_priv(dev); | ||
241 | unsigned i; | ||
242 | unsigned num = pnd->data_intf->cur_altsetting->desc.bInterfaceNumber; | ||
243 | |||
244 | netif_stop_queue(dev); | ||
245 | |||
246 | for (i = 0; i < rxq_size; i++) { | ||
247 | struct urb *req = pnd->urbs[i]; | ||
248 | |||
249 | if (!req) | ||
250 | continue; | ||
251 | usb_kill_urb(req); | ||
252 | usb_free_urb(req); | ||
253 | pnd->urbs[i] = NULL; | ||
254 | } | ||
255 | |||
256 | return usb_set_interface(pnd->usb, num, !pnd->active_setting); | ||
257 | } | ||
258 | |||
259 | static int usbpn_set_mtu(struct net_device *dev, int new_mtu) | ||
260 | { | ||
261 | if ((new_mtu < PHONET_MIN_MTU) || (new_mtu > PHONET_MAX_MTU)) | ||
262 | return -EINVAL; | ||
263 | |||
264 | dev->mtu = new_mtu; | ||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static const struct net_device_ops usbpn_ops = { | ||
269 | .ndo_open = usbpn_open, | ||
270 | .ndo_stop = usbpn_close, | ||
271 | .ndo_start_xmit = usbpn_xmit, | ||
272 | .ndo_change_mtu = usbpn_set_mtu, | ||
273 | }; | ||
274 | |||
275 | static void usbpn_setup(struct net_device *dev) | ||
276 | { | ||
277 | dev->features = 0; | ||
278 | dev->netdev_ops = &usbpn_ops, | ||
279 | dev->header_ops = &phonet_header_ops; | ||
280 | dev->type = ARPHRD_PHONET; | ||
281 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; | ||
282 | dev->mtu = PHONET_MAX_MTU; | ||
283 | dev->hard_header_len = 1; | ||
284 | dev->dev_addr[0] = PN_MEDIA_USB; | ||
285 | dev->addr_len = 1; | ||
286 | dev->tx_queue_len = 3; | ||
287 | |||
288 | dev->destructor = free_netdev; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * USB driver callbacks | ||
293 | */ | ||
294 | static struct usb_device_id usbpn_ids[] = { | ||
295 | { | ||
296 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | ||
297 | | USB_DEVICE_ID_MATCH_INT_CLASS | ||
298 | | USB_DEVICE_ID_MATCH_INT_SUBCLASS, | ||
299 | .idVendor = 0x0421, /* Nokia */ | ||
300 | .bInterfaceClass = USB_CLASS_COMM, | ||
301 | .bInterfaceSubClass = 0xFE, | ||
302 | }, | ||
303 | { }, | ||
304 | }; | ||
305 | |||
306 | MODULE_DEVICE_TABLE(usb, usbpn_ids); | ||
307 | |||
308 | static struct usb_driver usbpn_driver; | ||
309 | |||
310 | int usbpn_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
311 | { | ||
312 | static const char ifname[] = "usbpn%d"; | ||
313 | const struct usb_cdc_union_desc *union_header = NULL; | ||
314 | const struct usb_cdc_header_desc *phonet_header = NULL; | ||
315 | const struct usb_host_interface *data_desc; | ||
316 | struct usb_interface *data_intf; | ||
317 | struct usb_device *usbdev = interface_to_usbdev(intf); | ||
318 | struct net_device *dev; | ||
319 | struct usbpn_dev *pnd; | ||
320 | u8 *data; | ||
321 | int len, err; | ||
322 | |||
323 | data = intf->altsetting->extra; | ||
324 | len = intf->altsetting->extralen; | ||
325 | while (len >= 3) { | ||
326 | u8 dlen = data[0]; | ||
327 | if (dlen < 3) | ||
328 | return -EINVAL; | ||
329 | |||
330 | /* bDescriptorType */ | ||
331 | if (data[1] == USB_DT_CS_INTERFACE) { | ||
332 | /* bDescriptorSubType */ | ||
333 | switch (data[2]) { | ||
334 | case USB_CDC_UNION_TYPE: | ||
335 | if (union_header || dlen < 5) | ||
336 | break; | ||
337 | union_header = | ||
338 | (struct usb_cdc_union_desc *)data; | ||
339 | break; | ||
340 | case 0xAB: | ||
341 | if (phonet_header || dlen < 5) | ||
342 | break; | ||
343 | phonet_header = | ||
344 | (struct usb_cdc_header_desc *)data; | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | data += dlen; | ||
349 | len -= dlen; | ||
350 | } | ||
351 | |||
352 | if (!union_header || !phonet_header) | ||
353 | return -EINVAL; | ||
354 | |||
355 | data_intf = usb_ifnum_to_if(usbdev, union_header->bSlaveInterface0); | ||
356 | if (data_intf == NULL) | ||
357 | return -ENODEV; | ||
358 | /* Data interface has one inactive and one active setting */ | ||
359 | if (data_intf->num_altsetting != 2) | ||
360 | return -EINVAL; | ||
361 | if (data_intf->altsetting[0].desc.bNumEndpoints == 0 | ||
362 | && data_intf->altsetting[1].desc.bNumEndpoints == 2) | ||
363 | data_desc = data_intf->altsetting + 1; | ||
364 | else | ||
365 | if (data_intf->altsetting[0].desc.bNumEndpoints == 2 | ||
366 | && data_intf->altsetting[1].desc.bNumEndpoints == 0) | ||
367 | data_desc = data_intf->altsetting; | ||
368 | else | ||
369 | return -EINVAL; | ||
370 | |||
371 | dev = alloc_netdev(sizeof(*pnd) + sizeof(pnd->urbs[0]) * rxq_size, | ||
372 | ifname, usbpn_setup); | ||
373 | if (!dev) | ||
374 | return -ENOMEM; | ||
375 | |||
376 | pnd = netdev_priv(dev); | ||
377 | SET_NETDEV_DEV(dev, &intf->dev); | ||
378 | netif_stop_queue(dev); | ||
379 | |||
380 | pnd->dev = dev; | ||
381 | pnd->usb = usb_get_dev(usbdev); | ||
382 | pnd->intf = intf; | ||
383 | pnd->data_intf = data_intf; | ||
384 | spin_lock_init(&pnd->tx_lock); | ||
385 | spin_lock_init(&pnd->rx_lock); | ||
386 | /* Endpoints */ | ||
387 | if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) { | ||
388 | pnd->rx_pipe = usb_rcvbulkpipe(usbdev, | ||
389 | data_desc->endpoint[0].desc.bEndpointAddress); | ||
390 | pnd->tx_pipe = usb_sndbulkpipe(usbdev, | ||
391 | data_desc->endpoint[1].desc.bEndpointAddress); | ||
392 | } else { | ||
393 | pnd->rx_pipe = usb_rcvbulkpipe(usbdev, | ||
394 | data_desc->endpoint[1].desc.bEndpointAddress); | ||
395 | pnd->tx_pipe = usb_sndbulkpipe(usbdev, | ||
396 | data_desc->endpoint[0].desc.bEndpointAddress); | ||
397 | } | ||
398 | pnd->active_setting = data_desc - data_intf->altsetting; | ||
399 | |||
400 | err = usb_driver_claim_interface(&usbpn_driver, data_intf, pnd); | ||
401 | if (err) | ||
402 | goto out; | ||
403 | |||
404 | /* Force inactive mode until the network device is brought UP */ | ||
405 | usb_set_interface(usbdev, union_header->bSlaveInterface0, | ||
406 | !pnd->active_setting); | ||
407 | usb_set_intfdata(intf, pnd); | ||
408 | |||
409 | err = register_netdev(dev); | ||
410 | if (err) { | ||
411 | usb_driver_release_interface(&usbpn_driver, data_intf); | ||
412 | goto out; | ||
413 | } | ||
414 | |||
415 | dev_dbg(&dev->dev, "USB CDC Phonet device found\n"); | ||
416 | return 0; | ||
417 | |||
418 | out: | ||
419 | usb_set_intfdata(intf, NULL); | ||
420 | free_netdev(dev); | ||
421 | return err; | ||
422 | } | ||
423 | |||
424 | static void usbpn_disconnect(struct usb_interface *intf) | ||
425 | { | ||
426 | struct usbpn_dev *pnd = usb_get_intfdata(intf); | ||
427 | struct usb_device *usb = pnd->usb; | ||
428 | |||
429 | if (pnd->disconnected) | ||
430 | return; | ||
431 | |||
432 | pnd->disconnected = 1; | ||
433 | usb_driver_release_interface(&usbpn_driver, | ||
434 | (pnd->intf == intf) ? pnd->data_intf : pnd->intf); | ||
435 | unregister_netdev(pnd->dev); | ||
436 | usb_put_dev(usb); | ||
437 | } | ||
438 | |||
439 | static struct usb_driver usbpn_driver = { | ||
440 | .name = "cdc_phonet", | ||
441 | .probe = usbpn_probe, | ||
442 | .disconnect = usbpn_disconnect, | ||
443 | .id_table = usbpn_ids, | ||
444 | }; | ||
445 | |||
446 | static int __init usbpn_init(void) | ||
447 | { | ||
448 | return usb_register(&usbpn_driver); | ||
449 | } | ||
450 | |||
451 | static void __exit usbpn_exit(void) | ||
452 | { | ||
453 | usb_deregister(&usbpn_driver); | ||
454 | } | ||
455 | |||
456 | module_init(usbpn_init); | ||
457 | module_exit(usbpn_exit); | ||
458 | |||
459 | MODULE_AUTHOR("Remi Denis-Courmont"); | ||
460 | MODULE_DESCRIPTION("USB CDC Phonet host interface"); | ||
461 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index cd35d50e46d4..45cebfb302cf 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c | |||
@@ -311,7 +311,7 @@ static int eem_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
311 | * bmCRC = 0 : CRC = 0xDEADBEEF | 311 | * bmCRC = 0 : CRC = 0xDEADBEEF |
312 | */ | 312 | */ |
313 | if (header & BIT(14)) | 313 | if (header & BIT(14)) |
314 | crc2 = ~crc32_le(~0, skb2->data, len); | 314 | crc2 = ~crc32_le(~0, skb2->data, skb2->len); |
315 | else | 315 | else |
316 | crc2 = 0xdeadbeef; | 316 | crc2 = 0xdeadbeef; |
317 | 317 | ||
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index e01314789718..1f9ec29fce50 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -999,6 +999,9 @@ static const struct net_device_ops kaweth_netdev_ops = { | |||
999 | .ndo_tx_timeout = kaweth_tx_timeout, | 999 | .ndo_tx_timeout = kaweth_tx_timeout, |
1000 | .ndo_set_multicast_list = kaweth_set_rx_mode, | 1000 | .ndo_set_multicast_list = kaweth_set_rx_mode, |
1001 | .ndo_get_stats = kaweth_netdev_stats, | 1001 | .ndo_get_stats = kaweth_netdev_stats, |
1002 | .ndo_change_mtu = eth_change_mtu, | ||
1003 | .ndo_set_mac_address = eth_mac_addr, | ||
1004 | .ndo_validate_addr = eth_validate_addr, | ||
1002 | }; | 1005 | }; |
1003 | 1006 | ||
1004 | static int kaweth_probe( | 1007 | static int kaweth_probe( |
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 73acbd244aa1..631d269ac980 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
@@ -1493,6 +1493,9 @@ static const struct net_device_ops pegasus_netdev_ops = { | |||
1493 | .ndo_set_multicast_list = pegasus_set_multicast, | 1493 | .ndo_set_multicast_list = pegasus_set_multicast, |
1494 | .ndo_get_stats = pegasus_netdev_stats, | 1494 | .ndo_get_stats = pegasus_netdev_stats, |
1495 | .ndo_tx_timeout = pegasus_tx_timeout, | 1495 | .ndo_tx_timeout = pegasus_tx_timeout, |
1496 | .ndo_change_mtu = eth_change_mtu, | ||
1497 | .ndo_set_mac_address = eth_mac_addr, | ||
1498 | .ndo_validate_addr = eth_validate_addr, | ||
1496 | }; | 1499 | }; |
1497 | 1500 | ||
1498 | static struct usb_driver pegasus_driver = { | 1501 | static struct usb_driver pegasus_driver = { |
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index d3489a3c4c03..88c30a58b4bd 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c | |||
@@ -621,6 +621,7 @@ static const struct net_device_ops rhine_netdev_ops = { | |||
621 | .ndo_start_xmit = rhine_start_tx, | 621 | .ndo_start_xmit = rhine_start_tx, |
622 | .ndo_get_stats = rhine_get_stats, | 622 | .ndo_get_stats = rhine_get_stats, |
623 | .ndo_set_multicast_list = rhine_set_rx_mode, | 623 | .ndo_set_multicast_list = rhine_set_rx_mode, |
624 | .ndo_change_mtu = eth_change_mtu, | ||
624 | .ndo_validate_addr = eth_validate_addr, | 625 | .ndo_validate_addr = eth_validate_addr, |
625 | .ndo_set_mac_address = eth_mac_addr, | 626 | .ndo_set_mac_address = eth_mac_addr, |
626 | .ndo_do_ioctl = netdev_ioctl, | 627 | .ndo_do_ioctl = netdev_ioctl, |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 345593c4accb..a370e510f19f 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -2521,6 +2521,8 @@ static const struct net_device_ops orinoco_netdev_ops = { | |||
2521 | .ndo_start_xmit = orinoco_xmit, | 2521 | .ndo_start_xmit = orinoco_xmit, |
2522 | .ndo_set_multicast_list = orinoco_set_multicast_list, | 2522 | .ndo_set_multicast_list = orinoco_set_multicast_list, |
2523 | .ndo_change_mtu = orinoco_change_mtu, | 2523 | .ndo_change_mtu = orinoco_change_mtu, |
2524 | .ndo_set_mac_address = eth_mac_addr, | ||
2525 | .ndo_validate_addr = eth_validate_addr, | ||
2524 | .ndo_tx_timeout = orinoco_tx_timeout, | 2526 | .ndo_tx_timeout = orinoco_tx_timeout, |
2525 | .ndo_get_stats = orinoco_get_stats, | 2527 | .ndo_get_stats = orinoco_get_stats, |
2526 | }; | 2528 | }; |
@@ -2555,7 +2557,6 @@ struct net_device | |||
2555 | priv->wireless_data.spy_data = &priv->spy_data; | 2557 | priv->wireless_data.spy_data = &priv->spy_data; |
2556 | dev->wireless_data = &priv->wireless_data; | 2558 | dev->wireless_data = &priv->wireless_data; |
2557 | #endif | 2559 | #endif |
2558 | /* we use the default eth_mac_addr for setting the MAC addr */ | ||
2559 | 2560 | ||
2560 | /* Reserve space in skb for the SNAP header */ | 2561 | /* Reserve space in skb for the SNAP header */ |
2561 | dev->hard_header_len += ENCAPS_OVERHEAD; | 2562 | dev->hard_header_len += ENCAPS_OVERHEAD; |
diff --git a/drivers/oprofile/oprofile_stats.c b/drivers/oprofile/oprofile_stats.c index e1f6ce03705e..3c2270a8300c 100644 --- a/drivers/oprofile/oprofile_stats.c +++ b/drivers/oprofile/oprofile_stats.c | |||
@@ -33,6 +33,7 @@ void oprofile_reset_stats(void) | |||
33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); | 33 | atomic_set(&oprofile_stats.sample_lost_no_mm, 0); |
34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); | 34 | atomic_set(&oprofile_stats.sample_lost_no_mapping, 0); |
35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); | 35 | atomic_set(&oprofile_stats.event_lost_overflow, 0); |
36 | atomic_set(&oprofile_stats.bt_lost_no_mapping, 0); | ||
36 | } | 37 | } |
37 | 38 | ||
38 | 39 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index a5b9f6ae507b..d703e73fffa7 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/pci_hotplug.h> | 32 | #include <linux/pci_hotplug.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
37 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
38 | #include <linux/kthread.h> | 37 | #include <linux/kthread.h> |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 2fa47af992a8..0ff689afa757 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/wait.h> | 36 | #include <linux/wait.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/pci.h> | 37 | #include <linux/pci.h> |
39 | #include <linux/pci_hotplug.h> | 38 | #include <linux/pci_hotplug.h> |
40 | #include <linux/kthread.h> | 39 | #include <linux/kthread.h> |
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 8450f4a6568a..e6089bdb6e5b 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <linux/pci_hotplug.h> | 35 | #include <linux/pci_hotplug.h> |
36 | #include <linux/smp_lock.h> | ||
36 | #include <linux/debugfs.h> | 37 | #include <linux/debugfs.h> |
37 | #include "cpqphp.h" | 38 | #include "cpqphp.h" |
38 | 39 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index ff4034502d24..8aab8edf123e 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
35 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
36 | #include "../pci.h" | 35 | #include "../pci.h" |
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index ec22284eed30..e1c1ec540893 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/pci.h> | 11 | #include <linux/pci.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/syscalls.h> | 12 | #include <linux/syscalls.h> |
14 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
15 | #include "pci.h" | 14 | #include "pci.h" |
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 8bde92126d34..b787335a8419 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c | |||
@@ -33,14 +33,14 @@ static enum power_supply_property *prop; | |||
33 | 33 | ||
34 | static unsigned long wm97xx_read_bat(struct power_supply *bat_ps) | 34 | static unsigned long wm97xx_read_bat(struct power_supply *bat_ps) |
35 | { | 35 | { |
36 | return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data, | 36 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent), |
37 | pdata->batt_aux) * pdata->batt_mult / | 37 | pdata->batt_aux) * pdata->batt_mult / |
38 | pdata->batt_div; | 38 | pdata->batt_div; |
39 | } | 39 | } |
40 | 40 | ||
41 | static unsigned long wm97xx_read_temp(struct power_supply *bat_ps) | 41 | static unsigned long wm97xx_read_temp(struct power_supply *bat_ps) |
42 | { | 42 | { |
43 | return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data, | 43 | return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent), |
44 | pdata->temp_aux) * pdata->temp_mult / | 44 | pdata->temp_aux) * pdata->temp_mult / |
45 | pdata->temp_div; | 45 | pdata->temp_div; |
46 | } | 46 | } |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index f8b1f04f26b8..c11770f5b368 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -1696,8 +1696,7 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device, | |||
1696 | DBF_DEV_EVENT(DBF_ERR, device, "%s", | 1696 | DBF_DEV_EVENT(DBF_ERR, device, "%s", |
1697 | "unsolicited interrupt received " | 1697 | "unsolicited interrupt received " |
1698 | "(sense available)"); | 1698 | "(sense available)"); |
1699 | device->discipline->dump_sense_dbf(device, NULL, irb, | 1699 | device->discipline->dump_sense_dbf(device, irb, "unsolicited"); |
1700 | "unsolicited"); | ||
1701 | } | 1700 | } |
1702 | 1701 | ||
1703 | dasd_schedule_device_bh(device); | 1702 | dasd_schedule_device_bh(device); |
@@ -2941,42 +2940,20 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) | |||
2941 | } | 2940 | } |
2942 | 2941 | ||
2943 | static void | 2942 | static void |
2944 | dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, | 2943 | dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb, |
2945 | struct irb *irb, char *reason) | 2944 | char *reason) |
2946 | { | 2945 | { |
2947 | u64 *sense; | 2946 | u64 *sense; |
2948 | int sl; | ||
2949 | struct tsb *tsb; | ||
2950 | 2947 | ||
2951 | sense = NULL; | 2948 | sense = (u64 *) dasd_get_sense(irb); |
2952 | tsb = NULL; | ||
2953 | if (req && scsw_is_tm(&req->irb.scsw)) { | ||
2954 | if (irb->scsw.tm.tcw) | ||
2955 | tsb = tcw_get_tsb( | ||
2956 | (struct tcw *)(unsigned long)irb->scsw.tm.tcw); | ||
2957 | if (tsb && (irb->scsw.tm.fcxs == 0x01)) { | ||
2958 | switch (tsb->flags & 0x07) { | ||
2959 | case 1: /* tsa_iostat */ | ||
2960 | sense = (u64 *)tsb->tsa.iostat.sense; | ||
2961 | break; | ||
2962 | case 2: /* ts_ddpc */ | ||
2963 | sense = (u64 *)tsb->tsa.ddpc.sense; | ||
2964 | break; | ||
2965 | case 3: /* tsa_intrg */ | ||
2966 | break; | ||
2967 | } | ||
2968 | } | ||
2969 | } else { | ||
2970 | if (irb->esw.esw0.erw.cons) | ||
2971 | sense = (u64 *)irb->ecw; | ||
2972 | } | ||
2973 | if (sense) { | 2949 | if (sense) { |
2974 | for (sl = 0; sl < 4; sl++) { | 2950 | DBF_DEV_EVENT(DBF_EMERG, device, |
2975 | DBF_DEV_EVENT(DBF_EMERG, device, | 2951 | "%s: %s %02x%02x%02x %016llx %016llx %016llx " |
2976 | "%s: %016llx %016llx %016llx %016llx", | 2952 | "%016llx", reason, |
2977 | reason, sense[0], sense[1], sense[2], | 2953 | scsw_is_tm(&irb->scsw) ? "t" : "c", |
2978 | sense[3]); | 2954 | scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), |
2979 | } | 2955 | scsw_dstat(&irb->scsw), sense[0], sense[1], |
2956 | sense[2], sense[3]); | ||
2980 | } else { | 2957 | } else { |
2981 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", | 2958 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", |
2982 | "SORRY - NO VALID SENSE AVAILABLE\n"); | 2959 | "SORRY - NO VALID SENSE AVAILABLE\n"); |
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c index d970ce2814be..cb8f9cef7429 100644 --- a/drivers/s390/block/dasd_erp.c +++ b/drivers/s390/block/dasd_erp.c | |||
@@ -172,7 +172,7 @@ dasd_log_sense_dbf(struct dasd_ccw_req *cqr, struct irb *irb) | |||
172 | device = cqr->startdev; | 172 | device = cqr->startdev; |
173 | /* dump sense data to s390 debugfeature*/ | 173 | /* dump sense data to s390 debugfeature*/ |
174 | if (device->discipline && device->discipline->dump_sense_dbf) | 174 | if (device->discipline && device->discipline->dump_sense_dbf) |
175 | device->discipline->dump_sense_dbf(device, cqr, irb, "log"); | 175 | device->discipline->dump_sense_dbf(device, irb, "log"); |
176 | } | 176 | } |
177 | EXPORT_SYMBOL(dasd_log_sense_dbf); | 177 | EXPORT_SYMBOL(dasd_log_sense_dbf); |
178 | 178 | ||
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index e21ee735f926..31849ad5e59f 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -241,7 +241,7 @@ static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device, | |||
241 | /* check for unsolicited interrupts */ | 241 | /* check for unsolicited interrupts */ |
242 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | 242 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", |
243 | "unsolicited interrupt received"); | 243 | "unsolicited interrupt received"); |
244 | device->discipline->dump_sense_dbf(device, NULL, irb, "unsolicited"); | 244 | device->discipline->dump_sense_dbf(device, irb, "unsolicited"); |
245 | dasd_schedule_device_bh(device); | 245 | dasd_schedule_device_bh(device); |
246 | return; | 246 | return; |
247 | }; | 247 | }; |
@@ -444,17 +444,20 @@ dasd_fba_fill_info(struct dasd_device * device, | |||
444 | } | 444 | } |
445 | 445 | ||
446 | static void | 446 | static void |
447 | dasd_fba_dump_sense_dbf(struct dasd_device *device, struct dasd_ccw_req *req, | 447 | dasd_fba_dump_sense_dbf(struct dasd_device *device, struct irb *irb, |
448 | struct irb *irb, char *reason) | 448 | char *reason) |
449 | { | 449 | { |
450 | int sl; | 450 | u64 *sense; |
451 | if (irb->esw.esw0.erw.cons) { | 451 | |
452 | for (sl = 0; sl < 4; sl++) { | 452 | sense = (u64 *) dasd_get_sense(irb); |
453 | DBF_DEV_EVENT(DBF_EMERG, device, | 453 | if (sense) { |
454 | "%s: %08x %08x %08x %08x", | 454 | DBF_DEV_EVENT(DBF_EMERG, device, |
455 | reason, irb->ecw[8 * 0], irb->ecw[8 * 1], | 455 | "%s: %s %02x%02x%02x %016llx %016llx %016llx " |
456 | irb->ecw[8 * 2], irb->ecw[8 * 3]); | 456 | "%016llx", reason, |
457 | } | 457 | scsw_is_tm(&irb->scsw) ? "t" : "c", |
458 | scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), | ||
459 | scsw_dstat(&irb->scsw), sense[0], sense[1], | ||
460 | sense[2], sense[3]); | ||
458 | } else { | 461 | } else { |
459 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", | 462 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", |
460 | "SORRY - NO VALID SENSE AVAILABLE\n"); | 463 | "SORRY - NO VALID SENSE AVAILABLE\n"); |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index fd63b2f2bda9..b699ca356ac5 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -284,8 +284,7 @@ struct dasd_discipline { | |||
284 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); | 284 | dasd_erp_fn_t(*erp_postaction) (struct dasd_ccw_req *); |
285 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, | 285 | void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, |
286 | struct irb *); | 286 | struct irb *); |
287 | void (*dump_sense_dbf) (struct dasd_device *, struct dasd_ccw_req *, | 287 | void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *); |
288 | struct irb *, char *); | ||
289 | 288 | ||
290 | void (*handle_unsolicited_interrupt) (struct dasd_device *, | 289 | void (*handle_unsolicited_interrupt) (struct dasd_device *, |
291 | struct irb *); | 290 | struct irb *); |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 4ce3f72ee1c1..df918ef27965 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/major.h> | 16 | #include <linux/major.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/blkpg.h> | 18 | #include <linux/blkpg.h> |
19 | #include <linux/smp_lock.h> | ||
19 | 20 | ||
20 | #include <asm/ccwdev.h> | 21 | #include <asm/ccwdev.h> |
21 | #include <asm/cmb.h> | 22 | #include <asm/cmb.h> |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 016f9e9d2591..d34617682a62 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -964,7 +964,8 @@ static int dcssblk_freeze(struct device *dev) | |||
964 | break; | 964 | break; |
965 | } | 965 | } |
966 | if (rc) | 966 | if (rc) |
967 | pr_err("Suspend failed because device %s is writeable.\n", | 967 | pr_err("Suspending the system failed because DCSS device %s " |
968 | "is writable\n", | ||
968 | dev_info->segment_name); | 969 | dev_info->segment_name); |
969 | return rc; | 970 | return rc; |
970 | } | 971 | } |
@@ -987,8 +988,8 @@ static int dcssblk_restore(struct device *dev) | |||
987 | goto out_panic; | 988 | goto out_panic; |
988 | } | 989 | } |
989 | if (start != entry->start || end != entry->end) { | 990 | if (start != entry->start || end != entry->end) { |
990 | pr_err("Mismatch of start / end address after " | 991 | pr_err("The address range of DCSS %s changed " |
991 | "resuming device %s\n", | 992 | "while the system was suspended\n", |
992 | entry->segment_name); | 993 | entry->segment_name); |
993 | goto out_panic; | 994 | goto out_panic; |
994 | } | 995 | } |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 2e9e1ecd6d82..db442cd6621e 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -443,7 +443,7 @@ fail: | |||
443 | */ | 443 | */ |
444 | static void xpram_resume_error(const char *message) | 444 | static void xpram_resume_error(const char *message) |
445 | { | 445 | { |
446 | pr_err("Resume error: %s\n", message); | 446 | pr_err("Resuming the system failed: %s\n", message); |
447 | panic("xpram resume error\n"); | 447 | panic("xpram resume error\n"); |
448 | } | 448 | } |
449 | 449 | ||
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 7892550d7932..3234e90bd7f9 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c | |||
@@ -320,7 +320,7 @@ static int mon_open(struct inode *inode, struct file *filp) | |||
320 | goto out_path; | 320 | goto out_path; |
321 | } | 321 | } |
322 | filp->private_data = monpriv; | 322 | filp->private_data = monpriv; |
323 | dev_set_drvdata(&monreader_device, monpriv); | 323 | dev_set_drvdata(monreader_device, monpriv); |
324 | unlock_kernel(); | 324 | unlock_kernel(); |
325 | return nonseekable_open(inode, filp); | 325 | return nonseekable_open(inode, filp); |
326 | 326 | ||
@@ -463,7 +463,7 @@ static struct miscdevice mon_dev = { | |||
463 | *****************************************************************************/ | 463 | *****************************************************************************/ |
464 | static int monreader_freeze(struct device *dev) | 464 | static int monreader_freeze(struct device *dev) |
465 | { | 465 | { |
466 | struct mon_private *monpriv = dev_get_drvdata(&dev); | 466 | struct mon_private *monpriv = dev_get_drvdata(dev); |
467 | int rc; | 467 | int rc; |
468 | 468 | ||
469 | if (!monpriv) | 469 | if (!monpriv) |
diff --git a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h index 85f491ea929c..7a7bfc947d97 100644 --- a/drivers/s390/char/sclp_rw.h +++ b/drivers/s390/char/sclp_rw.h | |||
@@ -92,5 +92,10 @@ void sclp_set_columns(struct sclp_buffer *, unsigned short); | |||
92 | void sclp_set_htab(struct sclp_buffer *, unsigned short); | 92 | void sclp_set_htab(struct sclp_buffer *, unsigned short); |
93 | int sclp_chars_in_buffer(struct sclp_buffer *); | 93 | int sclp_chars_in_buffer(struct sclp_buffer *); |
94 | 94 | ||
95 | #ifdef CONFIG_SCLP_CONSOLE | ||
95 | void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); | 96 | void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event); |
97 | #else | ||
98 | static inline void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event) { } | ||
99 | #endif | ||
100 | |||
96 | #endif /* __SCLP_RW_H__ */ | 101 | #endif /* __SCLP_RW_H__ */ |
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c index cb7854c10c04..f2bc287b69e4 100644 --- a/drivers/s390/char/vmwatchdog.c +++ b/drivers/s390/char/vmwatchdog.c | |||
@@ -250,14 +250,14 @@ static int vmwdt_resume(void) | |||
250 | static int vmwdt_suspend(void) | 250 | static int vmwdt_suspend(void) |
251 | { | 251 | { |
252 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { | 252 | if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { |
253 | pr_err("The watchdog is in use. " | 253 | pr_err("The system cannot be suspended while the watchdog" |
254 | "This prevents hibernation or suspend.\n"); | 254 | " is in use\n"); |
255 | return NOTIFY_BAD; | 255 | return NOTIFY_BAD; |
256 | } | 256 | } |
257 | if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) { | 257 | if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) { |
258 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); | 258 | clear_bit(VMWDT_OPEN, &vmwdt_is_open); |
259 | pr_err("The watchdog is running. " | 259 | pr_err("The system cannot be suspended while the watchdog" |
260 | "This prevents hibernation or suspend.\n"); | 260 | " is running\n"); |
261 | return NOTIFY_BAD; | 261 | return NOTIFY_BAD; |
262 | } | 262 | } |
263 | return NOTIFY_DONE; | 263 | return NOTIFY_DONE; |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 650bcef08f2a..cd78c501803a 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | #include <linux/moduleparam.h> | 10 | #include <linux/moduleparam.h> |
11 | #include <linux/vmalloc.h> | 11 | #include <linux/vmalloc.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include <linux/list.h> | 12 | #include <linux/list.h> |
14 | 13 | ||
15 | #include <scsi/scsi_tcq.h> | 14 | #include <scsi/scsi_tcq.h> |
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c index 34b4ae0fe760..c108b1a0ce98 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/serial/bfin_sport_uart.c | |||
@@ -236,7 +236,6 @@ static int sport_startup(struct uart_port *port) | |||
236 | int retval; | 236 | int retval; |
237 | 237 | ||
238 | pr_debug("%s enter\n", __func__); | 238 | pr_debug("%s enter\n", __func__); |
239 | memset(buffer, 20, '\0'); | ||
240 | snprintf(buffer, 20, "%s rx", up->name); | 239 | snprintf(buffer, 20, "%s rx", up->name); |
241 | retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); | 240 | retval = request_irq(up->rx_irq, sport_uart_rx_irq, IRQF_SAMPLE_RANDOM, buffer, up); |
242 | if (retval) { | 241 | if (retval) { |
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index 698048f64f5e..f7c24baa1416 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c | |||
@@ -730,7 +730,6 @@ static int __devexit msm_serial_remove(struct platform_device *pdev) | |||
730 | } | 730 | } |
731 | 731 | ||
732 | static struct platform_driver msm_platform_driver = { | 732 | static struct platform_driver msm_platform_driver = { |
733 | .probe = msm_serial_probe, | ||
734 | .remove = msm_serial_remove, | 733 | .remove = msm_serial_remove, |
735 | .driver = { | 734 | .driver = { |
736 | .name = "msm_serial", | 735 | .name = "msm_serial", |
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index baf83c6a9412..e3c3adc282e2 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c | |||
@@ -45,6 +45,8 @@ Devices: [JR3] PCI force sensor board (jr3_pci) | |||
45 | #include <linux/delay.h> | 45 | #include <linux/delay.h> |
46 | #include <linux/ctype.h> | 46 | #include <linux/ctype.h> |
47 | #include <linux/firmware.h> | 47 | #include <linux/firmware.h> |
48 | #include <linux/jiffies.h> | ||
49 | #include <linux/timer.h> | ||
48 | #include "comedi_pci.h" | 50 | #include "comedi_pci.h" |
49 | #include "jr3_pci.h" | 51 | #include "jr3_pci.h" |
50 | 52 | ||
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 92121cf8c45c..5d9bab352c1d 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c | |||
@@ -111,9 +111,13 @@ static const struct s626_board s626_boards[] = { | |||
111 | #define PCI_VENDOR_ID_S626 0x1131 | 111 | #define PCI_VENDOR_ID_S626 0x1131 |
112 | #define PCI_DEVICE_ID_S626 0x7146 | 112 | #define PCI_DEVICE_ID_S626 0x7146 |
113 | 113 | ||
114 | /* | ||
115 | * For devices with vendor:device id == 0x1131:0x7146 you must specify | ||
116 | * also subvendor:subdevice ids, because otherwise it will conflict with | ||
117 | * Philips SAA7146 media/dvb based cards. | ||
118 | */ | ||
114 | static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { | 119 | static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = { |
115 | {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 120 | {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, 0x6000, 0x0272, 0, 0, 0}, |
116 | 0}, | ||
117 | {0} | 121 | {0} |
118 | }; | 122 | }; |
119 | 123 | ||
@@ -499,25 +503,26 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
499 | resource_size_t resourceStart; | 503 | resource_size_t resourceStart; |
500 | dma_addr_t appdma; | 504 | dma_addr_t appdma; |
501 | struct comedi_subdevice *s; | 505 | struct comedi_subdevice *s; |
502 | struct pci_dev *pdev; | 506 | const struct pci_device_id *ids; |
507 | struct pci_dev *pdev = NULL; | ||
503 | 508 | ||
504 | if (alloc_private(dev, sizeof(struct s626_private)) < 0) | 509 | if (alloc_private(dev, sizeof(struct s626_private)) < 0) |
505 | return -ENOMEM; | 510 | return -ENOMEM; |
506 | 511 | ||
507 | for (pdev = pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, | 512 | for (i = 0; i < (ARRAY_SIZE(s626_pci_table) - 1) && !pdev; i++) { |
508 | NULL); pdev != NULL; | 513 | ids = &s626_pci_table[i]; |
509 | pdev = pci_get_device(PCI_VENDOR_ID_S626, | 514 | do { |
510 | PCI_DEVICE_ID_S626, pdev)) { | 515 | pdev = pci_get_subsys(ids->vendor, ids->device, ids->subvendor, |
511 | if (it->options[0] || it->options[1]) { | 516 | ids->subdevice, pdev); |
512 | if (pdev->bus->number == it->options[0] && | 517 | |
513 | PCI_SLOT(pdev->devfn) == it->options[1]) { | 518 | if ((it->options[0] || it->options[1]) && pdev) { |
514 | /* matches requested bus/slot */ | 519 | /* matches requested bus/slot */ |
520 | if (pdev->bus->number == it->options[0] && | ||
521 | PCI_SLOT(pdev->devfn) == it->options[1]) | ||
522 | break; | ||
523 | } else | ||
515 | break; | 524 | break; |
516 | } | 525 | } while (1); |
517 | } else { | ||
518 | /* no bus/slot specified */ | ||
519 | break; | ||
520 | } | ||
521 | } | 526 | } |
522 | devpriv->pdev = pdev; | 527 | devpriv->pdev = pdev; |
523 | 528 | ||
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c index a5e4acab089e..bb22347af60e 100644 --- a/drivers/staging/go7007/s2250-loader.c +++ b/drivers/staging/go7007/s2250-loader.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/smp_lock.h> | ||
20 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
21 | #include <dvb-usb.h> | 22 | #include <dvb-usb.h> |
22 | 23 | ||
diff --git a/drivers/staging/meilhaus/TODO b/drivers/staging/meilhaus/TODO index 6ec25203089c..d6ce39823de6 100644 --- a/drivers/staging/meilhaus/TODO +++ b/drivers/staging/meilhaus/TODO | |||
@@ -7,4 +7,4 @@ TODO: | |||
7 | - possible comedi merge | 7 | - possible comedi merge |
8 | 8 | ||
9 | Please send cleanup patches to Greg Kroah-Hartman <greg@kroah.com> | 9 | Please send cleanup patches to Greg Kroah-Hartman <greg@kroah.com> |
10 | and CC: David Kiliani <mail@davidkiliani.de> | 10 | and CC: David Kiliani <mail@davidkiliani.de> and Meilhaus Support <support@meilhaus.de> |
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c index 1cdfe69585ea..2f8155c1968b 100644 --- a/drivers/staging/rspiusb/rspiusb.c +++ b/drivers/staging/rspiusb/rspiusb.c | |||
@@ -444,8 +444,7 @@ static void piusb_write_bulk_callback(struct urb *urb) | |||
444 | __func__, status); | 444 | __func__, status); |
445 | 445 | ||
446 | pdx->pendingWrite = 0; | 446 | pdx->pendingWrite = 0; |
447 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 447 | kfree(urb->transfer_buffer); |
448 | urb->transfer_buffer, urb->transfer_dma); | ||
449 | } | 448 | } |
450 | 449 | ||
451 | int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, | 450 | int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, |
@@ -457,9 +456,7 @@ int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, | |||
457 | 456 | ||
458 | urb = usb_alloc_urb(0, GFP_KERNEL); | 457 | urb = usb_alloc_urb(0, GFP_KERNEL); |
459 | if (urb != NULL) { | 458 | if (urb != NULL) { |
460 | kbuf = | 459 | kbuf = kmalloc(len, GFP_KERNEL); |
461 | usb_buffer_alloc(pdx->udev, len, GFP_KERNEL, | ||
462 | &urb->transfer_dma); | ||
463 | if (!kbuf) { | 460 | if (!kbuf) { |
464 | dev_err(&pdx->udev->dev, "buffer_alloc failed\n"); | 461 | dev_err(&pdx->udev->dev, "buffer_alloc failed\n"); |
465 | return -ENOMEM; | 462 | return -ENOMEM; |
@@ -470,7 +467,6 @@ int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, | |||
470 | } | 467 | } |
471 | usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf, | 468 | usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf, |
472 | len, piusb_write_bulk_callback, pdx); | 469 | len, piusb_write_bulk_callback, pdx); |
473 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
474 | err = usb_submit_urb(urb, GFP_KERNEL); | 470 | err = usb_submit_urb(urb, GFP_KERNEL); |
475 | if (err) { | 471 | if (err) { |
476 | dev_err(&pdx->udev->dev, | 472 | dev_err(&pdx->udev->dev, |
@@ -641,7 +637,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) | |||
641 | numPagesRequired = | 637 | numPagesRequired = |
642 | ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; | 638 | ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT; |
643 | dbg("Number of pages needed = %d", numPagesRequired); | 639 | dbg("Number of pages needed = %d", numPagesRequired); |
644 | maplist_p = vmalloc(numPagesRequired * sizeof(struct page)); | 640 | maplist_p = vmalloc(numPagesRequired * sizeof(struct page *)); |
645 | if (!maplist_p) { | 641 | if (!maplist_p) { |
646 | dbg("Can't Allocate Memory for maplist_p"); | 642 | dbg("Can't Allocate Memory for maplist_p"); |
647 | return -ENOMEM; | 643 | return -ENOMEM; |
@@ -712,9 +708,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) | |||
712 | usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], | 708 | usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], |
713 | pdx->udev, | 709 | pdx->udev, |
714 | epAddr, | 710 | epAddr, |
715 | (dma_addr_t *) sg_dma_address(&pdx-> | 711 | NULL, // non-DMA HC? buy a better hardware |
716 | sgl[frameInfo] | ||
717 | [i]), | ||
718 | sg_dma_len(&pdx->sgl[frameInfo][i]), | 712 | sg_dma_len(&pdx->sgl[frameInfo][i]), |
719 | piusb_readPIXEL_callback, (void *)pdx); | 713 | piusb_readPIXEL_callback, (void *)pdx); |
720 | pdx->PixelUrb[frameInfo][i]->transfer_dma = | 714 | pdx->PixelUrb[frameInfo][i]->transfer_dma = |
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h index 5e5b3f2b7eb1..29e3b53e52a1 100644 --- a/drivers/staging/rt2870/rt2870.h +++ b/drivers/staging/rt2870/rt2870.h | |||
@@ -89,6 +89,7 @@ | |||
89 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ | 89 | {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \ |
90 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ | 90 | {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \ |
91 | {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */ \ | 91 | {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */ \ |
92 | {USB_DEVICE(0x0DF6,0x003F)}, /* Sitecom WL-608 */ \ | ||
92 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ | 93 | {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \ |
93 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ | 94 | {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \ |
94 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ | 95 | {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \ |
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index 93af37e2d31a..54b4b718f84a 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c | |||
@@ -461,19 +461,19 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, | |||
461 | struct iw_request_info *info, | 461 | struct iw_request_info *info, |
462 | union iwreq_data *wrqu, char *extra) | 462 | union iwreq_data *wrqu, char *extra) |
463 | { | 463 | { |
464 | strcpy(wrqu->name, "802.11"); | 464 | strlcpy(wrqu->name, "802.11", IFNAMSIZ); |
465 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ | 465 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ |
466 | strcat(wrqu->name, "b"); | 466 | strlcat(wrqu->name, "b", IFNAMSIZ); |
467 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 467 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
468 | strcat(wrqu->name, "/g"); | 468 | strlcat(wrqu->name, "/g", IFNAMSIZ); |
469 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 469 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
470 | strcat(wrqu->name, "g"); | 470 | strlcat(wrqu->name, "g", IFNAMSIZ); |
471 | 471 | ||
472 | if((ieee->state == IEEE80211_LINKED) || | 472 | if((ieee->state == IEEE80211_LINKED) || |
473 | (ieee->state == IEEE80211_LINKED_SCANNING)) | 473 | (ieee->state == IEEE80211_LINKED_SCANNING)) |
474 | strcat(wrqu->name," linked"); | 474 | strlcat(wrqu->name," link", IFNAMSIZ); |
475 | else if(ieee->state != IEEE80211_NOLINK) | 475 | else if(ieee->state != IEEE80211_NOLINK) |
476 | strcat(wrqu->name," link.."); | 476 | strlcat(wrqu->name," .....", IFNAMSIZ); |
477 | 477 | ||
478 | 478 | ||
479 | return 0; | 479 | return 0; |
diff --git a/drivers/staging/rtl8192su/Kconfig b/drivers/staging/rtl8192su/Kconfig index 4b5552c5926e..770f41280f21 100644 --- a/drivers/staging/rtl8192su/Kconfig +++ b/drivers/staging/rtl8192su/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config RTL8192SU | 1 | config RTL8192SU |
2 | tristate "RealTek RTL8192SU Wireless LAN NIC driver" | 2 | tristate "RealTek RTL8192SU Wireless LAN NIC driver" |
3 | depends on PCI | 3 | depends on PCI |
4 | depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS | 4 | depends on WIRELESS_EXT |
5 | default N | 5 | default N |
6 | ---help--- | 6 | ---help--- |
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c index f408b4583b82..759032db4a34 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c | |||
@@ -118,7 +118,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
118 | #else | 118 | #else |
119 | ieee = (struct ieee80211_device *)dev->priv; | 119 | ieee = (struct ieee80211_device *)dev->priv; |
120 | #endif | 120 | #endif |
121 | dev->hard_start_xmit = ieee80211_xmit; | ||
122 | 121 | ||
123 | memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); | 122 | memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv); |
124 | ieee->dev = dev; | 123 | ieee->dev = dev; |
diff --git a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c index 1f50c46dcb90..191dc3fbbe32 100644 --- a/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c | |||
@@ -548,21 +548,21 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, | |||
548 | struct iw_request_info *info, | 548 | struct iw_request_info *info, |
549 | union iwreq_data *wrqu, char *extra) | 549 | union iwreq_data *wrqu, char *extra) |
550 | { | 550 | { |
551 | strcpy(wrqu->name, "802.11"); | 551 | strlcpy(wrqu->name, "802.11", IFNAMSIZ); |
552 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ | 552 | if(ieee->modulation & IEEE80211_CCK_MODULATION){ |
553 | strcat(wrqu->name, "b"); | 553 | strlcat(wrqu->name, "b", IFNAMSIZ); |
554 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 554 | if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
555 | strcat(wrqu->name, "/g"); | 555 | strlcat(wrqu->name, "/g", IFNAMSIZ); |
556 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) | 556 | }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) |
557 | strcat(wrqu->name, "g"); | 557 | strlcat(wrqu->name, "g", IFNAMSIZ); |
558 | if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) | 558 | if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) |
559 | strcat(wrqu->name, "/n"); | 559 | strlcat(wrqu->name, "/n", IFNAMSIZ); |
560 | 560 | ||
561 | if((ieee->state == IEEE80211_LINKED) || | 561 | if((ieee->state == IEEE80211_LINKED) || |
562 | (ieee->state == IEEE80211_LINKED_SCANNING)) | 562 | (ieee->state == IEEE80211_LINKED_SCANNING)) |
563 | strcat(wrqu->name," linked"); | 563 | strlcat(wrqu->name, " link", IFNAMSIZ); |
564 | else if(ieee->state != IEEE80211_NOLINK) | 564 | else if(ieee->state != IEEE80211_NOLINK) |
565 | strcat(wrqu->name," link.."); | 565 | strlcat(wrqu->name, " .....", IFNAMSIZ); |
566 | 566 | ||
567 | 567 | ||
568 | return 0; | 568 | return 0; |
diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index f1423d714496..4ab250743e81 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c | |||
@@ -12132,6 +12132,19 @@ static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct | |||
12132 | } | 12132 | } |
12133 | #endif | 12133 | #endif |
12134 | 12134 | ||
12135 | static const struct net_device_ops rtl8192_netdev_ops = { | ||
12136 | .ndo_open = rtl8192_open, | ||
12137 | .ndo_stop = rtl8192_close, | ||
12138 | .ndo_get_stats = rtl8192_stats, | ||
12139 | .ndo_tx_timeout = tx_timeout, | ||
12140 | .ndo_do_ioctl = rtl8192_ioctl, | ||
12141 | .ndo_set_multicast_list = r8192_set_multicast, | ||
12142 | .ndo_set_mac_address = r8192_set_mac_adr, | ||
12143 | .ndo_validate_addr = eth_validate_addr, | ||
12144 | .ndo_change_mtu = eth_change_mtu, | ||
12145 | .ndo_start_xmit = ieee80211_xmit, | ||
12146 | }; | ||
12147 | |||
12135 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) | 12148 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) |
12136 | static int __devinit rtl8192_usb_probe(struct usb_interface *intf, | 12149 | static int __devinit rtl8192_usb_probe(struct usb_interface *intf, |
12137 | const struct usb_device_id *id) | 12150 | const struct usb_device_id *id) |
@@ -12186,15 +12199,7 @@ static void * __devinit rtl8192_usb_probe(struct usb_device *udev, | |||
12186 | priv->ops = &rtl8192u_ops; | 12199 | priv->ops = &rtl8192u_ops; |
12187 | #endif | 12200 | #endif |
12188 | 12201 | ||
12189 | dev->open = rtl8192_open; | 12202 | dev->netdev_ops = &rtl8192_netdev_ops; |
12190 | dev->stop = rtl8192_close; | ||
12191 | //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit; | ||
12192 | dev->tx_timeout = tx_timeout; | ||
12193 | //dev->wireless_handlers = &r8192_wx_handlers_def; | ||
12194 | dev->do_ioctl = rtl8192_ioctl; | ||
12195 | dev->set_multicast_list = r8192_set_multicast; | ||
12196 | dev->set_mac_address = r8192_set_mac_adr; | ||
12197 | dev->get_stats = rtl8192_stats; | ||
12198 | 12203 | ||
12199 | //DMESG("Oops: i'm coming\n"); | 12204 | //DMESG("Oops: i'm coming\n"); |
12200 | #if WIRELESS_EXT >= 12 | 12205 | #if WIRELESS_EXT >= 12 |
diff --git a/drivers/staging/rtl8192su/r8192U_pm.c b/drivers/staging/rtl8192su/r8192U_pm.c index 92c95aa36638..b1531a8d0cde 100644 --- a/drivers/staging/rtl8192su/r8192U_pm.c +++ b/drivers/staging/rtl8192su/r8192U_pm.c | |||
@@ -35,7 +35,9 @@ int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state) | |||
35 | return 0; | 35 | return 0; |
36 | } | 36 | } |
37 | 37 | ||
38 | dev->stop(dev); | 38 | if (dev->netdev_ops->ndo_stop) |
39 | dev->netdev_ops->ndo_stop(dev); | ||
40 | |||
39 | mdelay(10); | 41 | mdelay(10); |
40 | 42 | ||
41 | netif_device_detach(dev); | 43 | netif_device_detach(dev); |
@@ -61,7 +63,9 @@ int rtl8192U_resume (struct usb_interface *intf) | |||
61 | } | 63 | } |
62 | 64 | ||
63 | netif_device_attach(dev); | 65 | netif_device_attach(dev); |
64 | dev->open(dev); | 66 | |
67 | if (dev->netdev_ops->ndo_open) | ||
68 | dev->netdev_ops->ndo_open(dev); | ||
65 | } | 69 | } |
66 | 70 | ||
67 | return 0; | 71 | return 0; |
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 90b29b564631..a9bd4106beb7 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c | |||
@@ -866,7 +866,7 @@ static void qt_release(struct usb_serial *serial) | |||
866 | 866 | ||
867 | } | 867 | } |
868 | 868 | ||
869 | int qt_open(struct tty_struct *tty, | 869 | static int qt_open(struct tty_struct *tty, |
870 | struct usb_serial_port *port, struct file *filp) | 870 | struct usb_serial_port *port, struct file *filp) |
871 | { | 871 | { |
872 | struct usb_serial *serial; | 872 | struct usb_serial *serial; |
@@ -1041,17 +1041,19 @@ static void qt_block_until_empty(struct tty_struct *tty, | |||
1041 | } | 1041 | } |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | static void qt_close(struct tty_struct *tty, struct usb_serial_port *port, | 1044 | static void qt_close( struct usb_serial_port *port) |
1045 | struct file *filp) | ||
1046 | { | 1045 | { |
1047 | struct usb_serial *serial = port->serial; | 1046 | struct usb_serial *serial = port->serial; |
1048 | struct quatech_port *qt_port; | 1047 | struct quatech_port *qt_port; |
1049 | struct quatech_port *port0; | 1048 | struct quatech_port *port0; |
1049 | struct tty_struct *tty; | ||
1050 | int status; | 1050 | int status; |
1051 | unsigned int index; | 1051 | unsigned int index; |
1052 | status = 0; | 1052 | status = 0; |
1053 | 1053 | ||
1054 | dbg("%s - port %d\n", __func__, port->number); | 1054 | dbg("%s - port %d\n", __func__, port->number); |
1055 | |||
1056 | tty = tty_port_tty_get(&port->port); | ||
1055 | index = tty->index - serial->minor; | 1057 | index = tty->index - serial->minor; |
1056 | 1058 | ||
1057 | qt_port = qt_get_port_private(port); | 1059 | qt_port = qt_get_port_private(port); |
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c index cfdaac9b747e..a137c78fac09 100644 --- a/drivers/staging/stlc45xx/stlc45xx.c +++ b/drivers/staging/stlc45xx/stlc45xx.c | |||
@@ -2235,24 +2235,6 @@ static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw, | |||
2235 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); | 2235 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); |
2236 | } | 2236 | } |
2237 | 2237 | ||
2238 | static int stlc45xx_op_config_interface(struct ieee80211_hw *hw, | ||
2239 | struct ieee80211_vif *vif, | ||
2240 | struct ieee80211_if_conf *conf) | ||
2241 | { | ||
2242 | struct stlc45xx *stlc = hw->priv; | ||
2243 | |||
2244 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); | ||
2245 | |||
2246 | mutex_lock(&stlc->mutex); | ||
2247 | |||
2248 | memcpy(stlc->bssid, conf->bssid, ETH_ALEN); | ||
2249 | stlc45xx_tx_setup(stlc); | ||
2250 | |||
2251 | mutex_unlock(&stlc->mutex); | ||
2252 | |||
2253 | return 0; | ||
2254 | } | ||
2255 | |||
2256 | static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed) | 2238 | static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed) |
2257 | { | 2239 | { |
2258 | struct stlc45xx *stlc = hw->priv; | 2240 | struct stlc45xx *stlc = hw->priv; |
@@ -2295,6 +2277,14 @@ static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2295 | { | 2277 | { |
2296 | struct stlc45xx *stlc = hw->priv; | 2278 | struct stlc45xx *stlc = hw->priv; |
2297 | 2279 | ||
2280 | stlc45xx_debug(DEBUG_FUNC, "%s", __func__); | ||
2281 | mutex_lock(&stlc->mutex); | ||
2282 | |||
2283 | memcpy(stlc->bssid, info->bssid, ETH_ALEN); | ||
2284 | stlc45xx_tx_setup(stlc); | ||
2285 | |||
2286 | mutex_unlock(&stlc->mutex); | ||
2287 | |||
2298 | if (changed & BSS_CHANGED_ASSOC) { | 2288 | if (changed & BSS_CHANGED_ASSOC) { |
2299 | stlc->associated = info->assoc; | 2289 | stlc->associated = info->assoc; |
2300 | if (info->assoc) | 2290 | if (info->assoc) |
@@ -2357,7 +2347,6 @@ static const struct ieee80211_ops stlc45xx_ops = { | |||
2357 | .add_interface = stlc45xx_op_add_interface, | 2347 | .add_interface = stlc45xx_op_add_interface, |
2358 | .remove_interface = stlc45xx_op_remove_interface, | 2348 | .remove_interface = stlc45xx_op_remove_interface, |
2359 | .config = stlc45xx_op_config, | 2349 | .config = stlc45xx_op_config, |
2360 | .config_interface = stlc45xx_op_config_interface, | ||
2361 | .configure_filter = stlc45xx_op_configure_filter, | 2350 | .configure_filter = stlc45xx_op_configure_filter, |
2362 | .tx = stlc45xx_op_tx, | 2351 | .tx = stlc45xx_op_tx, |
2363 | .bss_info_changed = stlc45xx_op_bss_info_changed, | 2352 | .bss_info_changed = stlc45xx_op_bss_info_changed, |
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 22f93dd0ba03..251220dc8851 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/smp_lock.h> | ||
21 | #include <linux/file.h> | 22 | #include <linux/file.h> |
22 | #include <linux/tcp.h> | 23 | #include <linux/tcp.h> |
23 | #include <linux/in.h> | 24 | #include <linux/in.h> |
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index a10ed27acbc2..f43ca416e4a8 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c | |||
@@ -344,7 +344,7 @@ static CHIP_INFO chip_info_table[]= { | |||
344 | }; | 344 | }; |
345 | 345 | ||
346 | static struct pci_device_id device_id_table[] __devinitdata = { | 346 | static struct pci_device_id device_id_table[] __devinitdata = { |
347 | { 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (int)&chip_info_table[0]}, | 347 | { 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long)&chip_info_table[0]}, |
348 | { 0, } | 348 | { 0, } |
349 | }; | 349 | }; |
350 | #endif | 350 | #endif |
@@ -369,7 +369,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | |||
369 | 369 | ||
370 | #ifdef CONFIG_PM | 370 | #ifdef CONFIG_PM |
371 | static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); | 371 | static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); |
372 | static int viawget_suspend(struct pci_dev *pcid, u32 state); | 372 | static int viawget_suspend(struct pci_dev *pcid, pm_message_t state); |
373 | static int viawget_resume(struct pci_dev *pcid); | 373 | static int viawget_resume(struct pci_dev *pcid); |
374 | struct notifier_block device_notifier = { | 374 | struct notifier_block device_notifier = { |
375 | notifier_call: device_notify_reboot, | 375 | notifier_call: device_notify_reboot, |
@@ -3941,7 +3941,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) | |||
3941 | while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { | 3941 | while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { |
3942 | if(pci_dev_driver(pdev) == &device_driver) { | 3942 | if(pci_dev_driver(pdev) == &device_driver) { |
3943 | if (pci_get_drvdata(pdev)) | 3943 | if (pci_get_drvdata(pdev)) |
3944 | viawget_suspend(pdev, 3); | 3944 | viawget_suspend(pdev, PMSG_HIBERNATE); |
3945 | } | 3945 | } |
3946 | } | 3946 | } |
3947 | } | 3947 | } |
@@ -3949,7 +3949,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) | |||
3949 | } | 3949 | } |
3950 | 3950 | ||
3951 | static int | 3951 | static int |
3952 | viawget_suspend(struct pci_dev *pcid, u32 state) | 3952 | viawget_suspend(struct pci_dev *pcid, pm_message_t state) |
3953 | { | 3953 | { |
3954 | int power_status; // to silence the compiler | 3954 | int power_status; // to silence the compiler |
3955 | 3955 | ||
@@ -3971,7 +3971,7 @@ viawget_suspend(struct pci_dev *pcid, u32 state) | |||
3971 | memset(pMgmt->abyCurrBSSID, 0, 6); | 3971 | memset(pMgmt->abyCurrBSSID, 0, 6); |
3972 | pMgmt->eCurrState = WMAC_STATE_IDLE; | 3972 | pMgmt->eCurrState = WMAC_STATE_IDLE; |
3973 | pci_disable_device(pcid); | 3973 | pci_disable_device(pcid); |
3974 | power_status = pci_set_power_state(pcid, state); | 3974 | power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state)); |
3975 | spin_unlock_irq(&pDevice->lock); | 3975 | spin_unlock_irq(&pDevice->lock); |
3976 | return 0; | 3976 | return 0; |
3977 | } | 3977 | } |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index a913efc69669..40de151f2789 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
@@ -257,6 +257,7 @@ | |||
257 | #include <linux/fs.h> /* everything... */ | 257 | #include <linux/fs.h> /* everything... */ |
258 | #include <linux/errno.h> /* error codes */ | 258 | #include <linux/errno.h> /* error codes */ |
259 | #include <linux/slab.h> | 259 | #include <linux/slab.h> |
260 | #include <linux/smp_lock.h> | ||
260 | #include <linux/mm.h> | 261 | #include <linux/mm.h> |
261 | #include <linux/ioport.h> | 262 | #include <linux/ioport.h> |
262 | #include <linux/interrupt.h> | 263 | #include <linux/interrupt.h> |
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index b52cc830c0b4..f3873f650bb4 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/phonedev.h> | 24 | #include <linux/phonedev.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
28 | #include <asm/system.h> | 27 | #include <asm/system.h> |
29 | 28 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 3f1045993474..e1f89416ef8c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm) | |||
387 | struct acm_ru *rcv; | 387 | struct acm_ru *rcv; |
388 | unsigned long flags; | 388 | unsigned long flags; |
389 | unsigned char throttled; | 389 | unsigned char throttled; |
390 | struct usb_host_endpoint *ep; | ||
390 | 391 | ||
391 | dbg("Entering acm_rx_tasklet"); | 392 | dbg("Entering acm_rx_tasklet"); |
392 | 393 | ||
@@ -462,11 +463,20 @@ urbs: | |||
462 | 463 | ||
463 | rcv->buffer = buf; | 464 | rcv->buffer = buf; |
464 | 465 | ||
465 | usb_fill_bulk_urb(rcv->urb, acm->dev, | 466 | ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out) |
466 | acm->rx_endpoint, | 467 | [usb_pipeendpoint(acm->rx_endpoint)]; |
467 | buf->base, | 468 | if (usb_endpoint_xfer_int(&ep->desc)) |
468 | acm->readsize, | 469 | usb_fill_int_urb(rcv->urb, acm->dev, |
469 | acm_read_bulk, rcv); | 470 | acm->rx_endpoint, |
471 | buf->base, | ||
472 | acm->readsize, | ||
473 | acm_read_bulk, rcv, ep->desc.bInterval); | ||
474 | else | ||
475 | usb_fill_bulk_urb(rcv->urb, acm->dev, | ||
476 | acm->rx_endpoint, | ||
477 | buf->base, | ||
478 | acm->readsize, | ||
479 | acm_read_bulk, rcv); | ||
470 | rcv->urb->transfer_dma = buf->dma; | 480 | rcv->urb->transfer_dma = buf->dma; |
471 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 481 | rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
472 | 482 | ||
@@ -740,7 +750,7 @@ static int acm_tty_chars_in_buffer(struct tty_struct *tty) | |||
740 | { | 750 | { |
741 | struct acm *acm = tty->driver_data; | 751 | struct acm *acm = tty->driver_data; |
742 | if (!ACM_READY(acm)) | 752 | if (!ACM_READY(acm)) |
743 | return -EINVAL; | 753 | return 0; |
744 | /* | 754 | /* |
745 | * This is inaccurate (overcounts), but it works. | 755 | * This is inaccurate (overcounts), but it works. |
746 | */ | 756 | */ |
@@ -1227,9 +1237,14 @@ made_compressed_probe: | |||
1227 | goto alloc_fail7; | 1237 | goto alloc_fail7; |
1228 | } | 1238 | } |
1229 | 1239 | ||
1230 | usb_fill_bulk_urb(snd->urb, usb_dev, | 1240 | if (usb_endpoint_xfer_int(epwrite)) |
1231 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | 1241 | usb_fill_int_urb(snd->urb, usb_dev, |
1232 | NULL, acm->writesize, acm_write_bulk, snd); | 1242 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), |
1243 | NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); | ||
1244 | else | ||
1245 | usb_fill_bulk_urb(snd->urb, usb_dev, | ||
1246 | usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), | ||
1247 | NULL, acm->writesize, acm_write_bulk, snd); | ||
1233 | snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1248 | snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1234 | snd->instance = acm; | 1249 | snd->instance = acm; |
1235 | } | 1250 | } |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 0fe434505ac4..ba589d4ca8bc 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
20 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
21 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 3703789d0d2a..b09a527f7341 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
751 | { | 751 | { |
752 | struct device *dev = &data->usb_dev->dev; | 752 | struct device *dev = &data->usb_dev->dev; |
753 | char *buffer; | 753 | char *buffer; |
754 | int rv; | 754 | int rv = 0; |
755 | 755 | ||
756 | buffer = kmalloc(0x18, GFP_KERNEL); | 756 | buffer = kmalloc(0x18, GFP_KERNEL); |
757 | if (!buffer) | 757 | if (!buffer) |
@@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
763 | 0, 0, buffer, 0x18, USBTMC_TIMEOUT); | 763 | 0, 0, buffer, 0x18, USBTMC_TIMEOUT); |
764 | if (rv < 0) { | 764 | if (rv < 0) { |
765 | dev_err(dev, "usb_control_msg returned %d\n", rv); | 765 | dev_err(dev, "usb_control_msg returned %d\n", rv); |
766 | return rv; | 766 | goto err_out; |
767 | } | 767 | } |
768 | 768 | ||
769 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 769 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
@@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
773 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); | 773 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); |
774 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { | 774 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { |
775 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 775 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
776 | return -EPERM; | 776 | rv = -EPERM; |
777 | goto err_out; | ||
777 | } | 778 | } |
778 | 779 | ||
779 | data->capabilities.interface_capabilities = buffer[4]; | 780 | data->capabilities.interface_capabilities = buffer[4]; |
@@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
781 | data->capabilities.usb488_interface_capabilities = buffer[14]; | 782 | data->capabilities.usb488_interface_capabilities = buffer[14]; |
782 | data->capabilities.usb488_device_capabilities = buffer[15]; | 783 | data->capabilities.usb488_device_capabilities = buffer[15]; |
783 | 784 | ||
785 | err_out: | ||
784 | kfree(buffer); | 786 | kfree(buffer); |
785 | return 0; | 787 | return rv; |
786 | } | 788 | } |
787 | 789 | ||
788 | #define capability_attribute(name) \ | 790 | #define capability_attribute(name) \ |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 69280c35b5cb..ad925946f869 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -28,7 +28,7 @@ comment "Miscellaneous USB options" | |||
28 | depends on USB | 28 | depends on USB |
29 | 29 | ||
30 | config USB_DEVICEFS | 30 | config USB_DEVICEFS |
31 | bool "USB device filesystem (DEPRECATED)" if EMBEDDED | 31 | bool "USB device filesystem (DEPRECATED)" |
32 | depends on USB | 32 | depends on USB |
33 | ---help--- | 33 | ---help--- |
34 | If you say Y here (and to "/proc file system support" in the "File | 34 | If you say Y here (and to "/proc file system support" in the "File |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 73c108d117b4..96f11715cd26 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -136,17 +136,19 @@ static const struct class_info clas_info[] = | |||
136 | {USB_CLASS_AUDIO, "audio"}, | 136 | {USB_CLASS_AUDIO, "audio"}, |
137 | {USB_CLASS_COMM, "comm."}, | 137 | {USB_CLASS_COMM, "comm."}, |
138 | {USB_CLASS_HID, "HID"}, | 138 | {USB_CLASS_HID, "HID"}, |
139 | {USB_CLASS_HUB, "hub"}, | ||
140 | {USB_CLASS_PHYSICAL, "PID"}, | 139 | {USB_CLASS_PHYSICAL, "PID"}, |
140 | {USB_CLASS_STILL_IMAGE, "still"}, | ||
141 | {USB_CLASS_PRINTER, "print"}, | 141 | {USB_CLASS_PRINTER, "print"}, |
142 | {USB_CLASS_MASS_STORAGE, "stor."}, | 142 | {USB_CLASS_MASS_STORAGE, "stor."}, |
143 | {USB_CLASS_HUB, "hub"}, | ||
143 | {USB_CLASS_CDC_DATA, "data"}, | 144 | {USB_CLASS_CDC_DATA, "data"}, |
144 | {USB_CLASS_APP_SPEC, "app."}, | ||
145 | {USB_CLASS_VENDOR_SPEC, "vend."}, | ||
146 | {USB_CLASS_STILL_IMAGE, "still"}, | ||
147 | {USB_CLASS_CSCID, "scard"}, | 145 | {USB_CLASS_CSCID, "scard"}, |
148 | {USB_CLASS_CONTENT_SEC, "c-sec"}, | 146 | {USB_CLASS_CONTENT_SEC, "c-sec"}, |
149 | {USB_CLASS_VIDEO, "video"}, | 147 | {USB_CLASS_VIDEO, "video"}, |
148 | {USB_CLASS_WIRELESS_CONTROLLER, "wlcon"}, | ||
149 | {USB_CLASS_MISC, "misc"}, | ||
150 | {USB_CLASS_APP_SPEC, "app."}, | ||
151 | {USB_CLASS_VENDOR_SPEC, "vend."}, | ||
150 | {-1, "unk."} /* leave as last */ | 152 | {-1, "unk."} /* leave as last */ |
151 | }; | 153 | }; |
152 | 154 | ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 308609039c73..38b8bce782d6 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -325,21 +325,34 @@ static void async_completed(struct urb *urb) | |||
325 | struct async *as = urb->context; | 325 | struct async *as = urb->context; |
326 | struct dev_state *ps = as->ps; | 326 | struct dev_state *ps = as->ps; |
327 | struct siginfo sinfo; | 327 | struct siginfo sinfo; |
328 | struct pid *pid = NULL; | ||
329 | uid_t uid = 0; | ||
330 | uid_t euid = 0; | ||
331 | u32 secid = 0; | ||
332 | int signr; | ||
328 | 333 | ||
329 | spin_lock(&ps->lock); | 334 | spin_lock(&ps->lock); |
330 | list_move_tail(&as->asynclist, &ps->async_completed); | 335 | list_move_tail(&as->asynclist, &ps->async_completed); |
331 | spin_unlock(&ps->lock); | ||
332 | as->status = urb->status; | 336 | as->status = urb->status; |
333 | if (as->signr) { | 337 | signr = as->signr; |
338 | if (signr) { | ||
334 | sinfo.si_signo = as->signr; | 339 | sinfo.si_signo = as->signr; |
335 | sinfo.si_errno = as->status; | 340 | sinfo.si_errno = as->status; |
336 | sinfo.si_code = SI_ASYNCIO; | 341 | sinfo.si_code = SI_ASYNCIO; |
337 | sinfo.si_addr = as->userurb; | 342 | sinfo.si_addr = as->userurb; |
338 | kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, | 343 | pid = as->pid; |
339 | as->euid, as->secid); | 344 | uid = as->uid; |
345 | euid = as->euid; | ||
346 | secid = as->secid; | ||
340 | } | 347 | } |
341 | snoop(&urb->dev->dev, "urb complete\n"); | 348 | snoop(&urb->dev->dev, "urb complete\n"); |
342 | snoop_urb(urb, as->userurb); | 349 | snoop_urb(urb, as->userurb); |
350 | spin_unlock(&ps->lock); | ||
351 | |||
352 | if (signr) | ||
353 | kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid, | ||
354 | euid, secid); | ||
355 | |||
343 | wake_up(&ps->wait); | 356 | wake_up(&ps->wait); |
344 | } | 357 | } |
345 | 358 | ||
@@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
982 | USBDEVFS_URB_ZERO_PACKET | | 995 | USBDEVFS_URB_ZERO_PACKET | |
983 | USBDEVFS_URB_NO_INTERRUPT)) | 996 | USBDEVFS_URB_NO_INTERRUPT)) |
984 | return -EINVAL; | 997 | return -EINVAL; |
985 | if (!uurb->buffer) | 998 | if (uurb->buffer_length > 0 && !uurb->buffer) |
986 | return -EINVAL; | 999 | return -EINVAL; |
987 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && | 1000 | if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && |
988 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { | 1001 | (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { |
@@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1038 | is_in = 0; | 1051 | is_in = 0; |
1039 | uurb->endpoint &= ~USB_DIR_IN; | 1052 | uurb->endpoint &= ~USB_DIR_IN; |
1040 | } | 1053 | } |
1041 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
1042 | uurb->buffer, uurb->buffer_length)) { | ||
1043 | kfree(dr); | ||
1044 | return -EFAULT; | ||
1045 | } | ||
1046 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " | 1054 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " |
1047 | "bRrequestType=%02x wValue=%04x " | 1055 | "bRrequestType=%02x wValue=%04x " |
1048 | "wIndex=%04x wLength=%04x\n", | 1056 | "wIndex=%04x wLength=%04x\n", |
@@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1062 | uurb->number_of_packets = 0; | 1070 | uurb->number_of_packets = 0; |
1063 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1071 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1064 | return -EINVAL; | 1072 | return -EINVAL; |
1065 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
1066 | uurb->buffer, uurb->buffer_length)) | ||
1067 | return -EFAULT; | ||
1068 | snoop(&ps->dev->dev, "bulk urb\n"); | 1073 | snoop(&ps->dev->dev, "bulk urb\n"); |
1069 | break; | 1074 | break; |
1070 | 1075 | ||
@@ -1106,28 +1111,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1106 | return -EINVAL; | 1111 | return -EINVAL; |
1107 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1112 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1108 | return -EINVAL; | 1113 | return -EINVAL; |
1109 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
1110 | uurb->buffer, uurb->buffer_length)) | ||
1111 | return -EFAULT; | ||
1112 | snoop(&ps->dev->dev, "interrupt urb\n"); | 1114 | snoop(&ps->dev->dev, "interrupt urb\n"); |
1113 | break; | 1115 | break; |
1114 | 1116 | ||
1115 | default: | 1117 | default: |
1116 | return -EINVAL; | 1118 | return -EINVAL; |
1117 | } | 1119 | } |
1118 | as = alloc_async(uurb->number_of_packets); | 1120 | if (uurb->buffer_length > 0 && |
1119 | if (!as) { | 1121 | !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, |
1122 | uurb->buffer, uurb->buffer_length)) { | ||
1120 | kfree(isopkt); | 1123 | kfree(isopkt); |
1121 | kfree(dr); | 1124 | kfree(dr); |
1122 | return -ENOMEM; | 1125 | return -EFAULT; |
1123 | } | 1126 | } |
1124 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL); | 1127 | as = alloc_async(uurb->number_of_packets); |
1125 | if (!as->urb->transfer_buffer) { | 1128 | if (!as) { |
1126 | kfree(isopkt); | 1129 | kfree(isopkt); |
1127 | kfree(dr); | 1130 | kfree(dr); |
1128 | free_async(as); | ||
1129 | return -ENOMEM; | 1131 | return -ENOMEM; |
1130 | } | 1132 | } |
1133 | if (uurb->buffer_length > 0) { | ||
1134 | as->urb->transfer_buffer = kmalloc(uurb->buffer_length, | ||
1135 | GFP_KERNEL); | ||
1136 | if (!as->urb->transfer_buffer) { | ||
1137 | kfree(isopkt); | ||
1138 | kfree(dr); | ||
1139 | free_async(as); | ||
1140 | return -ENOMEM; | ||
1141 | } | ||
1142 | } | ||
1131 | as->urb->dev = ps->dev; | 1143 | as->urb->dev = ps->dev; |
1132 | as->urb->pipe = (uurb->type << 30) | | 1144 | as->urb->pipe = (uurb->type << 30) | |
1133 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | | 1145 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | |
@@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1169 | kfree(isopkt); | 1181 | kfree(isopkt); |
1170 | as->ps = ps; | 1182 | as->ps = ps; |
1171 | as->userurb = arg; | 1183 | as->userurb = arg; |
1172 | if (uurb->endpoint & USB_DIR_IN) | 1184 | if (is_in && uurb->buffer_length > 0) |
1173 | as->userbuffer = uurb->buffer; | 1185 | as->userbuffer = uurb->buffer; |
1174 | else | 1186 | else |
1175 | as->userbuffer = NULL; | 1187 | as->userbuffer = NULL; |
@@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1179 | as->uid = cred->uid; | 1191 | as->uid = cred->uid; |
1180 | as->euid = cred->euid; | 1192 | as->euid = cred->euid; |
1181 | security_task_getsecid(current, &as->secid); | 1193 | security_task_getsecid(current, &as->secid); |
1182 | if (!is_in) { | 1194 | if (!is_in && uurb->buffer_length > 0) { |
1183 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, | 1195 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, |
1184 | as->urb->transfer_buffer_length)) { | 1196 | uurb->buffer_length)) { |
1185 | free_async(as); | 1197 | free_async(as); |
1186 | return -EFAULT; | 1198 | return -EFAULT; |
1187 | } | 1199 | } |
@@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1231 | if (as->userbuffer) | 1243 | if (as->userbuffer) |
1232 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1244 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, |
1233 | urb->transfer_buffer_length)) | 1245 | urb->transfer_buffer_length)) |
1234 | return -EFAULT; | 1246 | goto err_out; |
1235 | if (put_user(as->status, &userurb->status)) | 1247 | if (put_user(as->status, &userurb->status)) |
1236 | return -EFAULT; | 1248 | goto err_out; |
1237 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1249 | if (put_user(urb->actual_length, &userurb->actual_length)) |
1238 | return -EFAULT; | 1250 | goto err_out; |
1239 | if (put_user(urb->error_count, &userurb->error_count)) | 1251 | if (put_user(urb->error_count, &userurb->error_count)) |
1240 | return -EFAULT; | 1252 | goto err_out; |
1241 | 1253 | ||
1242 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { | 1254 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { |
1243 | for (i = 0; i < urb->number_of_packets; i++) { | 1255 | for (i = 0; i < urb->number_of_packets; i++) { |
1244 | if (put_user(urb->iso_frame_desc[i].actual_length, | 1256 | if (put_user(urb->iso_frame_desc[i].actual_length, |
1245 | &userurb->iso_frame_desc[i].actual_length)) | 1257 | &userurb->iso_frame_desc[i].actual_length)) |
1246 | return -EFAULT; | 1258 | goto err_out; |
1247 | if (put_user(urb->iso_frame_desc[i].status, | 1259 | if (put_user(urb->iso_frame_desc[i].status, |
1248 | &userurb->iso_frame_desc[i].status)) | 1260 | &userurb->iso_frame_desc[i].status)) |
1249 | return -EFAULT; | 1261 | goto err_out; |
1250 | } | 1262 | } |
1251 | } | 1263 | } |
1252 | 1264 | ||
@@ -1255,6 +1267,10 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1255 | if (put_user(addr, (void __user * __user *)arg)) | 1267 | if (put_user(addr, (void __user * __user *)arg)) |
1256 | return -EFAULT; | 1268 | return -EFAULT; |
1257 | return 0; | 1269 | return 0; |
1270 | |||
1271 | err_out: | ||
1272 | free_async(as); | ||
1273 | return -EFAULT; | ||
1258 | } | 1274 | } |
1259 | 1275 | ||
1260 | static struct async *reap_as(struct dev_state *ps) | 1276 | static struct async *reap_as(struct dev_state *ps) |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index d397ecfd5b17..ec5c67ea07b7 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -227,6 +227,10 @@ struct hc_driver { | |||
227 | /* has a port been handed over to a companion? */ | 227 | /* has a port been handed over to a companion? */ |
228 | int (*port_handed_over)(struct usb_hcd *, int); | 228 | int (*port_handed_over)(struct usb_hcd *, int); |
229 | 229 | ||
230 | /* CLEAR_TT_BUFFER completion callback */ | ||
231 | void (*clear_tt_buffer_complete)(struct usb_hcd *, | ||
232 | struct usb_host_endpoint *); | ||
233 | |||
230 | /* xHCI specific functions */ | 234 | /* xHCI specific functions */ |
231 | /* Called by usb_alloc_dev to alloc HC device structures */ | 235 | /* Called by usb_alloc_dev to alloc HC device structures */ |
232 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); | 236 | int (*alloc_dev)(struct usb_hcd *, struct usb_device *); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2af3b4f06054..71f86c60d83c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -450,10 +450,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) | |||
450 | * talking to TTs must queue control transfers (not just bulk and iso), so | 450 | * talking to TTs must queue control transfers (not just bulk and iso), so |
451 | * both can talk to the same hub concurrently. | 451 | * both can talk to the same hub concurrently. |
452 | */ | 452 | */ |
453 | static void hub_tt_kevent (struct work_struct *work) | 453 | static void hub_tt_work(struct work_struct *work) |
454 | { | 454 | { |
455 | struct usb_hub *hub = | 455 | struct usb_hub *hub = |
456 | container_of(work, struct usb_hub, tt.kevent); | 456 | container_of(work, struct usb_hub, tt.clear_work); |
457 | unsigned long flags; | 457 | unsigned long flags; |
458 | int limit = 100; | 458 | int limit = 100; |
459 | 459 | ||
@@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work) | |||
462 | struct list_head *next; | 462 | struct list_head *next; |
463 | struct usb_tt_clear *clear; | 463 | struct usb_tt_clear *clear; |
464 | struct usb_device *hdev = hub->hdev; | 464 | struct usb_device *hdev = hub->hdev; |
465 | const struct hc_driver *drv; | ||
465 | int status; | 466 | int status; |
466 | 467 | ||
467 | next = hub->tt.clear_list.next; | 468 | next = hub->tt.clear_list.next; |
@@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work) | |||
471 | /* drop lock so HCD can concurrently report other TT errors */ | 472 | /* drop lock so HCD can concurrently report other TT errors */ |
472 | spin_unlock_irqrestore (&hub->tt.lock, flags); | 473 | spin_unlock_irqrestore (&hub->tt.lock, flags); |
473 | status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); | 474 | status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt); |
474 | spin_lock_irqsave (&hub->tt.lock, flags); | ||
475 | |||
476 | if (status) | 475 | if (status) |
477 | dev_err (&hdev->dev, | 476 | dev_err (&hdev->dev, |
478 | "clear tt %d (%04x) error %d\n", | 477 | "clear tt %d (%04x) error %d\n", |
479 | clear->tt, clear->devinfo, status); | 478 | clear->tt, clear->devinfo, status); |
479 | |||
480 | /* Tell the HCD, even if the operation failed */ | ||
481 | drv = clear->hcd->driver; | ||
482 | if (drv->clear_tt_buffer_complete) | ||
483 | (drv->clear_tt_buffer_complete)(clear->hcd, clear->ep); | ||
484 | |||
480 | kfree(clear); | 485 | kfree(clear); |
486 | spin_lock_irqsave(&hub->tt.lock, flags); | ||
481 | } | 487 | } |
482 | spin_unlock_irqrestore (&hub->tt.lock, flags); | 488 | spin_unlock_irqrestore (&hub->tt.lock, flags); |
483 | } | 489 | } |
484 | 490 | ||
485 | /** | 491 | /** |
486 | * usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub | 492 | * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub |
487 | * @udev: the device whose split transaction failed | 493 | * @urb: an URB associated with the failed or incomplete split transaction |
488 | * @pipe: identifies the endpoint of the failed transaction | ||
489 | * | 494 | * |
490 | * High speed HCDs use this to tell the hub driver that some split control or | 495 | * High speed HCDs use this to tell the hub driver that some split control or |
491 | * bulk transaction failed in a way that requires clearing internal state of | 496 | * bulk transaction failed in a way that requires clearing internal state of |
@@ -495,8 +500,10 @@ static void hub_tt_kevent (struct work_struct *work) | |||
495 | * It may not be possible for that hub to handle additional full (or low) | 500 | * It may not be possible for that hub to handle additional full (or low) |
496 | * speed transactions until that state is fully cleared out. | 501 | * speed transactions until that state is fully cleared out. |
497 | */ | 502 | */ |
498 | void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | 503 | int usb_hub_clear_tt_buffer(struct urb *urb) |
499 | { | 504 | { |
505 | struct usb_device *udev = urb->dev; | ||
506 | int pipe = urb->pipe; | ||
500 | struct usb_tt *tt = udev->tt; | 507 | struct usb_tt *tt = udev->tt; |
501 | unsigned long flags; | 508 | unsigned long flags; |
502 | struct usb_tt_clear *clear; | 509 | struct usb_tt_clear *clear; |
@@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
508 | if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { | 515 | if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) { |
509 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); | 516 | dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); |
510 | /* FIXME recover somehow ... RESET_TT? */ | 517 | /* FIXME recover somehow ... RESET_TT? */ |
511 | return; | 518 | return -ENOMEM; |
512 | } | 519 | } |
513 | 520 | ||
514 | /* info that CLEAR_TT_BUFFER needs */ | 521 | /* info that CLEAR_TT_BUFFER needs */ |
@@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) | |||
520 | : (USB_ENDPOINT_XFER_BULK << 11); | 527 | : (USB_ENDPOINT_XFER_BULK << 11); |
521 | if (usb_pipein (pipe)) | 528 | if (usb_pipein (pipe)) |
522 | clear->devinfo |= 1 << 15; | 529 | clear->devinfo |= 1 << 15; |
523 | 530 | ||
531 | /* info for completion callback */ | ||
532 | clear->hcd = bus_to_hcd(udev->bus); | ||
533 | clear->ep = urb->ep; | ||
534 | |||
524 | /* tell keventd to clear state for this TT */ | 535 | /* tell keventd to clear state for this TT */ |
525 | spin_lock_irqsave (&tt->lock, flags); | 536 | spin_lock_irqsave (&tt->lock, flags); |
526 | list_add_tail (&clear->clear_list, &tt->clear_list); | 537 | list_add_tail (&clear->clear_list, &tt->clear_list); |
527 | schedule_work (&tt->kevent); | 538 | schedule_work(&tt->clear_work); |
528 | spin_unlock_irqrestore (&tt->lock, flags); | 539 | spin_unlock_irqrestore (&tt->lock, flags); |
540 | return 0; | ||
529 | } | 541 | } |
530 | EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer); | 542 | EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer); |
531 | 543 | ||
532 | /* If do_delay is false, return the number of milliseconds the caller | 544 | /* If do_delay is false, return the number of milliseconds the caller |
533 | * needs to delay. | 545 | * needs to delay. |
@@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
818 | if (hub->has_indicators) | 830 | if (hub->has_indicators) |
819 | cancel_delayed_work_sync(&hub->leds); | 831 | cancel_delayed_work_sync(&hub->leds); |
820 | if (hub->tt.hub) | 832 | if (hub->tt.hub) |
821 | cancel_work_sync(&hub->tt.kevent); | 833 | cancel_work_sync(&hub->tt.clear_work); |
822 | } | 834 | } |
823 | 835 | ||
824 | /* caller has locked the hub device */ | 836 | /* caller has locked the hub device */ |
@@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub, | |||
935 | 947 | ||
936 | spin_lock_init (&hub->tt.lock); | 948 | spin_lock_init (&hub->tt.lock); |
937 | INIT_LIST_HEAD (&hub->tt.clear_list); | 949 | INIT_LIST_HEAD (&hub->tt.clear_list); |
938 | INIT_WORK (&hub->tt.kevent, hub_tt_kevent); | 950 | INIT_WORK(&hub->tt.clear_work, hub_tt_work); |
939 | switch (hdev->descriptor.bDeviceProtocol) { | 951 | switch (hdev->descriptor.bDeviceProtocol) { |
940 | case 0: | 952 | case 0: |
941 | break; | 953 | break; |
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h index 889c0f32a40b..de8081f065ed 100644 --- a/drivers/usb/core/hub.h +++ b/drivers/usb/core/hub.h | |||
@@ -188,16 +188,18 @@ struct usb_tt { | |||
188 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ | 188 | /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ |
189 | spinlock_t lock; | 189 | spinlock_t lock; |
190 | struct list_head clear_list; /* of usb_tt_clear */ | 190 | struct list_head clear_list; /* of usb_tt_clear */ |
191 | struct work_struct kevent; | 191 | struct work_struct clear_work; |
192 | }; | 192 | }; |
193 | 193 | ||
194 | struct usb_tt_clear { | 194 | struct usb_tt_clear { |
195 | struct list_head clear_list; | 195 | struct list_head clear_list; |
196 | unsigned tt; | 196 | unsigned tt; |
197 | u16 devinfo; | 197 | u16 devinfo; |
198 | struct usb_hcd *hcd; | ||
199 | struct usb_host_endpoint *ep; | ||
198 | }; | 200 | }; |
199 | 201 | ||
200 | extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe); | 202 | extern int usb_hub_clear_tt_buffer(struct urb *urb); |
201 | extern void usb_ep0_reinit(struct usb_device *); | 203 | extern void usb_ep0_reinit(struct usb_device *); |
202 | 204 | ||
203 | #endif /* __LINUX_HUB_H */ | 205 | #endif /* __LINUX_HUB_H */ |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 2bed83caacb1..9720e699f472 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid, | |||
806 | return rc; | 806 | return rc; |
807 | } | 807 | } |
808 | 808 | ||
809 | static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf) | ||
810 | { | ||
811 | int err; | ||
812 | |||
813 | if (dev->have_langid) | ||
814 | return 0; | ||
815 | |||
816 | if (dev->string_langid < 0) | ||
817 | return -EPIPE; | ||
818 | |||
819 | err = usb_string_sub(dev, 0, 0, tbuf); | ||
820 | |||
821 | /* If the string was reported but is malformed, default to english | ||
822 | * (0x0409) */ | ||
823 | if (err == -ENODATA || (err > 0 && err < 4)) { | ||
824 | dev->string_langid = 0x0409; | ||
825 | dev->have_langid = 1; | ||
826 | dev_err(&dev->dev, | ||
827 | "string descriptor 0 malformed (err = %d), " | ||
828 | "defaulting to 0x%04x\n", | ||
829 | err, dev->string_langid); | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | /* In case of all other errors, we assume the device is not able to | ||
834 | * deal with strings at all. Set string_langid to -1 in order to | ||
835 | * prevent any string to be retrieved from the device */ | ||
836 | if (err < 0) { | ||
837 | dev_err(&dev->dev, "string descriptor 0 read error: %d\n", | ||
838 | err); | ||
839 | dev->string_langid = -1; | ||
840 | return -EPIPE; | ||
841 | } | ||
842 | |||
843 | /* always use the first langid listed */ | ||
844 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
845 | dev->have_langid = 1; | ||
846 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
847 | dev->string_langid); | ||
848 | return 0; | ||
849 | } | ||
850 | |||
809 | /** | 851 | /** |
810 | * usb_string - returns UTF-8 version of a string descriptor | 852 | * usb_string - returns UTF-8 version of a string descriptor |
811 | * @dev: the device whose string descriptor is being retrieved | 853 | * @dev: the device whose string descriptor is being retrieved |
@@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
837 | if (!tbuf) | 879 | if (!tbuf) |
838 | return -ENOMEM; | 880 | return -ENOMEM; |
839 | 881 | ||
840 | /* get langid for strings if it's not yet known */ | 882 | err = usb_get_langid(dev, tbuf); |
841 | if (!dev->have_langid) { | 883 | if (err < 0) |
842 | err = usb_string_sub(dev, 0, 0, tbuf); | 884 | goto errout; |
843 | if (err < 0) { | ||
844 | dev_err(&dev->dev, | ||
845 | "string descriptor 0 read error: %d\n", | ||
846 | err); | ||
847 | } else if (err < 4) { | ||
848 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | ||
849 | } else { | ||
850 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | ||
851 | /* always use the first langid listed */ | ||
852 | dev_dbg(&dev->dev, "default language 0x%04x\n", | ||
853 | dev->string_langid); | ||
854 | } | ||
855 | |||
856 | dev->have_langid = 1; | ||
857 | } | ||
858 | 885 | ||
859 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 886 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
860 | if (err < 0) | 887 | if (err < 0) |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5d1ddf485d1e..7f8e83a954ac 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -286,6 +286,27 @@ config USB_S3C_HSOTG | |||
286 | default USB_GADGET | 286 | default USB_GADGET |
287 | select USB_GADGET_SELECTED | 287 | select USB_GADGET_SELECTED |
288 | 288 | ||
289 | config USB_GADGET_IMX | ||
290 | boolean "Freescale IMX USB Peripheral Controller" | ||
291 | depends on ARCH_MX1 | ||
292 | help | ||
293 | Freescale's IMX series include an integrated full speed | ||
294 | USB 1.1 device controller. The controller in the IMX series | ||
295 | is register-compatible. | ||
296 | |||
297 | It has Six fixed-function endpoints, as well as endpoint | ||
298 | zero (for control transfers). | ||
299 | |||
300 | Say "y" to link the driver statically, or "m" to build a | ||
301 | dynamically linked module called "imx_udc" and force all | ||
302 | gadget drivers to also be dynamically linked. | ||
303 | |||
304 | config USB_IMX | ||
305 | tristate | ||
306 | depends on USB_GADGET_IMX | ||
307 | default USB_GADGET | ||
308 | select USB_GADGET_SELECTED | ||
309 | |||
289 | config USB_GADGET_S3C2410 | 310 | config USB_GADGET_S3C2410 |
290 | boolean "S3C2410 USB Device Controller" | 311 | boolean "S3C2410 USB Device Controller" |
291 | depends on ARCH_S3C2410 | 312 | depends on ARCH_S3C2410 |
@@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC | |||
321 | This OTG-capable silicon IP is used in dual designs including | 342 | This OTG-capable silicon IP is used in dual designs including |
322 | the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin | 343 | the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin |
323 | 344 | ||
324 | config USB_GADGET_IMX | ||
325 | boolean "Freescale IMX USB Peripheral Controller" | ||
326 | depends on ARCH_MX1 | ||
327 | help | ||
328 | Freescale's IMX series include an integrated full speed | ||
329 | USB 1.1 device controller. The controller in the IMX series | ||
330 | is register-compatible. | ||
331 | |||
332 | It has Six fixed-function endpoints, as well as endpoint | ||
333 | zero (for control transfers). | ||
334 | |||
335 | Say "y" to link the driver statically, or "m" to build a | ||
336 | dynamically linked module called "imx_udc" and force all | ||
337 | gadget drivers to also be dynamically linked. | ||
338 | |||
339 | config USB_IMX | ||
340 | tristate | ||
341 | depends on USB_GADGET_IMX | ||
342 | default USB_GADGET | ||
343 | select USB_GADGET_SELECTED | ||
344 | |||
345 | config USB_GADGET_M66592 | 345 | config USB_GADGET_M66592 |
346 | boolean "Renesas M66592 USB Peripheral Controller" | 346 | boolean "Renesas M66592 USB Peripheral Controller" |
347 | select USB_GADGET_DUALSPEED | 347 | select USB_GADGET_DUALSPEED |
@@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST | |||
604 | config USB_AUDIO | 604 | config USB_AUDIO |
605 | tristate "Audio Gadget (EXPERIMENTAL)" | 605 | tristate "Audio Gadget (EXPERIMENTAL)" |
606 | depends on SND | 606 | depends on SND |
607 | select SND_PCM | ||
607 | help | 608 | help |
608 | Gadget Audio is compatible with USB Audio Class specification 1.0. | 609 | Gadget Audio is compatible with USB Audio Class specification 1.0. |
609 | It will include at least one AudioControl interface, zero or more | 610 | It will include at least one AudioControl interface, zero or more |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 826f3adde5d8..77352ccc245e 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <linux/ioport.h> | 48 | #include <linux/ioport.h> |
49 | #include <linux/sched.h> | 49 | #include <linux/sched.h> |
50 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
51 | #include <linux/smp_lock.h> | ||
52 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
53 | #include <linux/init.h> | 52 | #include <linux/init.h> |
54 | #include <linux/timer.h> | 53 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/audio.c b/drivers/usb/gadget/audio.c index 94de7e864614..9f80f4e970bd 100644 --- a/drivers/usb/gadget/audio.c +++ b/drivers/usb/gadget/audio.c | |||
@@ -42,9 +42,9 @@ | |||
42 | * Instead: allocate your own, using normal USB-IF procedures. | 42 | * Instead: allocate your own, using normal USB-IF procedures. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | /* Thanks to NetChip Technologies for donating this product ID. */ | 45 | /* Thanks to Linux Foundation for donating this product ID. */ |
46 | #define AUDIO_VENDOR_NUM 0x0525 /* NetChip */ | 46 | #define AUDIO_VENDOR_NUM 0x1d6b /* Linux Foundation */ |
47 | #define AUDIO_PRODUCT_NUM 0xa4a1 /* Linux-USB Audio Gadget */ | 47 | #define AUDIO_PRODUCT_NUM 0x0101 /* Linux-USB Audio Gadget */ |
48 | 48 | ||
49 | /*-------------------------------------------------------------------------*/ | 49 | /*-------------------------------------------------------------------------*/ |
50 | 50 | ||
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index d006dc652e02..bd102f5052ba 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev) | |||
293 | /* CDC Subset */ | 293 | /* CDC Subset */ |
294 | eth_config_driver.label = "CDC Subset/SAFE"; | 294 | eth_config_driver.label = "CDC Subset/SAFE"; |
295 | 295 | ||
296 | device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM), | 296 | device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM); |
297 | device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM), | 297 | device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM); |
298 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 298 | if (!has_rndis()) |
299 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | ||
299 | } | 300 | } |
300 | 301 | ||
301 | if (has_rndis()) { | 302 | if (has_rndis()) { |
302 | /* RNDIS plus ECM-or-Subset */ | 303 | /* RNDIS plus ECM-or-Subset */ |
303 | device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM), | 304 | device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM); |
304 | device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM), | 305 | device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM); |
305 | device_desc.bNumConfigurations = 2; | 306 | device_desc.bNumConfigurations = 2; |
306 | } | 307 | } |
307 | 308 | ||
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index 6829d5961359..a3913519fd58 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/ioport.h> | 34 | #include <linux/ioport.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
39 | #include <linux/init.h> | 38 | #include <linux/init.h> |
40 | #include <linux/timer.h> | 39 | #include <linux/timer.h> |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 0ce4e2819847..ed21e263f832 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -139,7 +139,7 @@ static int is_vbus_present(void) | |||
139 | { | 139 | { |
140 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 140 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
141 | 141 | ||
142 | if (mach->gpio_vbus) { | 142 | if (gpio_is_valid(mach->gpio_vbus)) { |
143 | int value = gpio_get_value(mach->gpio_vbus); | 143 | int value = gpio_get_value(mach->gpio_vbus); |
144 | 144 | ||
145 | if (mach->gpio_vbus_inverted) | 145 | if (mach->gpio_vbus_inverted) |
@@ -158,7 +158,7 @@ static void pullup_off(void) | |||
158 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 158 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
159 | int off_level = mach->gpio_pullup_inverted; | 159 | int off_level = mach->gpio_pullup_inverted; |
160 | 160 | ||
161 | if (mach->gpio_pullup) | 161 | if (gpio_is_valid(mach->gpio_pullup)) |
162 | gpio_set_value(mach->gpio_pullup, off_level); | 162 | gpio_set_value(mach->gpio_pullup, off_level); |
163 | else if (mach->udc_command) | 163 | else if (mach->udc_command) |
164 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 164 | mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); |
@@ -169,7 +169,7 @@ static void pullup_on(void) | |||
169 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; | 169 | struct pxa2xx_udc_mach_info *mach = the_controller->mach; |
170 | int on_level = !mach->gpio_pullup_inverted; | 170 | int on_level = !mach->gpio_pullup_inverted; |
171 | 171 | ||
172 | if (mach->gpio_pullup) | 172 | if (gpio_is_valid(mach->gpio_pullup)) |
173 | gpio_set_value(mach->gpio_pullup, on_level); | 173 | gpio_set_value(mach->gpio_pullup, on_level); |
174 | else if (mach->udc_command) | 174 | else if (mach->udc_command) |
175 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | 175 | mach->udc_command(PXA2XX_UDC_CMD_CONNECT); |
@@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
1000 | udc = container_of(_gadget, struct pxa25x_udc, gadget); | 1000 | udc = container_of(_gadget, struct pxa25x_udc, gadget); |
1001 | 1001 | ||
1002 | /* not all boards support pullup control */ | 1002 | /* not all boards support pullup control */ |
1003 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 1003 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) |
1004 | return -EOPNOTSUPP; | 1004 | return -EOPNOTSUPP; |
1005 | 1005 | ||
1006 | udc->pullup = (is_active != 0); | 1006 | udc->pullup = (is_active != 0); |
@@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev) | |||
1802 | USIR0 |= tmp; | 1802 | USIR0 |= tmp; |
1803 | handled = 1; | 1803 | handled = 1; |
1804 | } | 1804 | } |
1805 | #ifndef CONFIG_USB_PXA25X_SMALL | ||
1805 | if (usir1 & tmp) { | 1806 | if (usir1 & tmp) { |
1806 | handle_ep(&dev->ep[i+8]); | 1807 | handle_ep(&dev->ep[i+8]); |
1807 | USIR1 |= tmp; | 1808 | USIR1 |= tmp; |
1808 | handled = 1; | 1809 | handled = 1; |
1809 | } | 1810 | } |
1811 | #endif | ||
1810 | } | 1812 | } |
1811 | } | 1813 | } |
1812 | 1814 | ||
@@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2160 | dev->dev = &pdev->dev; | 2162 | dev->dev = &pdev->dev; |
2161 | dev->mach = pdev->dev.platform_data; | 2163 | dev->mach = pdev->dev.platform_data; |
2162 | 2164 | ||
2163 | if (dev->mach->gpio_vbus) { | 2165 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
2164 | if ((retval = gpio_request(dev->mach->gpio_vbus, | 2166 | if ((retval = gpio_request(dev->mach->gpio_vbus, |
2165 | "pxa25x_udc GPIO VBUS"))) { | 2167 | "pxa25x_udc GPIO VBUS"))) { |
2166 | dev_dbg(&pdev->dev, | 2168 | dev_dbg(&pdev->dev, |
@@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) | |||
2173 | } else | 2175 | } else |
2174 | vbus_irq = 0; | 2176 | vbus_irq = 0; |
2175 | 2177 | ||
2176 | if (dev->mach->gpio_pullup) { | 2178 | if (gpio_is_valid(dev->mach->gpio_pullup)) { |
2177 | if ((retval = gpio_request(dev->mach->gpio_pullup, | 2179 | if ((retval = gpio_request(dev->mach->gpio_pullup, |
2178 | "pca25x_udc GPIO PULLUP"))) { | 2180 | "pca25x_udc GPIO PULLUP"))) { |
2179 | dev_dbg(&pdev->dev, | 2181 | dev_dbg(&pdev->dev, |
@@ -2256,10 +2258,10 @@ lubbock_fail0: | |||
2256 | #endif | 2258 | #endif |
2257 | free_irq(irq, dev); | 2259 | free_irq(irq, dev); |
2258 | err_irq1: | 2260 | err_irq1: |
2259 | if (dev->mach->gpio_pullup) | 2261 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2260 | gpio_free(dev->mach->gpio_pullup); | 2262 | gpio_free(dev->mach->gpio_pullup); |
2261 | err_gpio_pullup: | 2263 | err_gpio_pullup: |
2262 | if (dev->mach->gpio_vbus) | 2264 | if (gpio_is_valid(dev->mach->gpio_vbus)) |
2263 | gpio_free(dev->mach->gpio_vbus); | 2265 | gpio_free(dev->mach->gpio_vbus); |
2264 | err_gpio_vbus: | 2266 | err_gpio_vbus: |
2265 | clk_put(dev->clk); | 2267 | clk_put(dev->clk); |
@@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) | |||
2294 | free_irq(LUBBOCK_USB_IRQ, dev); | 2296 | free_irq(LUBBOCK_USB_IRQ, dev); |
2295 | } | 2297 | } |
2296 | #endif | 2298 | #endif |
2297 | if (dev->mach->gpio_vbus) { | 2299 | if (gpio_is_valid(dev->mach->gpio_vbus)) { |
2298 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); | 2300 | free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); |
2299 | gpio_free(dev->mach->gpio_vbus); | 2301 | gpio_free(dev->mach->gpio_vbus); |
2300 | } | 2302 | } |
2301 | if (dev->mach->gpio_pullup) | 2303 | if (gpio_is_valid(dev->mach->gpio_pullup)) |
2302 | gpio_free(dev->mach->gpio_pullup); | 2304 | gpio_free(dev->mach->gpio_pullup); |
2303 | 2305 | ||
2304 | clk_put(dev->clk); | 2306 | clk_put(dev->clk); |
@@ -2329,7 +2331,7 @@ static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state) | |||
2329 | struct pxa25x_udc *udc = platform_get_drvdata(dev); | 2331 | struct pxa25x_udc *udc = platform_get_drvdata(dev); |
2330 | unsigned long flags; | 2332 | unsigned long flags; |
2331 | 2333 | ||
2332 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) | 2334 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) |
2333 | WARNING("USB host won't detect disconnect!\n"); | 2335 | WARNING("USB host won't detect disconnect!\n"); |
2334 | udc->suspended = 1; | 2336 | udc->suspended = 1; |
2335 | 2337 | ||
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 2b4660e08c4d..ca41b0b5afb3 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
442 | 442 | ||
443 | case OID_802_3_MAC_OPTIONS: | 443 | case OID_802_3_MAC_OPTIONS: |
444 | pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); | 444 | pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__); |
445 | *outbuf = cpu_to_le32(0); | ||
446 | retval = 0; | ||
445 | break; | 447 | break; |
446 | 448 | ||
447 | /* ieee802.3 statistics OIDs (table 4-4) */ | 449 | /* ieee802.3 statistics OIDs (table 4-4) */ |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 9a2b8920532d..a9b452fe6221 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/errno.h> | 31 | #include <linux/errno.h> |
33 | #include <linux/init.h> | 32 | #include <linux/init.h> |
34 | #include <linux/timer.h> | 33 | #include <linux/timer.h> |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 0c03471f0d41..1a920c70b5a1 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC | |||
181 | Enables support for the USB controller on the MPC52xx or | 181 | Enables support for the USB controller on the MPC52xx or |
182 | STB03xxx processor chip. If unsure, say Y. | 182 | STB03xxx processor chip. If unsure, say Y. |
183 | 183 | ||
184 | config USB_OHCI_HCD_PPC_OF | ||
185 | bool "OHCI support for PPC USB controller on OF platform bus" | ||
186 | depends on USB_OHCI_HCD && PPC_OF | ||
187 | default y | ||
188 | ---help--- | ||
189 | Enables support for the USB controller PowerPC present on the | ||
190 | OpenFirmware platform bus. | ||
191 | |||
192 | config USB_OHCI_HCD_PPC_OF_BE | 184 | config USB_OHCI_HCD_PPC_OF_BE |
193 | bool "Support big endian HC" | 185 | bool "OHCI support for OF platform bus (big endian)" |
194 | depends on USB_OHCI_HCD_PPC_OF | 186 | depends on USB_OHCI_HCD && PPC_OF |
195 | default y | ||
196 | select USB_OHCI_BIG_ENDIAN_DESC | 187 | select USB_OHCI_BIG_ENDIAN_DESC |
197 | select USB_OHCI_BIG_ENDIAN_MMIO | 188 | select USB_OHCI_BIG_ENDIAN_MMIO |
189 | ---help--- | ||
190 | Enables support for big-endian USB controllers present on the | ||
191 | OpenFirmware platform bus. | ||
198 | 192 | ||
199 | config USB_OHCI_HCD_PPC_OF_LE | 193 | config USB_OHCI_HCD_PPC_OF_LE |
200 | bool "Support little endian HC" | 194 | bool "OHCI support for OF platform bus (little endian)" |
201 | depends on USB_OHCI_HCD_PPC_OF | 195 | depends on USB_OHCI_HCD && PPC_OF |
202 | default n | ||
203 | select USB_OHCI_LITTLE_ENDIAN | 196 | select USB_OHCI_LITTLE_ENDIAN |
197 | ---help--- | ||
198 | Enables support for little-endian USB controllers present on the | ||
199 | OpenFirmware platform bus. | ||
200 | |||
201 | config USB_OHCI_HCD_PPC_OF | ||
202 | bool | ||
203 | depends on USB_OHCI_HCD && PPC_OF | ||
204 | default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE | ||
204 | 205 | ||
205 | config USB_OHCI_HCD_PCI | 206 | config USB_OHCI_HCD_PCI |
206 | bool "OHCI support for PCI-bus USB controllers" | 207 | bool "OHCI support for PCI-bus USB controllers" |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index c3a778bd359c..59d208d94d4e 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
113 | .bus_resume = ehci_bus_resume, | 113 | .bus_resume = ehci_bus_resume, |
114 | .relinquish_port = ehci_relinquish_port, | 114 | .relinquish_port = ehci_relinquish_port, |
115 | .port_handed_over = ehci_port_handed_over, | 115 | .port_handed_over = ehci_port_handed_over, |
116 | |||
117 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
116 | }; | 118 | }; |
117 | 119 | ||
118 | static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | 120 | static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index bf86809c5120..991174937db3 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = { | |||
325 | .bus_resume = ehci_bus_resume, | 325 | .bus_resume = ehci_bus_resume, |
326 | .relinquish_port = ehci_relinquish_port, | 326 | .relinquish_port = ehci_relinquish_port, |
327 | .port_handed_over = ehci_port_handed_over, | 327 | .port_handed_over = ehci_port_handed_over, |
328 | |||
329 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
328 | }; | 330 | }; |
329 | 331 | ||
330 | static int ehci_fsl_drv_probe(struct platform_device *pdev) | 332 | static int ehci_fsl_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 2b72473544d3..7d03549c3339 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -1003,6 +1003,8 @@ idle_timeout: | |||
1003 | schedule_timeout_uninterruptible(1); | 1003 | schedule_timeout_uninterruptible(1); |
1004 | goto rescan; | 1004 | goto rescan; |
1005 | case QH_STATE_IDLE: /* fully unlinked */ | 1005 | case QH_STATE_IDLE: /* fully unlinked */ |
1006 | if (qh->clearing_tt) | ||
1007 | goto idle_timeout; | ||
1006 | if (list_empty (&qh->qtd_list)) { | 1008 | if (list_empty (&qh->qtd_list)) { |
1007 | qh_put (qh); | 1009 | qh_put (qh); |
1008 | break; | 1010 | break; |
@@ -1030,12 +1032,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | |||
1030 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 1032 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); |
1031 | struct ehci_qh *qh; | 1033 | struct ehci_qh *qh; |
1032 | int eptype = usb_endpoint_type(&ep->desc); | 1034 | int eptype = usb_endpoint_type(&ep->desc); |
1035 | int epnum = usb_endpoint_num(&ep->desc); | ||
1036 | int is_out = usb_endpoint_dir_out(&ep->desc); | ||
1037 | unsigned long flags; | ||
1033 | 1038 | ||
1034 | if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) | 1039 | if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) |
1035 | return; | 1040 | return; |
1036 | 1041 | ||
1037 | rescan: | 1042 | spin_lock_irqsave(&ehci->lock, flags); |
1038 | spin_lock_irq(&ehci->lock); | ||
1039 | qh = ep->hcpriv; | 1043 | qh = ep->hcpriv; |
1040 | 1044 | ||
1041 | /* For Bulk and Interrupt endpoints we maintain the toggle state | 1045 | /* For Bulk and Interrupt endpoints we maintain the toggle state |
@@ -1044,29 +1048,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) | |||
1044 | * the toggle bit in the QH. | 1048 | * the toggle bit in the QH. |
1045 | */ | 1049 | */ |
1046 | if (qh) { | 1050 | if (qh) { |
1051 | usb_settoggle(qh->dev, epnum, is_out, 0); | ||
1047 | if (!list_empty(&qh->qtd_list)) { | 1052 | if (!list_empty(&qh->qtd_list)) { |
1048 | WARN_ONCE(1, "clear_halt for a busy endpoint\n"); | 1053 | WARN_ONCE(1, "clear_halt for a busy endpoint\n"); |
1049 | } else if (qh->qh_state == QH_STATE_IDLE) { | 1054 | } else if (qh->qh_state == QH_STATE_LINKED) { |
1050 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | 1055 | |
1051 | } else { | 1056 | /* The toggle value in the QH can't be updated |
1052 | /* It's not safe to write into the overlay area | 1057 | * while the QH is active. Unlink it now; |
1053 | * while the QH is active. Unlink it first and | 1058 | * re-linking will call qh_refresh(). |
1054 | * wait for the unlink to complete. | ||
1055 | */ | 1059 | */ |
1056 | if (qh->qh_state == QH_STATE_LINKED) { | 1060 | if (eptype == USB_ENDPOINT_XFER_BULK) { |
1057 | if (eptype == USB_ENDPOINT_XFER_BULK) { | 1061 | unlink_async(ehci, qh); |
1058 | unlink_async(ehci, qh); | 1062 | } else { |
1059 | } else { | 1063 | intr_deschedule(ehci, qh); |
1060 | intr_deschedule(ehci, qh); | 1064 | (void) qh_schedule(ehci, qh); |
1061 | (void) qh_schedule(ehci, qh); | ||
1062 | } | ||
1063 | } | 1065 | } |
1064 | spin_unlock_irq(&ehci->lock); | ||
1065 | schedule_timeout_uninterruptible(1); | ||
1066 | goto rescan; | ||
1067 | } | 1066 | } |
1068 | } | 1067 | } |
1069 | spin_unlock_irq(&ehci->lock); | 1068 | spin_unlock_irqrestore(&ehci->lock, flags); |
1070 | } | 1069 | } |
1071 | 1070 | ||
1072 | static int ehci_get_frame (struct usb_hcd *hcd) | 1071 | static int ehci_get_frame (struct usb_hcd *hcd) |
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c index a44bb4a94954..89b7c70c6ed6 100644 --- a/drivers/usb/host/ehci-ixp4xx.c +++ b/drivers/usb/host/ehci-ixp4xx.c | |||
@@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = { | |||
61 | #endif | 61 | #endif |
62 | .relinquish_port = ehci_relinquish_port, | 62 | .relinquish_port = ehci_relinquish_port, |
63 | .port_handed_over = ehci_port_handed_over, | 63 | .port_handed_over = ehci_port_handed_over, |
64 | |||
65 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
64 | }; | 66 | }; |
65 | 67 | ||
66 | static int ixp4xx_ehci_probe(struct platform_device *pdev) | 68 | static int ixp4xx_ehci_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 770dd9aba62a..dc2ac613a9d1 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
@@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = { | |||
165 | .bus_resume = ehci_bus_resume, | 165 | .bus_resume = ehci_bus_resume, |
166 | .relinquish_port = ehci_relinquish_port, | 166 | .relinquish_port = ehci_relinquish_port, |
167 | .port_handed_over = ehci_port_handed_over, | 167 | .port_handed_over = ehci_port_handed_over, |
168 | |||
169 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
168 | }; | 170 | }; |
169 | 171 | ||
170 | static void __init | 172 | static void __init |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index f3683e1da161..c2f1b7df918c 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = { | |||
404 | .bus_resume = ehci_bus_resume, | 404 | .bus_resume = ehci_bus_resume, |
405 | .relinquish_port = ehci_relinquish_port, | 405 | .relinquish_port = ehci_relinquish_port, |
406 | .port_handed_over = ehci_port_handed_over, | 406 | .port_handed_over = ehci_port_handed_over, |
407 | |||
408 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
407 | }; | 409 | }; |
408 | 410 | ||
409 | /*-------------------------------------------------------------------------*/ | 411 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index fbd272288fc2..36f96da129f5 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c | |||
@@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { | |||
79 | #endif | 79 | #endif |
80 | .relinquish_port = ehci_relinquish_port, | 80 | .relinquish_port = ehci_relinquish_port, |
81 | .port_handed_over = ehci_port_handed_over, | 81 | .port_handed_over = ehci_port_handed_over, |
82 | |||
83 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
82 | }; | 84 | }; |
83 | 85 | ||
84 | 86 | ||
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 93f7035d00a1..1dee33b9139e 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -75,6 +75,8 @@ static const struct hc_driver ps3_ehci_hc_driver = { | |||
75 | #endif | 75 | #endif |
76 | .relinquish_port = ehci_relinquish_port, | 76 | .relinquish_port = ehci_relinquish_port, |
77 | .port_handed_over = ehci_port_handed_over, | 77 | .port_handed_over = ehci_port_handed_over, |
78 | |||
79 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
78 | }; | 80 | }; |
79 | 81 | ||
80 | static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) | 82 | static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3192f683f807..9a1384747f3b 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) | |||
93 | qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); | 93 | qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); |
94 | qh->hw_alt_next = EHCI_LIST_END(ehci); | 94 | qh->hw_alt_next = EHCI_LIST_END(ehci); |
95 | 95 | ||
96 | /* Except for control endpoints, we make hardware maintain data | ||
97 | * toggle (like OHCI) ... here (re)initialize the toggle in the QH, | ||
98 | * and set the pseudo-toggle in udev. Only usb_clear_halt() will | ||
99 | * ever clear it. | ||
100 | */ | ||
101 | if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { | ||
102 | unsigned is_out, epnum; | ||
103 | |||
104 | is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); | ||
105 | epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f; | ||
106 | if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { | ||
107 | qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | ||
108 | usb_settoggle (qh->dev, epnum, is_out, 1); | ||
109 | } | ||
110 | } | ||
111 | |||
96 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ | 112 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ |
97 | wmb (); | 113 | wmb (); |
98 | qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); | 114 | qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); |
@@ -123,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
123 | 139 | ||
124 | /*-------------------------------------------------------------------------*/ | 140 | /*-------------------------------------------------------------------------*/ |
125 | 141 | ||
142 | static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh); | ||
143 | |||
144 | static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd, | ||
145 | struct usb_host_endpoint *ep) | ||
146 | { | ||
147 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
148 | struct ehci_qh *qh = ep->hcpriv; | ||
149 | unsigned long flags; | ||
150 | |||
151 | spin_lock_irqsave(&ehci->lock, flags); | ||
152 | qh->clearing_tt = 0; | ||
153 | if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list) | ||
154 | && HC_IS_RUNNING(hcd->state)) | ||
155 | qh_link_async(ehci, qh); | ||
156 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
157 | } | ||
158 | |||
159 | static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh, | ||
160 | struct urb *urb, u32 token) | ||
161 | { | ||
162 | |||
163 | /* If an async split transaction gets an error or is unlinked, | ||
164 | * the TT buffer may be left in an indeterminate state. We | ||
165 | * have to clear the TT buffer. | ||
166 | * | ||
167 | * Note: this routine is never called for Isochronous transfers. | ||
168 | */ | ||
169 | if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) { | ||
170 | #ifdef DEBUG | ||
171 | struct usb_device *tt = urb->dev->tt->hub; | ||
172 | dev_dbg(&tt->dev, | ||
173 | "clear tt buffer port %d, a%d ep%d t%08x\n", | ||
174 | urb->dev->ttport, urb->dev->devnum, | ||
175 | usb_pipeendpoint(urb->pipe), token); | ||
176 | #endif /* DEBUG */ | ||
177 | if (!ehci_is_TDI(ehci) | ||
178 | || urb->dev->tt->hub != | ||
179 | ehci_to_hcd(ehci)->self.root_hub) { | ||
180 | if (usb_hub_clear_tt_buffer(urb) == 0) | ||
181 | qh->clearing_tt = 1; | ||
182 | } else { | ||
183 | |||
184 | /* REVISIT ARC-derived cores don't clear the root | ||
185 | * hub TT buffer in this way... | ||
186 | */ | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | |||
126 | static int qtd_copy_status ( | 191 | static int qtd_copy_status ( |
127 | struct ehci_hcd *ehci, | 192 | struct ehci_hcd *ehci, |
128 | struct urb *urb, | 193 | struct urb *urb, |
@@ -149,6 +214,14 @@ static int qtd_copy_status ( | |||
149 | if (token & QTD_STS_BABBLE) { | 214 | if (token & QTD_STS_BABBLE) { |
150 | /* FIXME "must" disable babbling device's port too */ | 215 | /* FIXME "must" disable babbling device's port too */ |
151 | status = -EOVERFLOW; | 216 | status = -EOVERFLOW; |
217 | /* CERR nonzero + halt --> stall */ | ||
218 | } else if (QTD_CERR(token)) { | ||
219 | status = -EPIPE; | ||
220 | |||
221 | /* In theory, more than one of the following bits can be set | ||
222 | * since they are sticky and the transaction is retried. | ||
223 | * Which to test first is rather arbitrary. | ||
224 | */ | ||
152 | } else if (token & QTD_STS_MMF) { | 225 | } else if (token & QTD_STS_MMF) { |
153 | /* fs/ls interrupt xfer missed the complete-split */ | 226 | /* fs/ls interrupt xfer missed the complete-split */ |
154 | status = -EPROTO; | 227 | status = -EPROTO; |
@@ -157,21 +230,15 @@ static int qtd_copy_status ( | |||
157 | ? -ENOSR /* hc couldn't read data */ | 230 | ? -ENOSR /* hc couldn't read data */ |
158 | : -ECOMM; /* hc couldn't write data */ | 231 | : -ECOMM; /* hc couldn't write data */ |
159 | } else if (token & QTD_STS_XACT) { | 232 | } else if (token & QTD_STS_XACT) { |
160 | /* timeout, bad crc, wrong PID, etc; retried */ | 233 | /* timeout, bad CRC, wrong PID, etc */ |
161 | if (QTD_CERR (token)) | 234 | ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n", |
162 | status = -EPIPE; | 235 | urb->dev->devpath, |
163 | else { | 236 | usb_pipeendpoint(urb->pipe), |
164 | ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", | 237 | usb_pipein(urb->pipe) ? "in" : "out"); |
165 | urb->dev->devpath, | 238 | status = -EPROTO; |
166 | usb_pipeendpoint (urb->pipe), | 239 | } else { /* unknown */ |
167 | usb_pipein (urb->pipe) ? "in" : "out"); | ||
168 | status = -EPROTO; | ||
169 | } | ||
170 | /* CERR nonzero + no errors + halt --> stall */ | ||
171 | } else if (QTD_CERR (token)) | ||
172 | status = -EPIPE; | ||
173 | else /* unknown */ | ||
174 | status = -EPROTO; | 240 | status = -EPROTO; |
241 | } | ||
175 | 242 | ||
176 | ehci_vdbg (ehci, | 243 | ehci_vdbg (ehci, |
177 | "dev%d ep%d%s qtd token %08x --> status %d\n", | 244 | "dev%d ep%d%s qtd token %08x --> status %d\n", |
@@ -179,28 +246,6 @@ static int qtd_copy_status ( | |||
179 | usb_pipeendpoint (urb->pipe), | 246 | usb_pipeendpoint (urb->pipe), |
180 | usb_pipein (urb->pipe) ? "in" : "out", | 247 | usb_pipein (urb->pipe) ? "in" : "out", |
181 | token, status); | 248 | token, status); |
182 | |||
183 | /* if async CSPLIT failed, try cleaning out the TT buffer */ | ||
184 | if (status != -EPIPE | ||
185 | && urb->dev->tt | ||
186 | && !usb_pipeint(urb->pipe) | ||
187 | && ((token & QTD_STS_MMF) != 0 | ||
188 | || QTD_CERR(token) == 0) | ||
189 | && (!ehci_is_TDI(ehci) | ||
190 | || urb->dev->tt->hub != | ||
191 | ehci_to_hcd(ehci)->self.root_hub)) { | ||
192 | #ifdef DEBUG | ||
193 | struct usb_device *tt = urb->dev->tt->hub; | ||
194 | dev_dbg (&tt->dev, | ||
195 | "clear tt buffer port %d, a%d ep%d t%08x\n", | ||
196 | urb->dev->ttport, urb->dev->devnum, | ||
197 | usb_pipeendpoint (urb->pipe), token); | ||
198 | #endif /* DEBUG */ | ||
199 | /* REVISIT ARC-derived cores don't clear the root | ||
200 | * hub TT buffer in this way... | ||
201 | */ | ||
202 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); | ||
203 | } | ||
204 | } | 249 | } |
205 | 250 | ||
206 | return status; | 251 | return status; |
@@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
391 | /* qh unlinked; token in overlay may be most current */ | 436 | /* qh unlinked; token in overlay may be most current */ |
392 | if (state == QH_STATE_IDLE | 437 | if (state == QH_STATE_IDLE |
393 | && cpu_to_hc32(ehci, qtd->qtd_dma) | 438 | && cpu_to_hc32(ehci, qtd->qtd_dma) |
394 | == qh->hw_current) | 439 | == qh->hw_current) { |
395 | token = hc32_to_cpu(ehci, qh->hw_token); | 440 | token = hc32_to_cpu(ehci, qh->hw_token); |
396 | 441 | ||
442 | /* An unlink may leave an incomplete | ||
443 | * async transaction in the TT buffer. | ||
444 | * We have to clear it. | ||
445 | */ | ||
446 | ehci_clear_tt_buffer(ehci, qh, urb, token); | ||
447 | } | ||
448 | |||
397 | /* force halt for unlinked or blocked qh, so we'll | 449 | /* force halt for unlinked or blocked qh, so we'll |
398 | * patch the qh later and so that completions can't | 450 | * patch the qh later and so that completions can't |
399 | * activate it while we "know" it's stopped. | 451 | * activate it while we "know" it's stopped. |
@@ -419,6 +471,13 @@ halt: | |||
419 | && (qtd->hw_alt_next | 471 | && (qtd->hw_alt_next |
420 | & EHCI_LIST_END(ehci))) | 472 | & EHCI_LIST_END(ehci))) |
421 | last_status = -EINPROGRESS; | 473 | last_status = -EINPROGRESS; |
474 | |||
475 | /* As part of low/full-speed endpoint-halt processing | ||
476 | * we must clear the TT buffer (11.17.5). | ||
477 | */ | ||
478 | if (unlikely(last_status != -EINPROGRESS && | ||
479 | last_status != -EREMOTEIO)) | ||
480 | ehci_clear_tt_buffer(ehci, qh, urb, token); | ||
422 | } | 481 | } |
423 | 482 | ||
424 | /* if we're removing something not at the queue head, | 483 | /* if we're removing something not at the queue head, |
@@ -834,6 +893,7 @@ done: | |||
834 | qh->qh_state = QH_STATE_IDLE; | 893 | qh->qh_state = QH_STATE_IDLE; |
835 | qh->hw_info1 = cpu_to_hc32(ehci, info1); | 894 | qh->hw_info1 = cpu_to_hc32(ehci, info1); |
836 | qh->hw_info2 = cpu_to_hc32(ehci, info2); | 895 | qh->hw_info2 = cpu_to_hc32(ehci, info2); |
896 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); | ||
837 | qh_refresh (ehci, qh); | 897 | qh_refresh (ehci, qh); |
838 | return qh; | 898 | return qh; |
839 | } | 899 | } |
@@ -847,6 +907,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
847 | __hc32 dma = QH_NEXT(ehci, qh->qh_dma); | 907 | __hc32 dma = QH_NEXT(ehci, qh->qh_dma); |
848 | struct ehci_qh *head; | 908 | struct ehci_qh *head; |
849 | 909 | ||
910 | /* Don't link a QH if there's a Clear-TT-Buffer pending */ | ||
911 | if (unlikely(qh->clearing_tt)) | ||
912 | return; | ||
913 | |||
850 | /* (re)start the async schedule? */ | 914 | /* (re)start the async schedule? */ |
851 | head = ehci->async; | 915 | head = ehci->async; |
852 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 916 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
@@ -864,7 +928,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
864 | } | 928 | } |
865 | } | 929 | } |
866 | 930 | ||
867 | /* clear halt and maybe recover from silicon quirk */ | 931 | /* clear halt and/or toggle; and maybe recover from silicon quirk */ |
868 | if (qh->qh_state == QH_STATE_IDLE) | 932 | if (qh->qh_state == QH_STATE_IDLE) |
869 | qh_refresh (ehci, qh); | 933 | qh_refresh (ehci, qh); |
870 | 934 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 9d1babc7ff65..74f7f83b29ad 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1619,11 +1619,14 @@ itd_complete ( | |||
1619 | desc->status = -EPROTO; | 1619 | desc->status = -EPROTO; |
1620 | 1620 | ||
1621 | /* HC need not update length with this error */ | 1621 | /* HC need not update length with this error */ |
1622 | if (!(t & EHCI_ISOC_BABBLE)) | 1622 | if (!(t & EHCI_ISOC_BABBLE)) { |
1623 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1623 | desc->actual_length = EHCI_ITD_LENGTH(t); |
1624 | urb->actual_length += desc->actual_length; | ||
1625 | } | ||
1624 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { | 1626 | } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { |
1625 | desc->status = 0; | 1627 | desc->status = 0; |
1626 | desc->actual_length = EHCI_ITD_LENGTH (t); | 1628 | desc->actual_length = EHCI_ITD_LENGTH(t); |
1629 | urb->actual_length += desc->actual_length; | ||
1627 | } else { | 1630 | } else { |
1628 | /* URB was too late */ | 1631 | /* URB was too late */ |
1629 | desc->status = -EXDEV; | 1632 | desc->status = -EXDEV; |
@@ -2014,7 +2017,8 @@ sitd_complete ( | |||
2014 | desc->status = -EPROTO; | 2017 | desc->status = -EPROTO; |
2015 | } else { | 2018 | } else { |
2016 | desc->status = 0; | 2019 | desc->status = 0; |
2017 | desc->actual_length = desc->length - SITD_LENGTH (t); | 2020 | desc->actual_length = desc->length - SITD_LENGTH(t); |
2021 | urb->actual_length += desc->actual_length; | ||
2018 | } | 2022 | } |
2019 | stream->depth -= stream->interval << 3; | 2023 | stream->depth -= stream->interval << 3; |
2020 | 2024 | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 90ad3395bb21..2bfff30f4704 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -354,7 +354,9 @@ struct ehci_qh { | |||
354 | unsigned short period; /* polling interval */ | 354 | unsigned short period; /* polling interval */ |
355 | unsigned short start; /* where polling starts */ | 355 | unsigned short start; /* where polling starts */ |
356 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ | 356 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ |
357 | |||
357 | struct usb_device *dev; /* access to TT */ | 358 | struct usb_device *dev; /* access to TT */ |
359 | unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ | ||
358 | } __attribute__ ((aligned (32))); | 360 | } __attribute__ ((aligned (32))); |
359 | 361 | ||
360 | /*-------------------------------------------------------------------------*/ | 362 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c index bb63b68ddb77..62a226b61670 100644 --- a/drivers/usb/host/fhci-sched.c +++ b/drivers/usb/host/fhci-sched.c | |||
@@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) | |||
576 | out_be16(&usb->fhci->regs->usb_event, | 576 | out_be16(&usb->fhci->regs->usb_event, |
577 | usb->saved_msk); | 577 | usb->saved_msk); |
578 | } else if (usb->port_status == FHCI_PORT_DISABLED) { | 578 | } else if (usb->port_status == FHCI_PORT_DISABLED) { |
579 | if (fhci_ioports_check_bus_state(fhci) == 1 && | 579 | if (fhci_ioports_check_bus_state(fhci) == 1) |
580 | usb->port_status != FHCI_PORT_LOW && | ||
581 | usb->port_status != FHCI_PORT_FULL) | ||
582 | fhci_device_connected_interrupt(fhci); | 580 | fhci_device_connected_interrupt(fhci); |
583 | } | 581 | } |
584 | usb_er &= ~USB_E_RESET_MASK; | 582 | usb_er &= ~USB_E_RESET_MASK; |
@@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) | |||
605 | } | 603 | } |
606 | 604 | ||
607 | if (usb_er & USB_E_IDLE_MASK) { | 605 | if (usb_er & USB_E_IDLE_MASK) { |
608 | if (usb->port_status == FHCI_PORT_DISABLED && | 606 | if (usb->port_status == FHCI_PORT_DISABLED) { |
609 | usb->port_status != FHCI_PORT_LOW && | ||
610 | usb->port_status != FHCI_PORT_FULL) { | ||
611 | usb_er &= ~USB_E_RESET_MASK; | 607 | usb_er &= ~USB_E_RESET_MASK; |
612 | fhci_device_connected_interrupt(fhci); | 608 | fhci_device_connected_interrupt(fhci); |
613 | } else if (usb->port_status == | 609 | } else if (usb->port_status == |
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 3fa3a1702796..d4feebfc63bd 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev) | |||
361 | 361 | ||
362 | static struct platform_driver isp1760_plat_driver = { | 362 | static struct platform_driver isp1760_plat_driver = { |
363 | .probe = isp1760_plat_probe, | 363 | .probe = isp1760_plat_probe, |
364 | .remove = isp1760_plat_remove, | 364 | .remove = __devexit_p(isp1760_plat_remove), |
365 | .driver = { | 365 | .driver = { |
366 | .name = "isp1760", | 366 | .name = "isp1760", |
367 | }, | 367 | }, |
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 56976cc0352a..e18f74946e68 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/sched.h> | 28 | #include <linux/sched.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 3c5fe5cee05a..90e1a8dedfa9 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/smp_lock.h> | ||
21 | #include <linux/poll.h> | 22 | #include <linux/poll.h> |
22 | #include <linux/usb/iowarrior.h> | 23 | #include <linux/usb/iowarrior.h> |
23 | 24 | ||
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index deb95bb49fd1..d645f3899fe1 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
33 | #include <linux/signal.h> | 33 | #include <linux/signal.h> |
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/smp_lock.h> | ||
35 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
36 | #include <linux/random.h> | 37 | #include <linux/random.h> |
37 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index e0ff9ccd866b..29092b8e59ce 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/smp_lock.h> | ||
19 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
20 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
21 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h index 8a39de3e6e47..59bf949e589b 100644 --- a/drivers/usb/musb/cppi_dma.h +++ b/drivers/usb/musb/cppi_dma.h | |||
@@ -5,7 +5,6 @@ | |||
5 | 5 | ||
6 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
7 | #include <linux/list.h> | 7 | #include <linux/list.h> |
8 | #include <linux/smp_lock.h> | ||
9 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
10 | #include <linux/dmapool.h> | 9 | #include <linux/dmapool.h> |
11 | 10 | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 180d7daa4099..e16ff605c458 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -35,13 +35,14 @@ | |||
35 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
36 | #include <mach/memory.h> | 36 | #include <mach/memory.h> |
37 | #include <mach/gpio.h> | 37 | #include <mach/gpio.h> |
38 | #include <mach/cputype.h> | ||
38 | 39 | ||
39 | #include <asm/mach-types.h> | 40 | #include <asm/mach-types.h> |
40 | 41 | ||
41 | #include "musb_core.h" | 42 | #include "musb_core.h" |
42 | 43 | ||
43 | #ifdef CONFIG_MACH_DAVINCI_EVM | 44 | #ifdef CONFIG_MACH_DAVINCI_EVM |
44 | #define GPIO_nVBUS_DRV 87 | 45 | #define GPIO_nVBUS_DRV 144 |
45 | #endif | 46 | #endif |
46 | 47 | ||
47 | #include "davinci.h" | 48 | #include "davinci.h" |
@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
329 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); | 330 | mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ); |
330 | WARNING("VBUS error workaround (delay coming)\n"); | 331 | WARNING("VBUS error workaround (delay coming)\n"); |
331 | } else if (is_host_enabled(musb) && drvvbus) { | 332 | } else if (is_host_enabled(musb) && drvvbus) { |
332 | musb->is_active = 1; | ||
333 | MUSB_HST_MODE(musb); | 333 | MUSB_HST_MODE(musb); |
334 | musb->xceiv->default_a = 1; | 334 | musb->xceiv->default_a = 1; |
335 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 335 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
343 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); | 343 | portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); |
344 | } | 344 | } |
345 | 345 | ||
346 | /* NOTE: this must complete poweron within 100 msec */ | 346 | /* NOTE: this must complete poweron within 100 msec |
347 | * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. | ||
348 | */ | ||
347 | davinci_source_power(musb, drvvbus, 0); | 349 | davinci_source_power(musb, drvvbus, 0); |
348 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", | 350 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", |
349 | drvvbus ? "on" : "off", | 351 | drvvbus ? "on" : "off", |
@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb) | |||
411 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | 413 | __raw_writel(phy_ctrl, USB_PHY_CTRL); |
412 | } | 414 | } |
413 | 415 | ||
416 | /* On dm355, the default-A state machine needs DRVVBUS control. | ||
417 | * If we won't be a host, there's no need to turn it on. | ||
418 | */ | ||
419 | if (cpu_is_davinci_dm355()) { | ||
420 | u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); | ||
421 | |||
422 | if (is_host_enabled(musb)) { | ||
423 | deepsleep &= ~DRVVBUS_OVERRIDE; | ||
424 | } else { | ||
425 | deepsleep &= ~DRVVBUS_FORCE; | ||
426 | deepsleep |= DRVVBUS_OVERRIDE; | ||
427 | } | ||
428 | __raw_writel(deepsleep, DM355_DEEPSLEEP); | ||
429 | } | ||
430 | |||
414 | /* reset the controller */ | 431 | /* reset the controller */ |
415 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); | 432 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); |
416 | 433 | ||
@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb) | |||
437 | if (is_host_enabled(musb)) | 454 | if (is_host_enabled(musb)) |
438 | del_timer_sync(&otg_workaround); | 455 | del_timer_sync(&otg_workaround); |
439 | 456 | ||
457 | /* force VBUS off */ | ||
458 | if (cpu_is_davinci_dm355()) { | ||
459 | u32 deepsleep = __raw_readl(DM355_DEEPSLEEP); | ||
460 | |||
461 | deepsleep &= ~DRVVBUS_FORCE; | ||
462 | deepsleep |= DRVVBUS_OVERRIDE; | ||
463 | __raw_writel(deepsleep, DM355_DEEPSLEEP); | ||
464 | } | ||
465 | |||
440 | davinci_source_power(musb, 0 /*off*/, 1); | 466 | davinci_source_power(musb, 0 /*off*/, 1); |
441 | 467 | ||
442 | /* delay, to avoid problems with module reload */ | 468 | /* delay, to avoid problems with module reload */ |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index f3772ca3b2cf..381d648a36b8 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/list.h> | 39 | #include <linux/list.h> |
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <linux/smp_lock.h> | ||
42 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
43 | #include <linux/timer.h> | 42 | #include <linux/timer.h> |
44 | #include <linux/clk.h> | 43 | #include <linux/clk.h> |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 94a2a350a414..cf94511485f2 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, | |||
373 | musb_save_toggle(qh, is_in, urb); | 373 | musb_save_toggle(qh, is_in, urb); |
374 | break; | 374 | break; |
375 | case USB_ENDPOINT_XFER_ISOC: | 375 | case USB_ENDPOINT_XFER_ISOC: |
376 | if (urb->error_count) | 376 | if (status == 0 && urb->error_count) |
377 | status = -EXDEV; | 377 | status = -EXDEV; |
378 | break; | 378 | break; |
379 | } | 379 | } |
@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd) | |||
2235 | static int musb_bus_suspend(struct usb_hcd *hcd) | 2235 | static int musb_bus_suspend(struct usb_hcd *hcd) |
2236 | { | 2236 | { |
2237 | struct musb *musb = hcd_to_musb(hcd); | 2237 | struct musb *musb = hcd_to_musb(hcd); |
2238 | u8 devctl; | ||
2238 | 2239 | ||
2239 | if (musb->xceiv->state == OTG_STATE_A_SUSPEND) | 2240 | if (!is_host_active(musb)) |
2240 | return 0; | 2241 | return 0; |
2241 | 2242 | ||
2242 | if (is_host_active(musb) && musb->is_active) { | 2243 | switch (musb->xceiv->state) { |
2243 | WARNING("trying to suspend as %s is_active=%i\n", | 2244 | case OTG_STATE_A_SUSPEND: |
2244 | otg_state_string(musb), musb->is_active); | 2245 | return 0; |
2246 | case OTG_STATE_A_WAIT_VRISE: | ||
2247 | /* ID could be grounded even if there's no device | ||
2248 | * on the other end of the cable. NOTE that the | ||
2249 | * A_WAIT_VRISE timers are messy with MUSB... | ||
2250 | */ | ||
2251 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
2252 | if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) | ||
2253 | musb->xceiv->state = OTG_STATE_A_WAIT_BCON; | ||
2254 | break; | ||
2255 | default: | ||
2256 | break; | ||
2257 | } | ||
2258 | |||
2259 | if (musb->is_active) { | ||
2260 | WARNING("trying to suspend as %s while active\n", | ||
2261 | otg_state_string(musb)); | ||
2245 | return -EBUSY; | 2262 | return -EBUSY; |
2246 | } else | 2263 | } else |
2247 | return 0; | 2264 | return 0; |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index 69feeec1628c..aa884d072f0b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
@@ -59,18 +59,4 @@ config NOP_USB_XCEIV | |||
59 | built-in with usb ip or which are autonomous and doesn't require any | 59 | built-in with usb ip or which are autonomous and doesn't require any |
60 | phy programming such as ISP1x04 etc. | 60 | phy programming such as ISP1x04 etc. |
61 | 61 | ||
62 | config USB_LANGWELL_OTG | ||
63 | tristate "Intel Langwell USB OTG dual-role support" | ||
64 | depends on USB && MRST | ||
65 | select USB_OTG | ||
66 | select USB_OTG_UTILS | ||
67 | help | ||
68 | Say Y here if you want to build Intel Langwell USB OTG | ||
69 | transciever driver in kernel. This driver implements role | ||
70 | switch between EHCI host driver and Langwell USB OTG | ||
71 | client driver. | ||
72 | |||
73 | To compile this driver as a module, choose M here: the | ||
74 | module will be called langwell_otg. | ||
75 | |||
76 | endif # USB || OTG | 62 | endif # USB || OTG |
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index 6d1abdd3c0ac..208167856529 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile | |||
@@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o | |||
9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o | 9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o |
10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o | 10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o |
11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o | 11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o |
12 | obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o | ||
13 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o | 12 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o |
14 | 13 | ||
15 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG | 14 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG |
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c deleted file mode 100644 index 6f628d0e9f39..000000000000 --- a/drivers/usb/otg/langwell_otg.c +++ /dev/null | |||
@@ -1,1915 +0,0 @@ | |||
1 | /* | ||
2 | * Intel Langwell USB OTG transceiver driver | ||
3 | * Copyright (C) 2008 - 2009, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | */ | ||
19 | /* This driver helps to switch Langwell OTG controller function between host | ||
20 | * and peripheral. It works with EHCI driver and Langwell client controller | ||
21 | * driver together. | ||
22 | */ | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/moduleparam.h> | ||
31 | #include <linux/usb/ch9.h> | ||
32 | #include <linux/usb/gadget.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include <linux/usb/otg.h> | ||
35 | #include <linux/notifier.h> | ||
36 | #include <asm/ipc_defs.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include "../core/hcd.h" | ||
39 | |||
40 | #include <linux/usb/langwell_otg.h> | ||
41 | |||
42 | #define DRIVER_DESC "Intel Langwell USB OTG transceiver driver" | ||
43 | #define DRIVER_VERSION "3.0.0.32L.0002" | ||
44 | |||
45 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
46 | MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>"); | ||
47 | MODULE_VERSION(DRIVER_VERSION); | ||
48 | MODULE_LICENSE("GPL"); | ||
49 | |||
50 | static const char driver_name[] = "langwell_otg"; | ||
51 | |||
52 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
53 | const struct pci_device_id *id); | ||
54 | static void langwell_otg_remove(struct pci_dev *pdev); | ||
55 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message); | ||
56 | static int langwell_otg_resume(struct pci_dev *pdev); | ||
57 | |||
58 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
59 | struct usb_bus *host); | ||
60 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
61 | struct usb_gadget *gadget); | ||
62 | static int langwell_otg_start_srp(struct otg_transceiver *otg); | ||
63 | |||
64 | static const struct pci_device_id pci_ids[] = {{ | ||
65 | .class = ((PCI_CLASS_SERIAL_USB << 8) | 0xfe), | ||
66 | .class_mask = ~0, | ||
67 | .vendor = 0x8086, | ||
68 | .device = 0x0811, | ||
69 | .subvendor = PCI_ANY_ID, | ||
70 | .subdevice = PCI_ANY_ID, | ||
71 | }, { /* end: all zeroes */ } | ||
72 | }; | ||
73 | |||
74 | static struct pci_driver otg_pci_driver = { | ||
75 | .name = (char *) driver_name, | ||
76 | .id_table = pci_ids, | ||
77 | |||
78 | .probe = langwell_otg_probe, | ||
79 | .remove = langwell_otg_remove, | ||
80 | |||
81 | .suspend = langwell_otg_suspend, | ||
82 | .resume = langwell_otg_resume, | ||
83 | }; | ||
84 | |||
85 | static const char *state_string(enum usb_otg_state state) | ||
86 | { | ||
87 | switch (state) { | ||
88 | case OTG_STATE_A_IDLE: | ||
89 | return "a_idle"; | ||
90 | case OTG_STATE_A_WAIT_VRISE: | ||
91 | return "a_wait_vrise"; | ||
92 | case OTG_STATE_A_WAIT_BCON: | ||
93 | return "a_wait_bcon"; | ||
94 | case OTG_STATE_A_HOST: | ||
95 | return "a_host"; | ||
96 | case OTG_STATE_A_SUSPEND: | ||
97 | return "a_suspend"; | ||
98 | case OTG_STATE_A_PERIPHERAL: | ||
99 | return "a_peripheral"; | ||
100 | case OTG_STATE_A_WAIT_VFALL: | ||
101 | return "a_wait_vfall"; | ||
102 | case OTG_STATE_A_VBUS_ERR: | ||
103 | return "a_vbus_err"; | ||
104 | case OTG_STATE_B_IDLE: | ||
105 | return "b_idle"; | ||
106 | case OTG_STATE_B_SRP_INIT: | ||
107 | return "b_srp_init"; | ||
108 | case OTG_STATE_B_PERIPHERAL: | ||
109 | return "b_peripheral"; | ||
110 | case OTG_STATE_B_WAIT_ACON: | ||
111 | return "b_wait_acon"; | ||
112 | case OTG_STATE_B_HOST: | ||
113 | return "b_host"; | ||
114 | default: | ||
115 | return "UNDEFINED"; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /* HSM timers */ | ||
120 | static inline struct langwell_otg_timer *otg_timer_initializer | ||
121 | (void (*function)(unsigned long), unsigned long expires, unsigned long data) | ||
122 | { | ||
123 | struct langwell_otg_timer *timer; | ||
124 | timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL); | ||
125 | timer->function = function; | ||
126 | timer->expires = expires; | ||
127 | timer->data = data; | ||
128 | return timer; | ||
129 | } | ||
130 | |||
131 | static struct langwell_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr, | ||
132 | *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_res_tmr, | ||
133 | *b_bus_suspend_tmr; | ||
134 | |||
135 | static struct list_head active_timers; | ||
136 | |||
137 | static struct langwell_otg *the_transceiver; | ||
138 | |||
139 | /* host/client notify transceiver when event affects HNP state */ | ||
140 | void langwell_update_transceiver() | ||
141 | { | ||
142 | otg_dbg("transceiver driver is notified\n"); | ||
143 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
144 | } | ||
145 | EXPORT_SYMBOL(langwell_update_transceiver); | ||
146 | |||
147 | static int langwell_otg_set_host(struct otg_transceiver *otg, | ||
148 | struct usb_bus *host) | ||
149 | { | ||
150 | otg->host = host; | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int langwell_otg_set_peripheral(struct otg_transceiver *otg, | ||
156 | struct usb_gadget *gadget) | ||
157 | { | ||
158 | otg->gadget = gadget; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int langwell_otg_set_power(struct otg_transceiver *otg, | ||
164 | unsigned mA) | ||
165 | { | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | /* A-device drives vbus, controlled through PMIC CHRGCNTL register*/ | ||
170 | static void langwell_otg_drv_vbus(int on) | ||
171 | { | ||
172 | struct ipc_pmic_reg_data pmic_data = {0}; | ||
173 | struct ipc_pmic_reg_data battery_data; | ||
174 | |||
175 | /* Check if battery is attached or not */ | ||
176 | battery_data.pmic_reg_data[0].register_address = 0xd2; | ||
177 | battery_data.ioc = 0; | ||
178 | battery_data.num_entries = 1; | ||
179 | if (ipc_pmic_register_read(&battery_data)) { | ||
180 | otg_dbg("Failed to read PMIC register 0xd2.\n"); | ||
181 | return; | ||
182 | } | ||
183 | |||
184 | if ((battery_data.pmic_reg_data[0].value & 0x20) == 0) { | ||
185 | otg_dbg("no battery attached\n"); | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | /* Workaround for battery attachment issue */ | ||
190 | if (battery_data.pmic_reg_data[0].value == 0x34) { | ||
191 | otg_dbg("battery \n"); | ||
192 | return; | ||
193 | } | ||
194 | |||
195 | otg_dbg("battery attached\n"); | ||
196 | |||
197 | pmic_data.ioc = 0; | ||
198 | pmic_data.pmic_reg_data[0].register_address = 0xD4; | ||
199 | pmic_data.num_entries = 1; | ||
200 | if (on) | ||
201 | pmic_data.pmic_reg_data[0].value = 0x20; | ||
202 | else | ||
203 | pmic_data.pmic_reg_data[0].value = 0xc0; | ||
204 | |||
205 | if (ipc_pmic_register_write(&pmic_data, TRUE)) | ||
206 | otg_dbg("Failed to write PMIC.\n"); | ||
207 | |||
208 | } | ||
209 | |||
210 | /* charge vbus or discharge vbus through a resistor to ground */ | ||
211 | static void langwell_otg_chrg_vbus(int on) | ||
212 | { | ||
213 | |||
214 | u32 val; | ||
215 | |||
216 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
217 | |||
218 | if (on) | ||
219 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC, | ||
220 | the_transceiver->regs + CI_OTGSC); | ||
221 | else | ||
222 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD, | ||
223 | the_transceiver->regs + CI_OTGSC); | ||
224 | |||
225 | } | ||
226 | |||
227 | /* Start SRP */ | ||
228 | static int langwell_otg_start_srp(struct otg_transceiver *otg) | ||
229 | { | ||
230 | u32 val; | ||
231 | |||
232 | otg_dbg("Start SRP ->\n"); | ||
233 | |||
234 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
235 | |||
236 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP, | ||
237 | the_transceiver->regs + CI_OTGSC); | ||
238 | |||
239 | /* Check if the data plus is finished or not */ | ||
240 | msleep(8); | ||
241 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
242 | if (val & (OTGSC_HADP | OTGSC_DP)) | ||
243 | otg_dbg("DataLine SRP Error\n"); | ||
244 | |||
245 | /* FIXME: VBus SRP */ | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | |||
251 | /* stop SOF via bus_suspend */ | ||
252 | static void langwell_otg_loc_sof(int on) | ||
253 | { | ||
254 | struct usb_hcd *hcd; | ||
255 | int err; | ||
256 | |||
257 | otg_dbg("loc_sof -> %d\n", on); | ||
258 | |||
259 | hcd = bus_to_hcd(the_transceiver->otg.host); | ||
260 | if (on) | ||
261 | err = hcd->driver->bus_resume(hcd); | ||
262 | else | ||
263 | err = hcd->driver->bus_suspend(hcd); | ||
264 | |||
265 | if (err) | ||
266 | otg_dbg("Failed to resume/suspend bus - %d\n", err); | ||
267 | } | ||
268 | |||
269 | static void langwell_otg_phy_low_power(int on) | ||
270 | { | ||
271 | u32 val; | ||
272 | |||
273 | otg_dbg("phy low power mode-> %d\n", on); | ||
274 | |||
275 | val = readl(the_transceiver->regs + CI_HOSTPC1); | ||
276 | if (on) | ||
277 | writel(val | HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1); | ||
278 | else | ||
279 | writel(val & ~HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1); | ||
280 | } | ||
281 | |||
282 | /* Enable/Disable OTG interrupt */ | ||
283 | static void langwell_otg_intr(int on) | ||
284 | { | ||
285 | u32 val; | ||
286 | |||
287 | otg_dbg("interrupt -> %d\n", on); | ||
288 | |||
289 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
290 | if (on) { | ||
291 | val = val | (OTGSC_INTEN_MASK | OTGSC_IDPU); | ||
292 | writel(val, the_transceiver->regs + CI_OTGSC); | ||
293 | } else { | ||
294 | val = val & ~(OTGSC_INTEN_MASK | OTGSC_IDPU); | ||
295 | writel(val, the_transceiver->regs + CI_OTGSC); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | /* set HAAR: Hardware Assist Auto-Reset */ | ||
300 | static void langwell_otg_HAAR(int on) | ||
301 | { | ||
302 | u32 val; | ||
303 | |||
304 | otg_dbg("HAAR -> %d\n", on); | ||
305 | |||
306 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
307 | if (on) | ||
308 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR, | ||
309 | the_transceiver->regs + CI_OTGSC); | ||
310 | else | ||
311 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR, | ||
312 | the_transceiver->regs + CI_OTGSC); | ||
313 | } | ||
314 | |||
315 | /* set HABA: Hardware Assist B-Disconnect to A-Connect */ | ||
316 | static void langwell_otg_HABA(int on) | ||
317 | { | ||
318 | u32 val; | ||
319 | |||
320 | otg_dbg("HABA -> %d\n", on); | ||
321 | |||
322 | val = readl(the_transceiver->regs + CI_OTGSC); | ||
323 | if (on) | ||
324 | writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA, | ||
325 | the_transceiver->regs + CI_OTGSC); | ||
326 | else | ||
327 | writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA, | ||
328 | the_transceiver->regs + CI_OTGSC); | ||
329 | } | ||
330 | |||
331 | static int langwell_otg_check_se0_srp(int on) | ||
332 | { | ||
333 | u32 val; | ||
334 | |||
335 | int delay_time = TB_SE0_SRP * 10; /* step is 100us */ | ||
336 | |||
337 | otg_dbg("check_se0_srp -> \n"); | ||
338 | |||
339 | do { | ||
340 | udelay(100); | ||
341 | if (!delay_time--) | ||
342 | break; | ||
343 | val = readl(the_transceiver->regs + CI_PORTSC1); | ||
344 | val &= PORTSC_LS; | ||
345 | } while (!val); | ||
346 | |||
347 | otg_dbg("check_se0_srp <- \n"); | ||
348 | return val; | ||
349 | } | ||
350 | |||
351 | /* The timeout callback function to set time out bit */ | ||
352 | static void set_tmout(unsigned long indicator) | ||
353 | { | ||
354 | *(int *)indicator = 1; | ||
355 | } | ||
356 | |||
357 | void langwell_otg_nsf_msg(unsigned long indicator) | ||
358 | { | ||
359 | switch (indicator) { | ||
360 | case 2: | ||
361 | case 4: | ||
362 | case 6: | ||
363 | case 7: | ||
364 | printk(KERN_ERR "OTG:NSF-%lu - deivce not responding\n", | ||
365 | indicator); | ||
366 | break; | ||
367 | case 3: | ||
368 | printk(KERN_ERR "OTG:NSF-%lu - deivce not supported\n", | ||
369 | indicator); | ||
370 | break; | ||
371 | default: | ||
372 | printk(KERN_ERR "Do not have this kind of NSF\n"); | ||
373 | break; | ||
374 | } | ||
375 | } | ||
376 | |||
377 | /* Initialize timers */ | ||
378 | static void langwell_otg_init_timers(struct otg_hsm *hsm) | ||
379 | { | ||
380 | /* HSM used timers */ | ||
381 | a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE, | ||
382 | (unsigned long)&hsm->a_wait_vrise_tmout); | ||
383 | a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON, | ||
384 | (unsigned long)&hsm->a_wait_bcon_tmout); | ||
385 | a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS, | ||
386 | (unsigned long)&hsm->a_aidl_bdis_tmout); | ||
387 | b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST, | ||
388 | (unsigned long)&hsm->b_ase0_brst_tmout); | ||
389 | b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP, | ||
390 | (unsigned long)&hsm->b_se0_srp); | ||
391 | b_srp_res_tmr = otg_timer_initializer(&set_tmout, TB_SRP_RES, | ||
392 | (unsigned long)&hsm->b_srp_res_tmout); | ||
393 | b_bus_suspend_tmr = otg_timer_initializer(&set_tmout, TB_BUS_SUSPEND, | ||
394 | (unsigned long)&hsm->b_bus_suspend_tmout); | ||
395 | } | ||
396 | |||
397 | /* Free timers */ | ||
398 | static void langwell_otg_free_timers(void) | ||
399 | { | ||
400 | kfree(a_wait_vrise_tmr); | ||
401 | kfree(a_wait_bcon_tmr); | ||
402 | kfree(a_aidl_bdis_tmr); | ||
403 | kfree(b_ase0_brst_tmr); | ||
404 | kfree(b_se0_srp_tmr); | ||
405 | kfree(b_srp_res_tmr); | ||
406 | kfree(b_bus_suspend_tmr); | ||
407 | } | ||
408 | |||
409 | /* Add timer to timer list */ | ||
410 | static void langwell_otg_add_timer(void *gtimer) | ||
411 | { | ||
412 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
413 | struct langwell_otg_timer *tmp_timer; | ||
414 | u32 val32; | ||
415 | |||
416 | /* Check if the timer is already in the active list, | ||
417 | * if so update timer count | ||
418 | */ | ||
419 | list_for_each_entry(tmp_timer, &active_timers, list) | ||
420 | if (tmp_timer == timer) { | ||
421 | timer->count = timer->expires; | ||
422 | return; | ||
423 | } | ||
424 | timer->count = timer->expires; | ||
425 | |||
426 | if (list_empty(&active_timers)) { | ||
427 | val32 = readl(the_transceiver->regs + CI_OTGSC); | ||
428 | writel(val32 | OTGSC_1MSE, the_transceiver->regs + CI_OTGSC); | ||
429 | } | ||
430 | |||
431 | list_add_tail(&timer->list, &active_timers); | ||
432 | } | ||
433 | |||
434 | /* Remove timer from the timer list; clear timeout status */ | ||
435 | static void langwell_otg_del_timer(void *gtimer) | ||
436 | { | ||
437 | struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer; | ||
438 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
439 | u32 val32; | ||
440 | |||
441 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) | ||
442 | if (tmp_timer == timer) | ||
443 | list_del(&timer->list); | ||
444 | |||
445 | if (list_empty(&active_timers)) { | ||
446 | val32 = readl(the_transceiver->regs + CI_OTGSC); | ||
447 | writel(val32 & ~OTGSC_1MSE, the_transceiver->regs + CI_OTGSC); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | /* Reduce timer count by 1, and find timeout conditions.*/ | ||
452 | static int langwell_otg_tick_timer(u32 *int_sts) | ||
453 | { | ||
454 | struct langwell_otg_timer *tmp_timer, *del_tmp; | ||
455 | int expired = 0; | ||
456 | |||
457 | list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) { | ||
458 | tmp_timer->count--; | ||
459 | /* check if timer expires */ | ||
460 | if (!tmp_timer->count) { | ||
461 | list_del(&tmp_timer->list); | ||
462 | tmp_timer->function(tmp_timer->data); | ||
463 | expired = 1; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | if (list_empty(&active_timers)) { | ||
468 | otg_dbg("tick timer: disable 1ms int\n"); | ||
469 | *int_sts = *int_sts & ~OTGSC_1MSE; | ||
470 | } | ||
471 | return expired; | ||
472 | } | ||
473 | |||
474 | static void reset_otg(void) | ||
475 | { | ||
476 | u32 val; | ||
477 | int delay_time = 1000; | ||
478 | |||
479 | otg_dbg("reseting OTG controller ...\n"); | ||
480 | val = readl(the_transceiver->regs + CI_USBCMD); | ||
481 | writel(val | USBCMD_RST, the_transceiver->regs + CI_USBCMD); | ||
482 | do { | ||
483 | udelay(100); | ||
484 | if (!delay_time--) | ||
485 | otg_dbg("reset timeout\n"); | ||
486 | val = readl(the_transceiver->regs + CI_USBCMD); | ||
487 | val &= USBCMD_RST; | ||
488 | } while (val != 0); | ||
489 | otg_dbg("reset done.\n"); | ||
490 | } | ||
491 | |||
492 | static void set_host_mode(void) | ||
493 | { | ||
494 | u32 val; | ||
495 | |||
496 | reset_otg(); | ||
497 | val = readl(the_transceiver->regs + CI_USBMODE); | ||
498 | val = (val & (~USBMODE_CM)) | USBMODE_HOST; | ||
499 | writel(val, the_transceiver->regs + CI_USBMODE); | ||
500 | } | ||
501 | |||
502 | static void set_client_mode(void) | ||
503 | { | ||
504 | u32 val; | ||
505 | |||
506 | reset_otg(); | ||
507 | val = readl(the_transceiver->regs + CI_USBMODE); | ||
508 | val = (val & (~USBMODE_CM)) | USBMODE_DEVICE; | ||
509 | writel(val, the_transceiver->regs + CI_USBMODE); | ||
510 | } | ||
511 | |||
512 | static void init_hsm(void) | ||
513 | { | ||
514 | struct langwell_otg *langwell = the_transceiver; | ||
515 | u32 val32; | ||
516 | |||
517 | /* read OTGSC after reset */ | ||
518 | val32 = readl(langwell->regs + CI_OTGSC); | ||
519 | otg_dbg("%s: OTGSC init value = 0x%x\n", __func__, val32); | ||
520 | |||
521 | /* set init state */ | ||
522 | if (val32 & OTGSC_ID) { | ||
523 | langwell->hsm.id = 1; | ||
524 | langwell->otg.default_a = 0; | ||
525 | set_client_mode(); | ||
526 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
527 | langwell_otg_drv_vbus(0); | ||
528 | } else { | ||
529 | langwell->hsm.id = 0; | ||
530 | langwell->otg.default_a = 1; | ||
531 | set_host_mode(); | ||
532 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
533 | } | ||
534 | |||
535 | /* set session indicator */ | ||
536 | if (val32 & OTGSC_BSE) | ||
537 | langwell->hsm.b_sess_end = 1; | ||
538 | if (val32 & OTGSC_BSV) | ||
539 | langwell->hsm.b_sess_vld = 1; | ||
540 | if (val32 & OTGSC_ASV) | ||
541 | langwell->hsm.a_sess_vld = 1; | ||
542 | if (val32 & OTGSC_AVV) | ||
543 | langwell->hsm.a_vbus_vld = 1; | ||
544 | |||
545 | /* defautly power the bus */ | ||
546 | langwell->hsm.a_bus_req = 1; | ||
547 | langwell->hsm.a_bus_drop = 0; | ||
548 | /* defautly don't request bus as B device */ | ||
549 | langwell->hsm.b_bus_req = 0; | ||
550 | /* no system error */ | ||
551 | langwell->hsm.a_clr_err = 0; | ||
552 | } | ||
553 | |||
554 | static irqreturn_t otg_dummy_irq(int irq, void *_dev) | ||
555 | { | ||
556 | void __iomem *reg_base = _dev; | ||
557 | u32 val; | ||
558 | u32 int_mask = 0; | ||
559 | |||
560 | val = readl(reg_base + CI_USBMODE); | ||
561 | if ((val & USBMODE_CM) != USBMODE_DEVICE) | ||
562 | return IRQ_NONE; | ||
563 | |||
564 | val = readl(reg_base + CI_USBSTS); | ||
565 | int_mask = val & INTR_DUMMY_MASK; | ||
566 | |||
567 | if (int_mask == 0) | ||
568 | return IRQ_NONE; | ||
569 | |||
570 | /* clear hsm.b_conn here since host driver can't detect it | ||
571 | * otg_dummy_irq called means B-disconnect happened. | ||
572 | */ | ||
573 | if (the_transceiver->hsm.b_conn) { | ||
574 | the_transceiver->hsm.b_conn = 0; | ||
575 | if (spin_trylock(&the_transceiver->wq_lock)) { | ||
576 | queue_work(the_transceiver->qwork, | ||
577 | &the_transceiver->work); | ||
578 | spin_unlock(&the_transceiver->wq_lock); | ||
579 | } | ||
580 | } | ||
581 | /* Clear interrupts */ | ||
582 | writel(int_mask, reg_base + CI_USBSTS); | ||
583 | return IRQ_HANDLED; | ||
584 | } | ||
585 | |||
586 | static irqreturn_t otg_irq(int irq, void *_dev) | ||
587 | { | ||
588 | struct langwell_otg *langwell = _dev; | ||
589 | u32 int_sts, int_en; | ||
590 | u32 int_mask = 0; | ||
591 | int flag = 0; | ||
592 | |||
593 | int_sts = readl(langwell->regs + CI_OTGSC); | ||
594 | int_en = (int_sts & OTGSC_INTEN_MASK) >> 8; | ||
595 | int_mask = int_sts & int_en; | ||
596 | if (int_mask == 0) | ||
597 | return IRQ_NONE; | ||
598 | |||
599 | if (int_mask & OTGSC_IDIS) { | ||
600 | otg_dbg("%s: id change int\n", __func__); | ||
601 | langwell->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0; | ||
602 | flag = 1; | ||
603 | } | ||
604 | if (int_mask & OTGSC_DPIS) { | ||
605 | otg_dbg("%s: data pulse int\n", __func__); | ||
606 | langwell->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0; | ||
607 | flag = 1; | ||
608 | } | ||
609 | if (int_mask & OTGSC_BSEIS) { | ||
610 | otg_dbg("%s: b session end int\n", __func__); | ||
611 | langwell->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0; | ||
612 | flag = 1; | ||
613 | } | ||
614 | if (int_mask & OTGSC_BSVIS) { | ||
615 | otg_dbg("%s: b session valid int\n", __func__); | ||
616 | langwell->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0; | ||
617 | flag = 1; | ||
618 | } | ||
619 | if (int_mask & OTGSC_ASVIS) { | ||
620 | otg_dbg("%s: a session valid int\n", __func__); | ||
621 | langwell->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0; | ||
622 | flag = 1; | ||
623 | } | ||
624 | if (int_mask & OTGSC_AVVIS) { | ||
625 | otg_dbg("%s: a vbus valid int\n", __func__); | ||
626 | langwell->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0; | ||
627 | flag = 1; | ||
628 | } | ||
629 | |||
630 | if (int_mask & OTGSC_1MSS) { | ||
631 | /* need to schedule otg_work if any timer is expired */ | ||
632 | if (langwell_otg_tick_timer(&int_sts)) | ||
633 | flag = 1; | ||
634 | } | ||
635 | |||
636 | writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask, | ||
637 | langwell->regs + CI_OTGSC); | ||
638 | if (flag) | ||
639 | queue_work(langwell->qwork, &langwell->work); | ||
640 | |||
641 | return IRQ_HANDLED; | ||
642 | } | ||
643 | |||
644 | static void langwell_otg_work(struct work_struct *work) | ||
645 | { | ||
646 | struct langwell_otg *langwell = container_of(work, | ||
647 | struct langwell_otg, work); | ||
648 | int retval; | ||
649 | |||
650 | otg_dbg("%s: old state = %s\n", __func__, | ||
651 | state_string(langwell->otg.state)); | ||
652 | |||
653 | switch (langwell->otg.state) { | ||
654 | case OTG_STATE_UNDEFINED: | ||
655 | case OTG_STATE_B_IDLE: | ||
656 | if (!langwell->hsm.id) { | ||
657 | langwell_otg_del_timer(b_srp_res_tmr); | ||
658 | langwell->otg.default_a = 1; | ||
659 | langwell->hsm.a_srp_det = 0; | ||
660 | |||
661 | langwell_otg_chrg_vbus(0); | ||
662 | langwell_otg_drv_vbus(0); | ||
663 | |||
664 | set_host_mode(); | ||
665 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
666 | queue_work(langwell->qwork, &langwell->work); | ||
667 | } else if (langwell->hsm.b_srp_res_tmout) { | ||
668 | langwell->hsm.b_srp_res_tmout = 0; | ||
669 | langwell->hsm.b_bus_req = 0; | ||
670 | langwell_otg_nsf_msg(6); | ||
671 | } else if (langwell->hsm.b_sess_vld) { | ||
672 | langwell_otg_del_timer(b_srp_res_tmr); | ||
673 | langwell->hsm.b_sess_end = 0; | ||
674 | langwell->hsm.a_bus_suspend = 0; | ||
675 | |||
676 | langwell_otg_chrg_vbus(0); | ||
677 | if (langwell->client_ops) { | ||
678 | langwell->client_ops->resume(langwell->pdev); | ||
679 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
680 | } else | ||
681 | otg_dbg("client driver not loaded.\n"); | ||
682 | |||
683 | } else if (langwell->hsm.b_bus_req && | ||
684 | (langwell->hsm.b_sess_end)) { | ||
685 | /* workaround for b_se0_srp detection */ | ||
686 | retval = langwell_otg_check_se0_srp(0); | ||
687 | if (retval) { | ||
688 | langwell->hsm.b_bus_req = 0; | ||
689 | otg_dbg("LS is not SE0, try again later\n"); | ||
690 | } else { | ||
691 | /* Start SRP */ | ||
692 | langwell_otg_start_srp(&langwell->otg); | ||
693 | langwell_otg_add_timer(b_srp_res_tmr); | ||
694 | } | ||
695 | } | ||
696 | break; | ||
697 | case OTG_STATE_B_SRP_INIT: | ||
698 | if (!langwell->hsm.id) { | ||
699 | langwell->otg.default_a = 1; | ||
700 | langwell->hsm.a_srp_det = 0; | ||
701 | |||
702 | langwell_otg_drv_vbus(0); | ||
703 | langwell_otg_chrg_vbus(0); | ||
704 | |||
705 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
706 | queue_work(langwell->qwork, &langwell->work); | ||
707 | } else if (langwell->hsm.b_sess_vld) { | ||
708 | langwell_otg_chrg_vbus(0); | ||
709 | if (langwell->client_ops) { | ||
710 | langwell->client_ops->resume(langwell->pdev); | ||
711 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
712 | } else | ||
713 | otg_dbg("client driver not loaded.\n"); | ||
714 | } | ||
715 | break; | ||
716 | case OTG_STATE_B_PERIPHERAL: | ||
717 | if (!langwell->hsm.id) { | ||
718 | langwell->otg.default_a = 1; | ||
719 | langwell->hsm.a_srp_det = 0; | ||
720 | |||
721 | langwell_otg_drv_vbus(0); | ||
722 | langwell_otg_chrg_vbus(0); | ||
723 | set_host_mode(); | ||
724 | |||
725 | if (langwell->client_ops) { | ||
726 | langwell->client_ops->suspend(langwell->pdev, | ||
727 | PMSG_FREEZE); | ||
728 | } else | ||
729 | otg_dbg("client driver has been removed.\n"); | ||
730 | |||
731 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
732 | queue_work(langwell->qwork, &langwell->work); | ||
733 | } else if (!langwell->hsm.b_sess_vld) { | ||
734 | langwell->hsm.b_hnp_enable = 0; | ||
735 | |||
736 | if (langwell->client_ops) { | ||
737 | langwell->client_ops->suspend(langwell->pdev, | ||
738 | PMSG_FREEZE); | ||
739 | } else | ||
740 | otg_dbg("client driver has been removed.\n"); | ||
741 | |||
742 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
743 | } else if (langwell->hsm.b_bus_req && langwell->hsm.b_hnp_enable | ||
744 | && langwell->hsm.a_bus_suspend) { | ||
745 | |||
746 | if (langwell->client_ops) { | ||
747 | langwell->client_ops->suspend(langwell->pdev, | ||
748 | PMSG_FREEZE); | ||
749 | } else | ||
750 | otg_dbg("client driver has been removed.\n"); | ||
751 | |||
752 | langwell_otg_HAAR(1); | ||
753 | langwell->hsm.a_conn = 0; | ||
754 | |||
755 | if (langwell->host_ops) { | ||
756 | langwell->host_ops->probe(langwell->pdev, | ||
757 | langwell->host_ops->id_table); | ||
758 | langwell->otg.state = OTG_STATE_B_WAIT_ACON; | ||
759 | } else | ||
760 | otg_dbg("host driver not loaded.\n"); | ||
761 | |||
762 | langwell->hsm.a_bus_resume = 0; | ||
763 | langwell->hsm.b_ase0_brst_tmout = 0; | ||
764 | langwell_otg_add_timer(b_ase0_brst_tmr); | ||
765 | } | ||
766 | break; | ||
767 | |||
768 | case OTG_STATE_B_WAIT_ACON: | ||
769 | if (!langwell->hsm.id) { | ||
770 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
771 | langwell->otg.default_a = 1; | ||
772 | langwell->hsm.a_srp_det = 0; | ||
773 | |||
774 | langwell_otg_drv_vbus(0); | ||
775 | langwell_otg_chrg_vbus(0); | ||
776 | set_host_mode(); | ||
777 | |||
778 | langwell_otg_HAAR(0); | ||
779 | if (langwell->host_ops) | ||
780 | langwell->host_ops->remove(langwell->pdev); | ||
781 | else | ||
782 | otg_dbg("host driver has been removed.\n"); | ||
783 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
784 | queue_work(langwell->qwork, &langwell->work); | ||
785 | } else if (!langwell->hsm.b_sess_vld) { | ||
786 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
787 | langwell->hsm.b_hnp_enable = 0; | ||
788 | langwell->hsm.b_bus_req = 0; | ||
789 | langwell_otg_chrg_vbus(0); | ||
790 | langwell_otg_HAAR(0); | ||
791 | |||
792 | if (langwell->host_ops) | ||
793 | langwell->host_ops->remove(langwell->pdev); | ||
794 | else | ||
795 | otg_dbg("host driver has been removed.\n"); | ||
796 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
797 | } else if (langwell->hsm.a_conn) { | ||
798 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
799 | langwell_otg_HAAR(0); | ||
800 | langwell->otg.state = OTG_STATE_B_HOST; | ||
801 | queue_work(langwell->qwork, &langwell->work); | ||
802 | } else if (langwell->hsm.a_bus_resume || | ||
803 | langwell->hsm.b_ase0_brst_tmout) { | ||
804 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
805 | langwell_otg_HAAR(0); | ||
806 | langwell_otg_nsf_msg(7); | ||
807 | |||
808 | if (langwell->host_ops) | ||
809 | langwell->host_ops->remove(langwell->pdev); | ||
810 | else | ||
811 | otg_dbg("host driver has been removed.\n"); | ||
812 | |||
813 | langwell->hsm.a_bus_suspend = 0; | ||
814 | langwell->hsm.b_bus_req = 0; | ||
815 | |||
816 | if (langwell->client_ops) | ||
817 | langwell->client_ops->resume(langwell->pdev); | ||
818 | else | ||
819 | otg_dbg("client driver not loaded.\n"); | ||
820 | |||
821 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
822 | } | ||
823 | break; | ||
824 | |||
825 | case OTG_STATE_B_HOST: | ||
826 | if (!langwell->hsm.id) { | ||
827 | langwell->otg.default_a = 1; | ||
828 | langwell->hsm.a_srp_det = 0; | ||
829 | |||
830 | langwell_otg_drv_vbus(0); | ||
831 | langwell_otg_chrg_vbus(0); | ||
832 | set_host_mode(); | ||
833 | if (langwell->host_ops) | ||
834 | langwell->host_ops->remove(langwell->pdev); | ||
835 | else | ||
836 | otg_dbg("host driver has been removed.\n"); | ||
837 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
838 | queue_work(langwell->qwork, &langwell->work); | ||
839 | } else if (!langwell->hsm.b_sess_vld) { | ||
840 | langwell->hsm.b_hnp_enable = 0; | ||
841 | langwell->hsm.b_bus_req = 0; | ||
842 | langwell_otg_chrg_vbus(0); | ||
843 | if (langwell->host_ops) | ||
844 | langwell->host_ops->remove(langwell->pdev); | ||
845 | else | ||
846 | otg_dbg("host driver has been removed.\n"); | ||
847 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
848 | } else if ((!langwell->hsm.b_bus_req) || | ||
849 | (!langwell->hsm.a_conn)) { | ||
850 | langwell->hsm.b_bus_req = 0; | ||
851 | langwell_otg_loc_sof(0); | ||
852 | if (langwell->host_ops) | ||
853 | langwell->host_ops->remove(langwell->pdev); | ||
854 | else | ||
855 | otg_dbg("host driver has been removed.\n"); | ||
856 | |||
857 | langwell->hsm.a_bus_suspend = 0; | ||
858 | |||
859 | if (langwell->client_ops) | ||
860 | langwell->client_ops->resume(langwell->pdev); | ||
861 | else | ||
862 | otg_dbg("client driver not loaded.\n"); | ||
863 | |||
864 | langwell->otg.state = OTG_STATE_B_PERIPHERAL; | ||
865 | } | ||
866 | break; | ||
867 | |||
868 | case OTG_STATE_A_IDLE: | ||
869 | langwell->otg.default_a = 1; | ||
870 | if (langwell->hsm.id) { | ||
871 | langwell->otg.default_a = 0; | ||
872 | langwell->hsm.b_bus_req = 0; | ||
873 | langwell_otg_drv_vbus(0); | ||
874 | langwell_otg_chrg_vbus(0); | ||
875 | |||
876 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
877 | queue_work(langwell->qwork, &langwell->work); | ||
878 | } else if (langwell->hsm.a_sess_vld) { | ||
879 | langwell_otg_drv_vbus(1); | ||
880 | langwell->hsm.a_srp_det = 1; | ||
881 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
882 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
883 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
884 | queue_work(langwell->qwork, &langwell->work); | ||
885 | } else if (!langwell->hsm.a_bus_drop && | ||
886 | (langwell->hsm.a_srp_det || langwell->hsm.a_bus_req)) { | ||
887 | langwell_otg_drv_vbus(1); | ||
888 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
889 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
890 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
891 | queue_work(langwell->qwork, &langwell->work); | ||
892 | } | ||
893 | break; | ||
894 | case OTG_STATE_A_WAIT_VRISE: | ||
895 | if (langwell->hsm.id) { | ||
896 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
897 | langwell->hsm.b_bus_req = 0; | ||
898 | langwell->otg.default_a = 0; | ||
899 | langwell_otg_drv_vbus(0); | ||
900 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
901 | } else if (langwell->hsm.a_vbus_vld) { | ||
902 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
903 | if (langwell->host_ops) | ||
904 | langwell->host_ops->probe(langwell->pdev, | ||
905 | langwell->host_ops->id_table); | ||
906 | else | ||
907 | otg_dbg("host driver not loaded.\n"); | ||
908 | langwell->hsm.b_conn = 0; | ||
909 | langwell->hsm.a_set_b_hnp_en = 0; | ||
910 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
911 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
912 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
913 | } else if (langwell->hsm.a_wait_vrise_tmout) { | ||
914 | if (langwell->hsm.a_vbus_vld) { | ||
915 | if (langwell->host_ops) | ||
916 | langwell->host_ops->probe( | ||
917 | langwell->pdev, | ||
918 | langwell->host_ops->id_table); | ||
919 | else | ||
920 | otg_dbg("host driver not loaded.\n"); | ||
921 | langwell->hsm.b_conn = 0; | ||
922 | langwell->hsm.a_set_b_hnp_en = 0; | ||
923 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
924 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
925 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
926 | } else { | ||
927 | langwell_otg_drv_vbus(0); | ||
928 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
929 | } | ||
930 | } | ||
931 | break; | ||
932 | case OTG_STATE_A_WAIT_BCON: | ||
933 | if (langwell->hsm.id) { | ||
934 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
935 | |||
936 | langwell->otg.default_a = 0; | ||
937 | langwell->hsm.b_bus_req = 0; | ||
938 | if (langwell->host_ops) | ||
939 | langwell->host_ops->remove(langwell->pdev); | ||
940 | else | ||
941 | otg_dbg("host driver has been removed.\n"); | ||
942 | langwell_otg_drv_vbus(0); | ||
943 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
944 | queue_work(langwell->qwork, &langwell->work); | ||
945 | } else if (!langwell->hsm.a_vbus_vld) { | ||
946 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
947 | |||
948 | if (langwell->host_ops) | ||
949 | langwell->host_ops->remove(langwell->pdev); | ||
950 | else | ||
951 | otg_dbg("host driver has been removed.\n"); | ||
952 | langwell_otg_drv_vbus(0); | ||
953 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
954 | } else if (langwell->hsm.a_bus_drop || | ||
955 | (langwell->hsm.a_wait_bcon_tmout && | ||
956 | !langwell->hsm.a_bus_req)) { | ||
957 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
958 | |||
959 | if (langwell->host_ops) | ||
960 | langwell->host_ops->remove(langwell->pdev); | ||
961 | else | ||
962 | otg_dbg("host driver has been removed.\n"); | ||
963 | langwell_otg_drv_vbus(0); | ||
964 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
965 | } else if (langwell->hsm.b_conn) { | ||
966 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
967 | |||
968 | langwell->hsm.a_suspend_req = 0; | ||
969 | langwell->otg.state = OTG_STATE_A_HOST; | ||
970 | if (!langwell->hsm.a_bus_req && | ||
971 | langwell->hsm.a_set_b_hnp_en) { | ||
972 | /* It is not safe enough to do a fast | ||
973 | * transistion from A_WAIT_BCON to | ||
974 | * A_SUSPEND */ | ||
975 | msleep(10000); | ||
976 | if (langwell->hsm.a_bus_req) | ||
977 | break; | ||
978 | |||
979 | if (request_irq(langwell->pdev->irq, | ||
980 | otg_dummy_irq, IRQF_SHARED, | ||
981 | driver_name, langwell->regs) != 0) { | ||
982 | otg_dbg("request interrupt %d fail\n", | ||
983 | langwell->pdev->irq); | ||
984 | } | ||
985 | |||
986 | langwell_otg_HABA(1); | ||
987 | langwell->hsm.b_bus_resume = 0; | ||
988 | langwell->hsm.a_aidl_bdis_tmout = 0; | ||
989 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
990 | |||
991 | langwell_otg_loc_sof(0); | ||
992 | langwell->otg.state = OTG_STATE_A_SUSPEND; | ||
993 | } else if (!langwell->hsm.a_bus_req && | ||
994 | !langwell->hsm.a_set_b_hnp_en) { | ||
995 | struct pci_dev *pdev = langwell->pdev; | ||
996 | if (langwell->host_ops) | ||
997 | langwell->host_ops->remove(pdev); | ||
998 | else | ||
999 | otg_dbg("host driver removed.\n"); | ||
1000 | langwell_otg_drv_vbus(0); | ||
1001 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1002 | } | ||
1003 | } | ||
1004 | break; | ||
1005 | case OTG_STATE_A_HOST: | ||
1006 | if (langwell->hsm.id) { | ||
1007 | langwell->otg.default_a = 0; | ||
1008 | langwell->hsm.b_bus_req = 0; | ||
1009 | if (langwell->host_ops) | ||
1010 | langwell->host_ops->remove(langwell->pdev); | ||
1011 | else | ||
1012 | otg_dbg("host driver has been removed.\n"); | ||
1013 | langwell_otg_drv_vbus(0); | ||
1014 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1015 | queue_work(langwell->qwork, &langwell->work); | ||
1016 | } else if (langwell->hsm.a_bus_drop || | ||
1017 | (!langwell->hsm.a_set_b_hnp_en && !langwell->hsm.a_bus_req)) { | ||
1018 | if (langwell->host_ops) | ||
1019 | langwell->host_ops->remove(langwell->pdev); | ||
1020 | else | ||
1021 | otg_dbg("host driver has been removed.\n"); | ||
1022 | langwell_otg_drv_vbus(0); | ||
1023 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1024 | } else if (!langwell->hsm.a_vbus_vld) { | ||
1025 | if (langwell->host_ops) | ||
1026 | langwell->host_ops->remove(langwell->pdev); | ||
1027 | else | ||
1028 | otg_dbg("host driver has been removed.\n"); | ||
1029 | langwell_otg_drv_vbus(0); | ||
1030 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1031 | } else if (langwell->hsm.a_set_b_hnp_en | ||
1032 | && !langwell->hsm.a_bus_req) { | ||
1033 | /* Set HABA to enable hardware assistance to signal | ||
1034 | * A-connect after receiver B-disconnect. Hardware | ||
1035 | * will then set client mode and enable URE, SLE and | ||
1036 | * PCE after the assistance. otg_dummy_irq is used to | ||
1037 | * clean these ints when client driver is not resumed. | ||
1038 | */ | ||
1039 | if (request_irq(langwell->pdev->irq, | ||
1040 | otg_dummy_irq, IRQF_SHARED, driver_name, | ||
1041 | langwell->regs) != 0) { | ||
1042 | otg_dbg("request interrupt %d failed\n", | ||
1043 | langwell->pdev->irq); | ||
1044 | } | ||
1045 | |||
1046 | /* set HABA */ | ||
1047 | langwell_otg_HABA(1); | ||
1048 | langwell->hsm.b_bus_resume = 0; | ||
1049 | langwell->hsm.a_aidl_bdis_tmout = 0; | ||
1050 | langwell_otg_add_timer(a_aidl_bdis_tmr); | ||
1051 | langwell_otg_loc_sof(0); | ||
1052 | langwell->otg.state = OTG_STATE_A_SUSPEND; | ||
1053 | } else if (!langwell->hsm.b_conn || !langwell->hsm.a_bus_req) { | ||
1054 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
1055 | langwell->hsm.a_set_b_hnp_en = 0; | ||
1056 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1057 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1058 | } | ||
1059 | break; | ||
1060 | case OTG_STATE_A_SUSPEND: | ||
1061 | if (langwell->hsm.id) { | ||
1062 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1063 | langwell_otg_HABA(0); | ||
1064 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1065 | langwell->otg.default_a = 0; | ||
1066 | langwell->hsm.b_bus_req = 0; | ||
1067 | if (langwell->host_ops) | ||
1068 | langwell->host_ops->remove(langwell->pdev); | ||
1069 | else | ||
1070 | otg_dbg("host driver has been removed.\n"); | ||
1071 | langwell_otg_drv_vbus(0); | ||
1072 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1073 | queue_work(langwell->qwork, &langwell->work); | ||
1074 | } else if (langwell->hsm.a_bus_req || | ||
1075 | langwell->hsm.b_bus_resume) { | ||
1076 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1077 | langwell_otg_HABA(0); | ||
1078 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1079 | langwell->hsm.a_suspend_req = 0; | ||
1080 | langwell_otg_loc_sof(1); | ||
1081 | langwell->otg.state = OTG_STATE_A_HOST; | ||
1082 | } else if (langwell->hsm.a_aidl_bdis_tmout || | ||
1083 | langwell->hsm.a_bus_drop) { | ||
1084 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1085 | langwell_otg_HABA(0); | ||
1086 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1087 | if (langwell->host_ops) | ||
1088 | langwell->host_ops->remove(langwell->pdev); | ||
1089 | else | ||
1090 | otg_dbg("host driver has been removed.\n"); | ||
1091 | langwell_otg_drv_vbus(0); | ||
1092 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1093 | } else if (!langwell->hsm.b_conn && | ||
1094 | langwell->hsm.a_set_b_hnp_en) { | ||
1095 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1096 | langwell_otg_HABA(0); | ||
1097 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1098 | |||
1099 | if (langwell->host_ops) | ||
1100 | langwell->host_ops->remove(langwell->pdev); | ||
1101 | else | ||
1102 | otg_dbg("host driver has been removed.\n"); | ||
1103 | |||
1104 | langwell->hsm.b_bus_suspend = 0; | ||
1105 | langwell->hsm.b_bus_suspend_vld = 0; | ||
1106 | langwell->hsm.b_bus_suspend_tmout = 0; | ||
1107 | |||
1108 | /* msleep(200); */ | ||
1109 | if (langwell->client_ops) | ||
1110 | langwell->client_ops->resume(langwell->pdev); | ||
1111 | else | ||
1112 | otg_dbg("client driver not loaded.\n"); | ||
1113 | |||
1114 | langwell_otg_add_timer(b_bus_suspend_tmr); | ||
1115 | langwell->otg.state = OTG_STATE_A_PERIPHERAL; | ||
1116 | break; | ||
1117 | } else if (!langwell->hsm.a_vbus_vld) { | ||
1118 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1119 | langwell_otg_HABA(0); | ||
1120 | free_irq(langwell->pdev->irq, langwell->regs); | ||
1121 | if (langwell->host_ops) | ||
1122 | langwell->host_ops->remove(langwell->pdev); | ||
1123 | else | ||
1124 | otg_dbg("host driver has been removed.\n"); | ||
1125 | langwell_otg_drv_vbus(0); | ||
1126 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1127 | } | ||
1128 | break; | ||
1129 | case OTG_STATE_A_PERIPHERAL: | ||
1130 | if (langwell->hsm.id) { | ||
1131 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1132 | langwell->otg.default_a = 0; | ||
1133 | langwell->hsm.b_bus_req = 0; | ||
1134 | if (langwell->client_ops) | ||
1135 | langwell->client_ops->suspend(langwell->pdev, | ||
1136 | PMSG_FREEZE); | ||
1137 | else | ||
1138 | otg_dbg("client driver has been removed.\n"); | ||
1139 | langwell_otg_drv_vbus(0); | ||
1140 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1141 | queue_work(langwell->qwork, &langwell->work); | ||
1142 | } else if (!langwell->hsm.a_vbus_vld) { | ||
1143 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1144 | if (langwell->client_ops) | ||
1145 | langwell->client_ops->suspend(langwell->pdev, | ||
1146 | PMSG_FREEZE); | ||
1147 | else | ||
1148 | otg_dbg("client driver has been removed.\n"); | ||
1149 | langwell_otg_drv_vbus(0); | ||
1150 | langwell->otg.state = OTG_STATE_A_VBUS_ERR; | ||
1151 | } else if (langwell->hsm.a_bus_drop) { | ||
1152 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1153 | if (langwell->client_ops) | ||
1154 | langwell->client_ops->suspend(langwell->pdev, | ||
1155 | PMSG_FREEZE); | ||
1156 | else | ||
1157 | otg_dbg("client driver has been removed.\n"); | ||
1158 | langwell_otg_drv_vbus(0); | ||
1159 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1160 | } else if (langwell->hsm.b_bus_suspend) { | ||
1161 | langwell_otg_del_timer(b_bus_suspend_tmr); | ||
1162 | if (langwell->client_ops) | ||
1163 | langwell->client_ops->suspend(langwell->pdev, | ||
1164 | PMSG_FREEZE); | ||
1165 | else | ||
1166 | otg_dbg("client driver has been removed.\n"); | ||
1167 | |||
1168 | if (langwell->host_ops) | ||
1169 | langwell->host_ops->probe(langwell->pdev, | ||
1170 | langwell->host_ops->id_table); | ||
1171 | else | ||
1172 | otg_dbg("host driver not loaded.\n"); | ||
1173 | langwell->hsm.a_set_b_hnp_en = 0; | ||
1174 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
1175 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1176 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1177 | } else if (langwell->hsm.b_bus_suspend_tmout) { | ||
1178 | u32 val; | ||
1179 | val = readl(langwell->regs + CI_PORTSC1); | ||
1180 | if (!(val & PORTSC_SUSP)) | ||
1181 | break; | ||
1182 | if (langwell->client_ops) | ||
1183 | langwell->client_ops->suspend(langwell->pdev, | ||
1184 | PMSG_FREEZE); | ||
1185 | else | ||
1186 | otg_dbg("client driver has been removed.\n"); | ||
1187 | if (langwell->host_ops) | ||
1188 | langwell->host_ops->probe(langwell->pdev, | ||
1189 | langwell->host_ops->id_table); | ||
1190 | else | ||
1191 | otg_dbg("host driver not loaded.\n"); | ||
1192 | langwell->hsm.a_set_b_hnp_en = 0; | ||
1193 | langwell->hsm.a_wait_bcon_tmout = 0; | ||
1194 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1195 | langwell->otg.state = OTG_STATE_A_WAIT_BCON; | ||
1196 | } | ||
1197 | break; | ||
1198 | case OTG_STATE_A_VBUS_ERR: | ||
1199 | if (langwell->hsm.id) { | ||
1200 | langwell->otg.default_a = 0; | ||
1201 | langwell->hsm.a_clr_err = 0; | ||
1202 | langwell->hsm.a_srp_det = 0; | ||
1203 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1204 | queue_work(langwell->qwork, &langwell->work); | ||
1205 | } else if (langwell->hsm.a_clr_err) { | ||
1206 | langwell->hsm.a_clr_err = 0; | ||
1207 | langwell->hsm.a_srp_det = 0; | ||
1208 | reset_otg(); | ||
1209 | init_hsm(); | ||
1210 | if (langwell->otg.state == OTG_STATE_A_IDLE) | ||
1211 | queue_work(langwell->qwork, &langwell->work); | ||
1212 | } | ||
1213 | break; | ||
1214 | case OTG_STATE_A_WAIT_VFALL: | ||
1215 | if (langwell->hsm.id) { | ||
1216 | langwell->otg.default_a = 0; | ||
1217 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1218 | queue_work(langwell->qwork, &langwell->work); | ||
1219 | } else if (langwell->hsm.a_bus_req) { | ||
1220 | langwell_otg_drv_vbus(1); | ||
1221 | langwell->hsm.a_wait_vrise_tmout = 0; | ||
1222 | langwell_otg_add_timer(a_wait_vrise_tmr); | ||
1223 | langwell->otg.state = OTG_STATE_A_WAIT_VRISE; | ||
1224 | } else if (!langwell->hsm.a_sess_vld) { | ||
1225 | langwell->hsm.a_srp_det = 0; | ||
1226 | langwell_otg_drv_vbus(0); | ||
1227 | set_host_mode(); | ||
1228 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
1229 | } | ||
1230 | break; | ||
1231 | default: | ||
1232 | ; | ||
1233 | } | ||
1234 | |||
1235 | otg_dbg("%s: new state = %s\n", __func__, | ||
1236 | state_string(langwell->otg.state)); | ||
1237 | } | ||
1238 | |||
1239 | static ssize_t | ||
1240 | show_registers(struct device *_dev, struct device_attribute *attr, char *buf) | ||
1241 | { | ||
1242 | struct langwell_otg *langwell; | ||
1243 | char *next; | ||
1244 | unsigned size; | ||
1245 | unsigned t; | ||
1246 | |||
1247 | langwell = the_transceiver; | ||
1248 | next = buf; | ||
1249 | size = PAGE_SIZE; | ||
1250 | |||
1251 | t = scnprintf(next, size, | ||
1252 | "\n" | ||
1253 | "USBCMD = 0x%08x \n" | ||
1254 | "USBSTS = 0x%08x \n" | ||
1255 | "USBINTR = 0x%08x \n" | ||
1256 | "ASYNCLISTADDR = 0x%08x \n" | ||
1257 | "PORTSC1 = 0x%08x \n" | ||
1258 | "HOSTPC1 = 0x%08x \n" | ||
1259 | "OTGSC = 0x%08x \n" | ||
1260 | "USBMODE = 0x%08x \n", | ||
1261 | readl(langwell->regs + 0x30), | ||
1262 | readl(langwell->regs + 0x34), | ||
1263 | readl(langwell->regs + 0x38), | ||
1264 | readl(langwell->regs + 0x48), | ||
1265 | readl(langwell->regs + 0x74), | ||
1266 | readl(langwell->regs + 0xb4), | ||
1267 | readl(langwell->regs + 0xf4), | ||
1268 | readl(langwell->regs + 0xf8) | ||
1269 | ); | ||
1270 | size -= t; | ||
1271 | next += t; | ||
1272 | |||
1273 | return PAGE_SIZE - size; | ||
1274 | } | ||
1275 | static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); | ||
1276 | |||
1277 | static ssize_t | ||
1278 | show_hsm(struct device *_dev, struct device_attribute *attr, char *buf) | ||
1279 | { | ||
1280 | struct langwell_otg *langwell; | ||
1281 | char *next; | ||
1282 | unsigned size; | ||
1283 | unsigned t; | ||
1284 | |||
1285 | langwell = the_transceiver; | ||
1286 | next = buf; | ||
1287 | size = PAGE_SIZE; | ||
1288 | |||
1289 | t = scnprintf(next, size, | ||
1290 | "\n" | ||
1291 | "current state = %s\n" | ||
1292 | "a_bus_resume = \t%d\n" | ||
1293 | "a_bus_suspend = \t%d\n" | ||
1294 | "a_conn = \t%d\n" | ||
1295 | "a_sess_vld = \t%d\n" | ||
1296 | "a_srp_det = \t%d\n" | ||
1297 | "a_vbus_vld = \t%d\n" | ||
1298 | "b_bus_resume = \t%d\n" | ||
1299 | "b_bus_suspend = \t%d\n" | ||
1300 | "b_conn = \t%d\n" | ||
1301 | "b_se0_srp = \t%d\n" | ||
1302 | "b_sess_end = \t%d\n" | ||
1303 | "b_sess_vld = \t%d\n" | ||
1304 | "id = \t%d\n" | ||
1305 | "a_set_b_hnp_en = \t%d\n" | ||
1306 | "b_srp_done = \t%d\n" | ||
1307 | "b_hnp_enable = \t%d\n" | ||
1308 | "a_wait_vrise_tmout = \t%d\n" | ||
1309 | "a_wait_bcon_tmout = \t%d\n" | ||
1310 | "a_aidl_bdis_tmout = \t%d\n" | ||
1311 | "b_ase0_brst_tmout = \t%d\n" | ||
1312 | "a_bus_drop = \t%d\n" | ||
1313 | "a_bus_req = \t%d\n" | ||
1314 | "a_clr_err = \t%d\n" | ||
1315 | "a_suspend_req = \t%d\n" | ||
1316 | "b_bus_req = \t%d\n" | ||
1317 | "b_bus_suspend_tmout = \t%d\n" | ||
1318 | "b_bus_suspend_vld = \t%d\n", | ||
1319 | state_string(langwell->otg.state), | ||
1320 | langwell->hsm.a_bus_resume, | ||
1321 | langwell->hsm.a_bus_suspend, | ||
1322 | langwell->hsm.a_conn, | ||
1323 | langwell->hsm.a_sess_vld, | ||
1324 | langwell->hsm.a_srp_det, | ||
1325 | langwell->hsm.a_vbus_vld, | ||
1326 | langwell->hsm.b_bus_resume, | ||
1327 | langwell->hsm.b_bus_suspend, | ||
1328 | langwell->hsm.b_conn, | ||
1329 | langwell->hsm.b_se0_srp, | ||
1330 | langwell->hsm.b_sess_end, | ||
1331 | langwell->hsm.b_sess_vld, | ||
1332 | langwell->hsm.id, | ||
1333 | langwell->hsm.a_set_b_hnp_en, | ||
1334 | langwell->hsm.b_srp_done, | ||
1335 | langwell->hsm.b_hnp_enable, | ||
1336 | langwell->hsm.a_wait_vrise_tmout, | ||
1337 | langwell->hsm.a_wait_bcon_tmout, | ||
1338 | langwell->hsm.a_aidl_bdis_tmout, | ||
1339 | langwell->hsm.b_ase0_brst_tmout, | ||
1340 | langwell->hsm.a_bus_drop, | ||
1341 | langwell->hsm.a_bus_req, | ||
1342 | langwell->hsm.a_clr_err, | ||
1343 | langwell->hsm.a_suspend_req, | ||
1344 | langwell->hsm.b_bus_req, | ||
1345 | langwell->hsm.b_bus_suspend_tmout, | ||
1346 | langwell->hsm.b_bus_suspend_vld | ||
1347 | ); | ||
1348 | size -= t; | ||
1349 | next += t; | ||
1350 | |||
1351 | return PAGE_SIZE - size; | ||
1352 | } | ||
1353 | static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL); | ||
1354 | |||
1355 | static ssize_t | ||
1356 | get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
1357 | { | ||
1358 | struct langwell_otg *langwell; | ||
1359 | char *next; | ||
1360 | unsigned size; | ||
1361 | unsigned t; | ||
1362 | |||
1363 | langwell = the_transceiver; | ||
1364 | next = buf; | ||
1365 | size = PAGE_SIZE; | ||
1366 | |||
1367 | t = scnprintf(next, size, "%d", langwell->hsm.a_bus_req); | ||
1368 | size -= t; | ||
1369 | next += t; | ||
1370 | |||
1371 | return PAGE_SIZE - size; | ||
1372 | } | ||
1373 | |||
1374 | static ssize_t | ||
1375 | set_a_bus_req(struct device *dev, struct device_attribute *attr, | ||
1376 | const char *buf, size_t count) | ||
1377 | { | ||
1378 | struct langwell_otg *langwell; | ||
1379 | langwell = the_transceiver; | ||
1380 | if (!langwell->otg.default_a) | ||
1381 | return -1; | ||
1382 | if (count > 2) | ||
1383 | return -1; | ||
1384 | |||
1385 | if (buf[0] == '0') { | ||
1386 | langwell->hsm.a_bus_req = 0; | ||
1387 | otg_dbg("a_bus_req = 0\n"); | ||
1388 | } else if (buf[0] == '1') { | ||
1389 | /* If a_bus_drop is TRUE, a_bus_req can't be set */ | ||
1390 | if (langwell->hsm.a_bus_drop) | ||
1391 | return -1; | ||
1392 | langwell->hsm.a_bus_req = 1; | ||
1393 | otg_dbg("a_bus_req = 1\n"); | ||
1394 | } | ||
1395 | if (spin_trylock(&langwell->wq_lock)) { | ||
1396 | queue_work(langwell->qwork, &langwell->work); | ||
1397 | spin_unlock(&langwell->wq_lock); | ||
1398 | } | ||
1399 | return count; | ||
1400 | } | ||
1401 | static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req); | ||
1402 | |||
1403 | static ssize_t | ||
1404 | get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) | ||
1405 | { | ||
1406 | struct langwell_otg *langwell; | ||
1407 | char *next; | ||
1408 | unsigned size; | ||
1409 | unsigned t; | ||
1410 | |||
1411 | langwell = the_transceiver; | ||
1412 | next = buf; | ||
1413 | size = PAGE_SIZE; | ||
1414 | |||
1415 | t = scnprintf(next, size, "%d", langwell->hsm.a_bus_drop); | ||
1416 | size -= t; | ||
1417 | next += t; | ||
1418 | |||
1419 | return PAGE_SIZE - size; | ||
1420 | } | ||
1421 | |||
1422 | static ssize_t | ||
1423 | set_a_bus_drop(struct device *dev, struct device_attribute *attr, | ||
1424 | const char *buf, size_t count) | ||
1425 | { | ||
1426 | struct langwell_otg *langwell; | ||
1427 | langwell = the_transceiver; | ||
1428 | if (!langwell->otg.default_a) | ||
1429 | return -1; | ||
1430 | if (count > 2) | ||
1431 | return -1; | ||
1432 | |||
1433 | if (buf[0] == '0') { | ||
1434 | langwell->hsm.a_bus_drop = 0; | ||
1435 | otg_dbg("a_bus_drop = 0\n"); | ||
1436 | } else if (buf[0] == '1') { | ||
1437 | langwell->hsm.a_bus_drop = 1; | ||
1438 | langwell->hsm.a_bus_req = 0; | ||
1439 | otg_dbg("a_bus_drop = 1, then a_bus_req = 0\n"); | ||
1440 | } | ||
1441 | if (spin_trylock(&langwell->wq_lock)) { | ||
1442 | queue_work(langwell->qwork, &langwell->work); | ||
1443 | spin_unlock(&langwell->wq_lock); | ||
1444 | } | ||
1445 | return count; | ||
1446 | } | ||
1447 | static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO, | ||
1448 | get_a_bus_drop, set_a_bus_drop); | ||
1449 | |||
1450 | static ssize_t | ||
1451 | get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) | ||
1452 | { | ||
1453 | struct langwell_otg *langwell; | ||
1454 | char *next; | ||
1455 | unsigned size; | ||
1456 | unsigned t; | ||
1457 | |||
1458 | langwell = the_transceiver; | ||
1459 | next = buf; | ||
1460 | size = PAGE_SIZE; | ||
1461 | |||
1462 | t = scnprintf(next, size, "%d", langwell->hsm.b_bus_req); | ||
1463 | size -= t; | ||
1464 | next += t; | ||
1465 | |||
1466 | return PAGE_SIZE - size; | ||
1467 | } | ||
1468 | |||
1469 | static ssize_t | ||
1470 | set_b_bus_req(struct device *dev, struct device_attribute *attr, | ||
1471 | const char *buf, size_t count) | ||
1472 | { | ||
1473 | struct langwell_otg *langwell; | ||
1474 | langwell = the_transceiver; | ||
1475 | |||
1476 | if (langwell->otg.default_a) | ||
1477 | return -1; | ||
1478 | |||
1479 | if (count > 2) | ||
1480 | return -1; | ||
1481 | |||
1482 | if (buf[0] == '0') { | ||
1483 | langwell->hsm.b_bus_req = 0; | ||
1484 | otg_dbg("b_bus_req = 0\n"); | ||
1485 | } else if (buf[0] == '1') { | ||
1486 | langwell->hsm.b_bus_req = 1; | ||
1487 | otg_dbg("b_bus_req = 1\n"); | ||
1488 | } | ||
1489 | if (spin_trylock(&langwell->wq_lock)) { | ||
1490 | queue_work(langwell->qwork, &langwell->work); | ||
1491 | spin_unlock(&langwell->wq_lock); | ||
1492 | } | ||
1493 | return count; | ||
1494 | } | ||
1495 | static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req); | ||
1496 | |||
1497 | static ssize_t | ||
1498 | set_a_clr_err(struct device *dev, struct device_attribute *attr, | ||
1499 | const char *buf, size_t count) | ||
1500 | { | ||
1501 | struct langwell_otg *langwell; | ||
1502 | langwell = the_transceiver; | ||
1503 | |||
1504 | if (!langwell->otg.default_a) | ||
1505 | return -1; | ||
1506 | if (count > 2) | ||
1507 | return -1; | ||
1508 | |||
1509 | if (buf[0] == '1') { | ||
1510 | langwell->hsm.a_clr_err = 1; | ||
1511 | otg_dbg("a_clr_err = 1\n"); | ||
1512 | } | ||
1513 | if (spin_trylock(&langwell->wq_lock)) { | ||
1514 | queue_work(langwell->qwork, &langwell->work); | ||
1515 | spin_unlock(&langwell->wq_lock); | ||
1516 | } | ||
1517 | return count; | ||
1518 | } | ||
1519 | static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err); | ||
1520 | |||
1521 | static struct attribute *inputs_attrs[] = { | ||
1522 | &dev_attr_a_bus_req.attr, | ||
1523 | &dev_attr_a_bus_drop.attr, | ||
1524 | &dev_attr_b_bus_req.attr, | ||
1525 | &dev_attr_a_clr_err.attr, | ||
1526 | NULL, | ||
1527 | }; | ||
1528 | |||
1529 | static struct attribute_group debug_dev_attr_group = { | ||
1530 | .name = "inputs", | ||
1531 | .attrs = inputs_attrs, | ||
1532 | }; | ||
1533 | |||
1534 | int langwell_register_host(struct pci_driver *host_driver) | ||
1535 | { | ||
1536 | int ret = 0; | ||
1537 | |||
1538 | the_transceiver->host_ops = host_driver; | ||
1539 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1540 | otg_dbg("host controller driver is registered\n"); | ||
1541 | |||
1542 | return ret; | ||
1543 | } | ||
1544 | EXPORT_SYMBOL(langwell_register_host); | ||
1545 | |||
1546 | void langwell_unregister_host(struct pci_driver *host_driver) | ||
1547 | { | ||
1548 | if (the_transceiver->host_ops) | ||
1549 | the_transceiver->host_ops->remove(the_transceiver->pdev); | ||
1550 | the_transceiver->host_ops = NULL; | ||
1551 | the_transceiver->hsm.a_bus_drop = 1; | ||
1552 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1553 | otg_dbg("host controller driver is unregistered\n"); | ||
1554 | } | ||
1555 | EXPORT_SYMBOL(langwell_unregister_host); | ||
1556 | |||
1557 | int langwell_register_peripheral(struct pci_driver *client_driver) | ||
1558 | { | ||
1559 | int ret = 0; | ||
1560 | |||
1561 | if (client_driver) | ||
1562 | ret = client_driver->probe(the_transceiver->pdev, | ||
1563 | client_driver->id_table); | ||
1564 | if (!ret) { | ||
1565 | the_transceiver->client_ops = client_driver; | ||
1566 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1567 | otg_dbg("client controller driver is registered\n"); | ||
1568 | } | ||
1569 | |||
1570 | return ret; | ||
1571 | } | ||
1572 | EXPORT_SYMBOL(langwell_register_peripheral); | ||
1573 | |||
1574 | void langwell_unregister_peripheral(struct pci_driver *client_driver) | ||
1575 | { | ||
1576 | if (the_transceiver->client_ops) | ||
1577 | the_transceiver->client_ops->remove(the_transceiver->pdev); | ||
1578 | the_transceiver->client_ops = NULL; | ||
1579 | the_transceiver->hsm.b_bus_req = 0; | ||
1580 | queue_work(the_transceiver->qwork, &the_transceiver->work); | ||
1581 | otg_dbg("client controller driver is unregistered\n"); | ||
1582 | } | ||
1583 | EXPORT_SYMBOL(langwell_unregister_peripheral); | ||
1584 | |||
1585 | static int langwell_otg_probe(struct pci_dev *pdev, | ||
1586 | const struct pci_device_id *id) | ||
1587 | { | ||
1588 | unsigned long resource, len; | ||
1589 | void __iomem *base = NULL; | ||
1590 | int retval; | ||
1591 | u32 val32; | ||
1592 | struct langwell_otg *langwell; | ||
1593 | char qname[] = "langwell_otg_queue"; | ||
1594 | |||
1595 | retval = 0; | ||
1596 | otg_dbg("\notg controller is detected.\n"); | ||
1597 | if (pci_enable_device(pdev) < 0) { | ||
1598 | retval = -ENODEV; | ||
1599 | goto done; | ||
1600 | } | ||
1601 | |||
1602 | langwell = kzalloc(sizeof *langwell, GFP_KERNEL); | ||
1603 | if (langwell == NULL) { | ||
1604 | retval = -ENOMEM; | ||
1605 | goto done; | ||
1606 | } | ||
1607 | the_transceiver = langwell; | ||
1608 | |||
1609 | /* control register: BAR 0 */ | ||
1610 | resource = pci_resource_start(pdev, 0); | ||
1611 | len = pci_resource_len(pdev, 0); | ||
1612 | if (!request_mem_region(resource, len, driver_name)) { | ||
1613 | retval = -EBUSY; | ||
1614 | goto err; | ||
1615 | } | ||
1616 | langwell->region = 1; | ||
1617 | |||
1618 | base = ioremap_nocache(resource, len); | ||
1619 | if (base == NULL) { | ||
1620 | retval = -EFAULT; | ||
1621 | goto err; | ||
1622 | } | ||
1623 | langwell->regs = base; | ||
1624 | |||
1625 | if (!pdev->irq) { | ||
1626 | otg_dbg("No IRQ.\n"); | ||
1627 | retval = -ENODEV; | ||
1628 | goto err; | ||
1629 | } | ||
1630 | |||
1631 | langwell->qwork = create_workqueue(qname); | ||
1632 | if (!langwell->qwork) { | ||
1633 | otg_dbg("cannot create workqueue %s\n", qname); | ||
1634 | retval = -ENOMEM; | ||
1635 | goto err; | ||
1636 | } | ||
1637 | INIT_WORK(&langwell->work, langwell_otg_work); | ||
1638 | |||
1639 | /* OTG common part */ | ||
1640 | langwell->pdev = pdev; | ||
1641 | langwell->otg.dev = &pdev->dev; | ||
1642 | langwell->otg.label = driver_name; | ||
1643 | langwell->otg.set_host = langwell_otg_set_host; | ||
1644 | langwell->otg.set_peripheral = langwell_otg_set_peripheral; | ||
1645 | langwell->otg.set_power = langwell_otg_set_power; | ||
1646 | langwell->otg.start_srp = langwell_otg_start_srp; | ||
1647 | langwell->otg.state = OTG_STATE_UNDEFINED; | ||
1648 | if (otg_set_transceiver(&langwell->otg)) { | ||
1649 | otg_dbg("can't set transceiver\n"); | ||
1650 | retval = -EBUSY; | ||
1651 | goto err; | ||
1652 | } | ||
1653 | |||
1654 | reset_otg(); | ||
1655 | init_hsm(); | ||
1656 | |||
1657 | spin_lock_init(&langwell->lock); | ||
1658 | spin_lock_init(&langwell->wq_lock); | ||
1659 | INIT_LIST_HEAD(&active_timers); | ||
1660 | langwell_otg_init_timers(&langwell->hsm); | ||
1661 | |||
1662 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
1663 | driver_name, langwell) != 0) { | ||
1664 | otg_dbg("request interrupt %d failed\n", pdev->irq); | ||
1665 | retval = -EBUSY; | ||
1666 | goto err; | ||
1667 | } | ||
1668 | |||
1669 | /* enable OTGSC int */ | ||
1670 | val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE | | ||
1671 | OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU; | ||
1672 | writel(val32, langwell->regs + CI_OTGSC); | ||
1673 | |||
1674 | retval = device_create_file(&pdev->dev, &dev_attr_registers); | ||
1675 | if (retval < 0) { | ||
1676 | otg_dbg("Can't register sysfs attribute: %d\n", retval); | ||
1677 | goto err; | ||
1678 | } | ||
1679 | |||
1680 | retval = device_create_file(&pdev->dev, &dev_attr_hsm); | ||
1681 | if (retval < 0) { | ||
1682 | otg_dbg("Can't hsm sysfs attribute: %d\n", retval); | ||
1683 | goto err; | ||
1684 | } | ||
1685 | |||
1686 | retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
1687 | if (retval < 0) { | ||
1688 | otg_dbg("Can't register sysfs attr group: %d\n", retval); | ||
1689 | goto err; | ||
1690 | } | ||
1691 | |||
1692 | if (langwell->otg.state == OTG_STATE_A_IDLE) | ||
1693 | queue_work(langwell->qwork, &langwell->work); | ||
1694 | |||
1695 | return 0; | ||
1696 | |||
1697 | err: | ||
1698 | if (the_transceiver) | ||
1699 | langwell_otg_remove(pdev); | ||
1700 | done: | ||
1701 | return retval; | ||
1702 | } | ||
1703 | |||
1704 | static void langwell_otg_remove(struct pci_dev *pdev) | ||
1705 | { | ||
1706 | struct langwell_otg *langwell; | ||
1707 | |||
1708 | langwell = the_transceiver; | ||
1709 | |||
1710 | if (langwell->qwork) { | ||
1711 | flush_workqueue(langwell->qwork); | ||
1712 | destroy_workqueue(langwell->qwork); | ||
1713 | } | ||
1714 | langwell_otg_free_timers(); | ||
1715 | |||
1716 | /* disable OTGSC interrupt as OTGSC doesn't change in reset */ | ||
1717 | writel(0, langwell->regs + CI_OTGSC); | ||
1718 | |||
1719 | if (pdev->irq) | ||
1720 | free_irq(pdev->irq, langwell); | ||
1721 | if (langwell->regs) | ||
1722 | iounmap(langwell->regs); | ||
1723 | if (langwell->region) | ||
1724 | release_mem_region(pci_resource_start(pdev, 0), | ||
1725 | pci_resource_len(pdev, 0)); | ||
1726 | |||
1727 | otg_set_transceiver(NULL); | ||
1728 | pci_disable_device(pdev); | ||
1729 | sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group); | ||
1730 | device_remove_file(&pdev->dev, &dev_attr_hsm); | ||
1731 | device_remove_file(&pdev->dev, &dev_attr_registers); | ||
1732 | kfree(langwell); | ||
1733 | langwell = NULL; | ||
1734 | } | ||
1735 | |||
1736 | static void transceiver_suspend(struct pci_dev *pdev) | ||
1737 | { | ||
1738 | pci_save_state(pdev); | ||
1739 | pci_set_power_state(pdev, PCI_D3hot); | ||
1740 | langwell_otg_phy_low_power(1); | ||
1741 | } | ||
1742 | |||
1743 | static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message) | ||
1744 | { | ||
1745 | int ret = 0; | ||
1746 | struct langwell_otg *langwell; | ||
1747 | |||
1748 | langwell = the_transceiver; | ||
1749 | |||
1750 | /* Disbale OTG interrupts */ | ||
1751 | langwell_otg_intr(0); | ||
1752 | |||
1753 | if (pdev->irq) | ||
1754 | free_irq(pdev->irq, langwell); | ||
1755 | |||
1756 | /* Prevent more otg_work */ | ||
1757 | flush_workqueue(langwell->qwork); | ||
1758 | spin_lock(&langwell->wq_lock); | ||
1759 | |||
1760 | /* start actions */ | ||
1761 | switch (langwell->otg.state) { | ||
1762 | case OTG_STATE_A_IDLE: | ||
1763 | case OTG_STATE_B_IDLE: | ||
1764 | case OTG_STATE_A_WAIT_VFALL: | ||
1765 | case OTG_STATE_A_VBUS_ERR: | ||
1766 | transceiver_suspend(pdev); | ||
1767 | break; | ||
1768 | case OTG_STATE_A_WAIT_VRISE: | ||
1769 | langwell_otg_del_timer(a_wait_vrise_tmr); | ||
1770 | langwell->hsm.a_srp_det = 0; | ||
1771 | langwell_otg_drv_vbus(0); | ||
1772 | langwell->otg.state = OTG_STATE_A_IDLE; | ||
1773 | transceiver_suspend(pdev); | ||
1774 | break; | ||
1775 | case OTG_STATE_A_WAIT_BCON: | ||
1776 | langwell_otg_del_timer(a_wait_bcon_tmr); | ||
1777 | if (langwell->host_ops) | ||
1778 | ret = langwell->host_ops->suspend(pdev, message); | ||
1779 | langwell_otg_drv_vbus(0); | ||
1780 | break; | ||
1781 | case OTG_STATE_A_HOST: | ||
1782 | if (langwell->host_ops) | ||
1783 | ret = langwell->host_ops->suspend(pdev, message); | ||
1784 | langwell_otg_drv_vbus(0); | ||
1785 | langwell_otg_phy_low_power(1); | ||
1786 | break; | ||
1787 | case OTG_STATE_A_SUSPEND: | ||
1788 | langwell_otg_del_timer(a_aidl_bdis_tmr); | ||
1789 | langwell_otg_HABA(0); | ||
1790 | if (langwell->host_ops) | ||
1791 | langwell->host_ops->remove(pdev); | ||
1792 | else | ||
1793 | otg_dbg("host driver has been removed.\n"); | ||
1794 | langwell_otg_drv_vbus(0); | ||
1795 | transceiver_suspend(pdev); | ||
1796 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1797 | break; | ||
1798 | case OTG_STATE_A_PERIPHERAL: | ||
1799 | if (langwell->client_ops) | ||
1800 | ret = langwell->client_ops->suspend(pdev, message); | ||
1801 | else | ||
1802 | otg_dbg("client driver has been removed.\n"); | ||
1803 | langwell_otg_drv_vbus(0); | ||
1804 | transceiver_suspend(pdev); | ||
1805 | langwell->otg.state = OTG_STATE_A_WAIT_VFALL; | ||
1806 | break; | ||
1807 | case OTG_STATE_B_HOST: | ||
1808 | if (langwell->host_ops) | ||
1809 | langwell->host_ops->remove(pdev); | ||
1810 | else | ||
1811 | otg_dbg("host driver has been removed.\n"); | ||
1812 | langwell->hsm.b_bus_req = 0; | ||
1813 | transceiver_suspend(pdev); | ||
1814 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1815 | break; | ||
1816 | case OTG_STATE_B_PERIPHERAL: | ||
1817 | if (langwell->client_ops) | ||
1818 | ret = langwell->client_ops->suspend(pdev, message); | ||
1819 | else | ||
1820 | otg_dbg("client driver has been removed.\n"); | ||
1821 | break; | ||
1822 | case OTG_STATE_B_WAIT_ACON: | ||
1823 | langwell_otg_del_timer(b_ase0_brst_tmr); | ||
1824 | langwell_otg_HAAR(0); | ||
1825 | if (langwell->host_ops) | ||
1826 | langwell->host_ops->remove(pdev); | ||
1827 | else | ||
1828 | otg_dbg("host driver has been removed.\n"); | ||
1829 | langwell->hsm.b_bus_req = 0; | ||
1830 | langwell->otg.state = OTG_STATE_B_IDLE; | ||
1831 | transceiver_suspend(pdev); | ||
1832 | break; | ||
1833 | default: | ||
1834 | otg_dbg("error state before suspend\n "); | ||
1835 | break; | ||
1836 | } | ||
1837 | spin_unlock(&langwell->wq_lock); | ||
1838 | |||
1839 | return ret; | ||
1840 | } | ||
1841 | |||
1842 | static void transceiver_resume(struct pci_dev *pdev) | ||
1843 | { | ||
1844 | pci_restore_state(pdev); | ||
1845 | pci_set_power_state(pdev, PCI_D0); | ||
1846 | langwell_otg_phy_low_power(0); | ||
1847 | } | ||
1848 | |||
1849 | static int langwell_otg_resume(struct pci_dev *pdev) | ||
1850 | { | ||
1851 | int ret = 0; | ||
1852 | struct langwell_otg *langwell; | ||
1853 | |||
1854 | langwell = the_transceiver; | ||
1855 | |||
1856 | spin_lock(&langwell->wq_lock); | ||
1857 | |||
1858 | switch (langwell->otg.state) { | ||
1859 | case OTG_STATE_A_IDLE: | ||
1860 | case OTG_STATE_B_IDLE: | ||
1861 | case OTG_STATE_A_WAIT_VFALL: | ||
1862 | case OTG_STATE_A_VBUS_ERR: | ||
1863 | transceiver_resume(pdev); | ||
1864 | break; | ||
1865 | case OTG_STATE_A_WAIT_BCON: | ||
1866 | langwell_otg_add_timer(a_wait_bcon_tmr); | ||
1867 | langwell_otg_drv_vbus(1); | ||
1868 | if (langwell->host_ops) | ||
1869 | ret = langwell->host_ops->resume(pdev); | ||
1870 | break; | ||
1871 | case OTG_STATE_A_HOST: | ||
1872 | langwell_otg_drv_vbus(1); | ||
1873 | langwell_otg_phy_low_power(0); | ||
1874 | if (langwell->host_ops) | ||
1875 | ret = langwell->host_ops->resume(pdev); | ||
1876 | break; | ||
1877 | case OTG_STATE_B_PERIPHERAL: | ||
1878 | if (langwell->client_ops) | ||
1879 | ret = langwell->client_ops->resume(pdev); | ||
1880 | else | ||
1881 | otg_dbg("client driver not loaded.\n"); | ||
1882 | break; | ||
1883 | default: | ||
1884 | otg_dbg("error state before suspend\n "); | ||
1885 | break; | ||
1886 | } | ||
1887 | |||
1888 | if (request_irq(pdev->irq, otg_irq, IRQF_SHARED, | ||
1889 | driver_name, the_transceiver) != 0) { | ||
1890 | otg_dbg("request interrupt %d failed\n", pdev->irq); | ||
1891 | ret = -EBUSY; | ||
1892 | } | ||
1893 | |||
1894 | /* enable OTG interrupts */ | ||
1895 | langwell_otg_intr(1); | ||
1896 | |||
1897 | spin_unlock(&langwell->wq_lock); | ||
1898 | |||
1899 | queue_work(langwell->qwork, &langwell->work); | ||
1900 | |||
1901 | |||
1902 | return ret; | ||
1903 | } | ||
1904 | |||
1905 | static int __init langwell_otg_init(void) | ||
1906 | { | ||
1907 | return pci_register_driver(&otg_pci_driver); | ||
1908 | } | ||
1909 | module_init(langwell_otg_init); | ||
1910 | |||
1911 | static void __exit langwell_otg_cleanup(void) | ||
1912 | { | ||
1913 | pci_unregister_driver(&otg_pci_driver); | ||
1914 | } | ||
1915 | module_exit(langwell_otg_cleanup); | ||
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 9ed5ea568679..af456b48985f 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c | |||
@@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register); | |||
53 | void usb_nop_xceiv_unregister(void) | 53 | void usb_nop_xceiv_unregister(void) |
54 | { | 54 | { |
55 | platform_device_unregister(pd); | 55 | platform_device_unregister(pd); |
56 | pd = NULL; | ||
56 | } | 57 | } |
57 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); | 58 | EXPORT_SYMBOL(usb_nop_xceiv_unregister); |
58 | 59 | ||
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 247b61bfb7f4..0e4f2e41ace5 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options) | |||
169 | kfree(tty); | 169 | kfree(tty); |
170 | } | 170 | } |
171 | } | 171 | } |
172 | /* So we know not to kill the hardware on a hangup on this | 172 | /* Now that any required fake tty operations are completed restore |
173 | port. We have also bumped the use count by one so it won't go | 173 | * the tty port count */ |
174 | idle */ | 174 | --port->port.count; |
175 | /* The console is special in terms of closing the device so | ||
176 | * indicate this port is now acting as a system console. */ | ||
175 | port->console = 1; | 177 | port->console = 1; |
176 | retval = 0; | 178 | retval = 0; |
177 | 179 | ||
@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co, | |||
204 | 206 | ||
205 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); | 207 | dbg("%s - port %d, %d byte(s)", __func__, port->number, count); |
206 | 208 | ||
207 | if (!port->port.count) { | 209 | if (!port->console) { |
208 | dbg("%s - port not opened", __func__); | 210 | dbg("%s - port not opened", __func__); |
209 | return; | 211 | return; |
210 | } | 212 | } |
@@ -300,8 +302,7 @@ void usb_serial_console_exit(void) | |||
300 | { | 302 | { |
301 | if (usbcons_info.port) { | 303 | if (usbcons_info.port) { |
302 | unregister_console(&usbcons); | 304 | unregister_console(&usbcons); |
303 | if (usbcons_info.port->port.count) | 305 | usbcons_info.port->console = 0; |
304 | usbcons_info.port->port.count--; | ||
305 | usbcons_info.port = NULL; | 306 | usbcons_info.port = NULL; |
306 | } | 307 | } |
307 | } | 308 | } |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2b9eeda62bfe..e9a40b820fd4 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = { | |||
67 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 67 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
68 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ | 68 | { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ |
69 | { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ | 69 | { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */ |
70 | { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */ | ||
71 | { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */ | ||
70 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ | 72 | { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */ |
71 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ | 73 | { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */ |
72 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ | 74 | { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */ |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 9734085fd2fe..59adfe123110 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1228 | /* precursor to disconnect so just go away */ | 1228 | /* precursor to disconnect so just go away */ |
1229 | return; | 1229 | return; |
1230 | case -EPIPE: | 1230 | case -EPIPE: |
1231 | usb_clear_halt(port->serial->dev, 0x81); | 1231 | /* Can't call usb_clear_halt while in_interrupt */ |
1232 | break; | 1232 | /* FALLS THROUGH */ |
1233 | default: | 1233 | default: |
1234 | /* something ugly is going on... */ | 1234 | /* something ugly is going on... */ |
1235 | dev_err(&urb->dev->dev, | 1235 | dev_err(&urb->dev->dev, |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 3dc3768ca71c..60c64cc5be2a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/smp_lock.h> | ||
36 | #include <linux/tty.h> | 37 | #include <linux/tty.h> |
37 | #include <linux/tty_driver.h> | 38 | #include <linux/tty_driver.h> |
38 | #include <linux/tty_flip.h> | 39 | #include <linux/tty_flip.h> |
@@ -107,6 +108,7 @@ struct ftdi_sio_quirk { | |||
107 | 108 | ||
108 | static int ftdi_jtag_probe(struct usb_serial *serial); | 109 | static int ftdi_jtag_probe(struct usb_serial *serial); |
109 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); | 110 | static int ftdi_mtxorb_hack_setup(struct usb_serial *serial); |
111 | static int ftdi_NDI_device_setup(struct usb_serial *serial); | ||
110 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); | 112 | static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); |
111 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); | 113 | static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); |
112 | 114 | ||
@@ -118,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { | |||
118 | .probe = ftdi_mtxorb_hack_setup, | 120 | .probe = ftdi_mtxorb_hack_setup, |
119 | }; | 121 | }; |
120 | 122 | ||
123 | static struct ftdi_sio_quirk ftdi_NDI_device_quirk = { | ||
124 | .probe = ftdi_NDI_device_setup, | ||
125 | }; | ||
126 | |||
121 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | 127 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { |
122 | .port_probe = ftdi_USB_UIRT_setup, | 128 | .port_probe = ftdi_USB_UIRT_setup, |
123 | }; | 129 | }; |
@@ -191,6 +197,7 @@ static struct usb_device_id id_table_combined [] = { | |||
191 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, | 197 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
192 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, | 198 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
193 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, | 199 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
200 | { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, | ||
194 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, | 201 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, |
195 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, | 202 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, |
196 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, | 203 | { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, |
@@ -579,6 +586,9 @@ static struct usb_device_id id_table_combined [] = { | |||
579 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 586 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
580 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 587 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
581 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, | 588 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, |
589 | { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) }, | ||
590 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) }, | ||
591 | { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) }, | ||
582 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 592 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
583 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, | 593 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, |
584 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, | 594 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, |
@@ -644,6 +654,16 @@ static struct usb_device_id id_table_combined [] = { | |||
644 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, | 654 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) }, |
645 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, | 655 | { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) }, |
646 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | 656 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, |
657 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID), | ||
658 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
659 | { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID), | ||
660 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
661 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID), | ||
662 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
663 | { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID), | ||
664 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
665 | { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), | ||
666 | .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, | ||
647 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 667 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
648 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | 668 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, |
649 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, | 669 | { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, |
@@ -660,6 +680,8 @@ static struct usb_device_id id_table_combined [] = { | |||
660 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 680 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
661 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), | 681 | { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), |
662 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 682 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
683 | { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), | ||
684 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
663 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | 685 | { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, |
664 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, | 686 | { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, |
665 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, | 687 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, |
@@ -667,7 +689,6 @@ static struct usb_device_id id_table_combined [] = { | |||
667 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, | 689 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, |
668 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, | 690 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, |
669 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, | 691 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, |
670 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, | ||
671 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, | 692 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, |
672 | { USB_DEVICE(DE_VID, STB_PID) }, | 693 | { USB_DEVICE(DE_VID, STB_PID) }, |
673 | { USB_DEVICE(DE_VID, WHT_PID) }, | 694 | { USB_DEVICE(DE_VID, WHT_PID) }, |
@@ -1023,6 +1044,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, | |||
1023 | case FT2232C: /* FT2232C chip */ | 1044 | case FT2232C: /* FT2232C chip */ |
1024 | case FT232RL: | 1045 | case FT232RL: |
1025 | if (baud <= 3000000) { | 1046 | if (baud <= 3000000) { |
1047 | __u16 product_id = le16_to_cpu( | ||
1048 | port->serial->dev->descriptor.idProduct); | ||
1049 | if (((FTDI_NDI_HUC_PID == product_id) || | ||
1050 | (FTDI_NDI_SPECTRA_SCU_PID == product_id) || | ||
1051 | (FTDI_NDI_FUTURE_2_PID == product_id) || | ||
1052 | (FTDI_NDI_FUTURE_3_PID == product_id) || | ||
1053 | (FTDI_NDI_AURORA_SCU_PID == product_id)) && | ||
1054 | (baud == 19200)) { | ||
1055 | baud = 1200000; | ||
1056 | } | ||
1026 | div_value = ftdi_232bm_baud_to_divisor(baud); | 1057 | div_value = ftdi_232bm_baud_to_divisor(baud); |
1027 | } else { | 1058 | } else { |
1028 | dbg("%s - Baud rate too high!", __func__); | 1059 | dbg("%s - Baud rate too high!", __func__); |
@@ -1554,6 +1585,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) | |||
1554 | } /* ftdi_HE_TIRA1_setup */ | 1585 | } /* ftdi_HE_TIRA1_setup */ |
1555 | 1586 | ||
1556 | /* | 1587 | /* |
1588 | * Module parameter to control latency timer for NDI FTDI-based USB devices. | ||
1589 | * If this value is not set in modprobe.conf.local its value will be set to 1ms. | ||
1590 | */ | ||
1591 | static int ndi_latency_timer = 1; | ||
1592 | |||
1593 | /* Setup for the NDI FTDI-based USB devices, which requires hardwired | ||
1594 | * baudrate (19200 gets mapped to 1200000). | ||
1595 | * | ||
1596 | * Called from usbserial:serial_probe. | ||
1597 | */ | ||
1598 | static int ftdi_NDI_device_setup(struct usb_serial *serial) | ||
1599 | { | ||
1600 | struct usb_device *udev = serial->dev; | ||
1601 | int latency = ndi_latency_timer; | ||
1602 | int rv = 0; | ||
1603 | char buf[1]; | ||
1604 | |||
1605 | if (latency == 0) | ||
1606 | latency = 1; | ||
1607 | if (latency > 99) | ||
1608 | latency = 99; | ||
1609 | |||
1610 | dbg("%s setting NDI device latency to %d", __func__, latency); | ||
1611 | dev_info(&udev->dev, "NDI device with a latency value of %d", latency); | ||
1612 | |||
1613 | rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
1614 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST, | ||
1615 | FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE, | ||
1616 | latency, 0, buf, 0, WDR_TIMEOUT); | ||
1617 | return 0; | ||
1618 | } | ||
1619 | |||
1620 | /* | ||
1557 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko | 1621 | * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko |
1558 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from | 1622 | * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from |
1559 | * userspace using openocd. | 1623 | * userspace using openocd. |
@@ -2121,7 +2185,7 @@ static void ftdi_process_read(struct work_struct *work) | |||
2121 | /* Note that the error flag is duplicated for | 2185 | /* Note that the error flag is duplicated for |
2122 | every character received since we don't know | 2186 | every character received since we don't know |
2123 | which character it applied to */ | 2187 | which character it applied to */ |
2124 | if (!usb_serial_handle_sysrq_char(port, | 2188 | if (!usb_serial_handle_sysrq_char(tty, port, |
2125 | data[packet_offset + i])) | 2189 | data[packet_offset + i])) |
2126 | tty_insert_flip_char(tty, | 2190 | tty_insert_flip_char(tty, |
2127 | data[packet_offset + i], | 2191 | data[packet_offset + i], |
@@ -2622,3 +2686,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default=" | |||
2622 | module_param(product, ushort, 0); | 2686 | module_param(product, ushort, 0); |
2623 | MODULE_PARM_DESC(product, "User specified product ID"); | 2687 | MODULE_PARM_DESC(product, "User specified product ID"); |
2624 | 2688 | ||
2689 | module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR); | ||
2690 | MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override"); | ||
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index f1d440a728a3..c9fbd7415092 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -506,6 +506,7 @@ | |||
506 | * | 506 | * |
507 | * Armin Laeuger originally sent the PID for the UM 100 module. | 507 | * Armin Laeuger originally sent the PID for the UM 100 module. |
508 | */ | 508 | */ |
509 | #define FTDI_R2000KU_TRUE_RNG 0xFB80 /* R2000KU TRUE RNG */ | ||
509 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ | 510 | #define FTDI_ELV_UR100_PID 0xFB58 /* USB-RS232-Umsetzer (UR 100) */ |
510 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ | 511 | #define FTDI_ELV_UM100_PID 0xFB5A /* USB-Modul UM 100 */ |
511 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ | 512 | #define FTDI_ELV_UO100_PID 0xFB5B /* USB-Modul UO 100 */ |
@@ -614,6 +615,9 @@ | |||
614 | #define FTDI_CCSICDU20_0_PID 0xF9D0 | 615 | #define FTDI_CCSICDU20_0_PID 0xF9D0 |
615 | #define FTDI_CCSICDU40_1_PID 0xF9D1 | 616 | #define FTDI_CCSICDU40_1_PID 0xF9D1 |
616 | #define FTDI_CCSMACHX_2_PID 0xF9D2 | 617 | #define FTDI_CCSMACHX_2_PID 0xF9D2 |
618 | #define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3 | ||
619 | #define FTDI_CCSICDU64_4_PID 0xF9D4 | ||
620 | #define FTDI_CCSPRIME8_5_PID 0xF9D5 | ||
617 | 621 | ||
618 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ | 622 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ |
619 | #define INSIDE_ACCESSO 0xFAD0 | 623 | #define INSIDE_ACCESSO 0xFAD0 |
@@ -736,6 +740,15 @@ | |||
736 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 740 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ |
737 | 741 | ||
738 | /* | 742 | /* |
743 | * NDI (www.ndigital.com) product ids | ||
744 | */ | ||
745 | #define FTDI_NDI_HUC_PID 0xDA70 /* NDI Host USB Converter */ | ||
746 | #define FTDI_NDI_SPECTRA_SCU_PID 0xDA71 /* NDI Spectra SCU */ | ||
747 | #define FTDI_NDI_FUTURE_2_PID 0xDA72 /* NDI future device #2 */ | ||
748 | #define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */ | ||
749 | #define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */ | ||
750 | |||
751 | /* | ||
739 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) | 752 | * Posiflex inc retail equipment (http://www.posiflex.com.tw) |
740 | */ | 753 | */ |
741 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ | 754 | #define POSIFLEX_VID 0x0d3a /* Vendor ID */ |
@@ -848,9 +861,6 @@ | |||
848 | #define TML_VID 0x1B91 /* Vendor ID */ | 861 | #define TML_VID 0x1B91 /* Vendor ID */ |
849 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | 862 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ |
850 | 863 | ||
851 | /* NDI Polaris System */ | ||
852 | #define FTDI_NDI_HUC_PID 0xDA70 | ||
853 | |||
854 | /* Propox devices */ | 864 | /* Propox devices */ |
855 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 865 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
856 | 866 | ||
@@ -934,6 +944,8 @@ | |||
934 | #define MARVELL_VID 0x9e88 | 944 | #define MARVELL_VID 0x9e88 |
935 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f | 945 | #define MARVELL_SHEEVAPLUG_PID 0x9e8f |
936 | 946 | ||
947 | #define FTDI_TURTELIZER_PID 0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ | ||
948 | |||
937 | /* | 949 | /* |
938 | * BmRequestType: 1100 0000b | 950 | * BmRequestType: 1100 0000b |
939 | * bRequest: FTDI_E2_READ | 951 | * bRequest: FTDI_E2_READ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 932d6241b787..ce57f6a32bdf 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -424,10 +424,17 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port) | |||
424 | if (!tty) | 424 | if (!tty) |
425 | goto done; | 425 | goto done; |
426 | 426 | ||
427 | /* Push data to tty */ | 427 | /* The per character mucking around with sysrq path it too slow for |
428 | for (i = 0; i < urb->actual_length; i++, ch++) { | 428 | stuff like 3G modems, so shortcircuit it in the 99.9999999% of cases |
429 | if (!usb_serial_handle_sysrq_char(port, *ch)) | 429 | where the USB serial is not a console anyway */ |
430 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 430 | if (!port->console || !port->sysrq) |
431 | tty_insert_flip_string(tty, ch, urb->actual_length); | ||
432 | else { | ||
433 | /* Push data to tty */ | ||
434 | for (i = 0; i < urb->actual_length; i++, ch++) { | ||
435 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | ||
436 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | ||
437 | } | ||
431 | } | 438 | } |
432 | tty_flip_buffer_push(tty); | 439 | tty_flip_buffer_push(tty); |
433 | tty_kref_put(tty); | 440 | tty_kref_put(tty); |
@@ -527,11 +534,12 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
527 | } | 534 | } |
528 | } | 535 | } |
529 | 536 | ||
530 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) | 537 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, |
538 | struct usb_serial_port *port, unsigned int ch) | ||
531 | { | 539 | { |
532 | if (port->sysrq && port->console) { | 540 | if (port->sysrq && port->console) { |
533 | if (ch && time_before(jiffies, port->sysrq)) { | 541 | if (ch && time_before(jiffies, port->sysrq)) { |
534 | handle_sysrq(ch, tty_port_tty_get(&port->port)); | 542 | handle_sysrq(ch, tty); |
535 | port->sysrq = 0; | 543 | port->sysrq = 0; |
536 | return 1; | 544 | return 1; |
537 | } | 545 | } |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index bfc5ce000ef9..ccd4dd340d2c 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -521,7 +521,7 @@ static int mos7720_chars_in_buffer(struct tty_struct *tty) | |||
521 | mos7720_port = usb_get_serial_port_data(port); | 521 | mos7720_port = usb_get_serial_port_data(port); |
522 | if (mos7720_port == NULL) { | 522 | if (mos7720_port == NULL) { |
523 | dbg("%s:leaving ...........", __func__); | 523 | dbg("%s:leaving ...........", __func__); |
524 | return -ENODEV; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | for (i = 0; i < NUM_URBS; ++i) { | 527 | for (i = 0; i < NUM_URBS; ++i) { |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index c40f95c1951c..c31940a307f8 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/smp_lock.h> | ||
29 | #include <linux/tty.h> | 30 | #include <linux/tty.h> |
30 | #include <linux/tty_driver.h> | 31 | #include <linux/tty_driver.h> |
31 | #include <linux/tty_flip.h> | 32 | #include <linux/tty_flip.h> |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 575816e6ba37..98262dd552bb 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -206,6 +206,7 @@ static int option_resume(struct usb_serial *serial); | |||
206 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 206 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
207 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | 207 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 |
208 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 | 208 | #define NOVATELWIRELESS_PRODUCT_MC760 0x6000 |
209 | #define NOVATELWIRELESS_PRODUCT_OVMC760 0x6002 | ||
209 | 210 | ||
210 | /* FUTURE NOVATEL PRODUCTS */ | 211 | /* FUTURE NOVATEL PRODUCTS */ |
211 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 | 212 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 |
@@ -307,11 +308,20 @@ static int option_resume(struct usb_serial *serial); | |||
307 | #define DLINK_VENDOR_ID 0x1186 | 308 | #define DLINK_VENDOR_ID 0x1186 |
308 | #define DLINK_PRODUCT_DWM_652 0x3e04 | 309 | #define DLINK_PRODUCT_DWM_652 0x3e04 |
309 | 310 | ||
311 | #define QISDA_VENDOR_ID 0x1da5 | ||
312 | #define QISDA_PRODUCT_H21_4512 0x4512 | ||
313 | #define QISDA_PRODUCT_H21_4523 0x4523 | ||
314 | #define QISDA_PRODUCT_H20_4515 0x4515 | ||
315 | #define QISDA_PRODUCT_H20_4519 0x4519 | ||
316 | |||
310 | 317 | ||
311 | /* TOSHIBA PRODUCTS */ | 318 | /* TOSHIBA PRODUCTS */ |
312 | #define TOSHIBA_VENDOR_ID 0x0930 | 319 | #define TOSHIBA_VENDOR_ID 0x0930 |
313 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 | 320 | #define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 |
314 | 321 | ||
322 | #define ALINK_VENDOR_ID 0x1e0e | ||
323 | #define ALINK_PRODUCT_3GU 0x9200 | ||
324 | |||
315 | static struct usb_device_id option_ids[] = { | 325 | static struct usb_device_id option_ids[] = { |
316 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 326 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
317 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 327 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -430,6 +440,7 @@ static struct usb_device_id option_ids[] = { | |||
430 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 440 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ |
431 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ | 441 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ |
432 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ | 442 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */ |
443 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */ | ||
433 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ | 444 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ |
434 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ | 445 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ |
435 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ | 446 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ |
@@ -529,8 +540,13 @@ static struct usb_device_id option_ids[] = { | |||
529 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, | 540 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, |
530 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 541 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
531 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 542 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
532 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ | 543 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
544 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, | ||
545 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, | ||
546 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, | ||
533 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | 547 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ |
548 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | ||
549 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | ||
534 | { } /* Terminating entry */ | 550 | { } /* Terminating entry */ |
535 | }; | 551 | }; |
536 | MODULE_DEVICE_TABLE(usb, option_ids); | 552 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -732,7 +748,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
732 | memcpy(this_urb->transfer_buffer, buf, todo); | 748 | memcpy(this_urb->transfer_buffer, buf, todo); |
733 | this_urb->transfer_buffer_length = todo; | 749 | this_urb->transfer_buffer_length = todo; |
734 | 750 | ||
735 | this_urb->dev = port->serial->dev; | ||
736 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 751 | err = usb_submit_urb(this_urb, GFP_ATOMIC); |
737 | if (err) { | 752 | if (err) { |
738 | dbg("usb_submit_urb %p (write bulk) failed " | 753 | dbg("usb_submit_urb %p (write bulk) failed " |
@@ -860,7 +875,6 @@ static void option_instat_callback(struct urb *urb) | |||
860 | 875 | ||
861 | /* Resubmit urb so we continue receiving IRQ data */ | 876 | /* Resubmit urb so we continue receiving IRQ data */ |
862 | if (status != -ESHUTDOWN && status != -ENOENT) { | 877 | if (status != -ESHUTDOWN && status != -ENOENT) { |
863 | urb->dev = serial->dev; | ||
864 | err = usb_submit_urb(urb, GFP_ATOMIC); | 878 | err = usb_submit_urb(urb, GFP_ATOMIC); |
865 | if (err) | 879 | if (err) |
866 | dbg("%s: resubmit intr urb failed. (%d)", | 880 | dbg("%s: resubmit intr urb failed. (%d)", |
@@ -921,23 +935,11 @@ static int option_open(struct tty_struct *tty, | |||
921 | 935 | ||
922 | dbg("%s", __func__); | 936 | dbg("%s", __func__); |
923 | 937 | ||
924 | /* Reset low level data toggle and start reading from endpoints */ | 938 | /* Start reading from the IN endpoint */ |
925 | for (i = 0; i < N_IN_URB; i++) { | 939 | for (i = 0; i < N_IN_URB; i++) { |
926 | urb = portdata->in_urbs[i]; | 940 | urb = portdata->in_urbs[i]; |
927 | if (!urb) | 941 | if (!urb) |
928 | continue; | 942 | continue; |
929 | if (urb->dev != serial->dev) { | ||
930 | dbg("%s: dev %p != %p", __func__, | ||
931 | urb->dev, serial->dev); | ||
932 | continue; | ||
933 | } | ||
934 | |||
935 | /* | ||
936 | * make sure endpoint data toggle is synchronized with the | ||
937 | * device | ||
938 | */ | ||
939 | usb_clear_halt(urb->dev, urb->pipe); | ||
940 | |||
941 | err = usb_submit_urb(urb, GFP_KERNEL); | 943 | err = usb_submit_urb(urb, GFP_KERNEL); |
942 | if (err) { | 944 | if (err) { |
943 | dbg("%s: submit urb %d failed (%d) %d", | 945 | dbg("%s: submit urb %d failed (%d) %d", |
@@ -946,16 +948,6 @@ static int option_open(struct tty_struct *tty, | |||
946 | } | 948 | } |
947 | } | 949 | } |
948 | 950 | ||
949 | /* Reset low level data toggle on out endpoints */ | ||
950 | for (i = 0; i < N_OUT_URB; i++) { | ||
951 | urb = portdata->out_urbs[i]; | ||
952 | if (!urb) | ||
953 | continue; | ||
954 | urb->dev = serial->dev; | ||
955 | /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
956 | usb_pipeout(urb->pipe), 0); */ | ||
957 | } | ||
958 | |||
959 | option_send_setup(port); | 951 | option_send_setup(port); |
960 | 952 | ||
961 | return 0; | 953 | return 0; |
@@ -1218,7 +1210,6 @@ static int option_resume(struct usb_serial *serial) | |||
1218 | dbg("%s: No interrupt URB for port %d\n", __func__, i); | 1210 | dbg("%s: No interrupt URB for port %d\n", __func__, i); |
1219 | continue; | 1211 | continue; |
1220 | } | 1212 | } |
1221 | port->interrupt_in_urb->dev = serial->dev; | ||
1222 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | 1213 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); |
1223 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); | 1214 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); |
1224 | if (err < 0) { | 1215 | if (err < 0) { |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index ec6c132a25b5..7d15bfa7c2db 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = { | |||
94 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, | 94 | { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, |
95 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, | 95 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 96 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
97 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | ||
97 | { } /* Terminating entry */ | 98 | { } /* Terminating entry */ |
98 | }; | 99 | }; |
99 | 100 | ||
@@ -971,18 +972,46 @@ exit: | |||
971 | __func__, retval); | 972 | __func__, retval); |
972 | } | 973 | } |
973 | 974 | ||
975 | static void pl2303_push_data(struct tty_struct *tty, | ||
976 | struct usb_serial_port *port, struct urb *urb, | ||
977 | u8 line_status) | ||
978 | { | ||
979 | unsigned char *data = urb->transfer_buffer; | ||
980 | /* get tty_flag from status */ | ||
981 | char tty_flag = TTY_NORMAL; | ||
982 | /* break takes precedence over parity, */ | ||
983 | /* which takes precedence over framing errors */ | ||
984 | if (line_status & UART_BREAK_ERROR) | ||
985 | tty_flag = TTY_BREAK; | ||
986 | else if (line_status & UART_PARITY_ERROR) | ||
987 | tty_flag = TTY_PARITY; | ||
988 | else if (line_status & UART_FRAME_ERROR) | ||
989 | tty_flag = TTY_FRAME; | ||
990 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
991 | |||
992 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
993 | /* overrun is special, not associated with a char */ | ||
994 | if (line_status & UART_OVERRUN_ERROR) | ||
995 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
996 | if (port->console && port->sysrq) { | ||
997 | int i; | ||
998 | for (i = 0; i < urb->actual_length; ++i) | ||
999 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | ||
1000 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1001 | } else | ||
1002 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1003 | tty_flip_buffer_push(tty); | ||
1004 | } | ||
1005 | |||
974 | static void pl2303_read_bulk_callback(struct urb *urb) | 1006 | static void pl2303_read_bulk_callback(struct urb *urb) |
975 | { | 1007 | { |
976 | struct usb_serial_port *port = urb->context; | 1008 | struct usb_serial_port *port = urb->context; |
977 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 1009 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
978 | struct tty_struct *tty; | 1010 | struct tty_struct *tty; |
979 | unsigned char *data = urb->transfer_buffer; | ||
980 | unsigned long flags; | 1011 | unsigned long flags; |
981 | int i; | ||
982 | int result; | 1012 | int result; |
983 | int status = urb->status; | 1013 | int status = urb->status; |
984 | u8 line_status; | 1014 | u8 line_status; |
985 | char tty_flag; | ||
986 | 1015 | ||
987 | dbg("%s - port %d", __func__, port->number); | 1016 | dbg("%s - port %d", __func__, port->number); |
988 | 1017 | ||
@@ -1010,10 +1039,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1010 | } | 1039 | } |
1011 | 1040 | ||
1012 | usb_serial_debug_data(debug, &port->dev, __func__, | 1041 | usb_serial_debug_data(debug, &port->dev, __func__, |
1013 | urb->actual_length, data); | 1042 | urb->actual_length, urb->transfer_buffer); |
1014 | |||
1015 | /* get tty_flag from status */ | ||
1016 | tty_flag = TTY_NORMAL; | ||
1017 | 1043 | ||
1018 | spin_lock_irqsave(&priv->lock, flags); | 1044 | spin_lock_irqsave(&priv->lock, flags); |
1019 | line_status = priv->line_status; | 1045 | line_status = priv->line_status; |
@@ -1021,26 +1047,9 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1021 | spin_unlock_irqrestore(&priv->lock, flags); | 1047 | spin_unlock_irqrestore(&priv->lock, flags); |
1022 | wake_up_interruptible(&priv->delta_msr_wait); | 1048 | wake_up_interruptible(&priv->delta_msr_wait); |
1023 | 1049 | ||
1024 | /* break takes precedence over parity, */ | ||
1025 | /* which takes precedence over framing errors */ | ||
1026 | if (line_status & UART_BREAK_ERROR) | ||
1027 | tty_flag = TTY_BREAK; | ||
1028 | else if (line_status & UART_PARITY_ERROR) | ||
1029 | tty_flag = TTY_PARITY; | ||
1030 | else if (line_status & UART_FRAME_ERROR) | ||
1031 | tty_flag = TTY_FRAME; | ||
1032 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
1033 | |||
1034 | tty = tty_port_tty_get(&port->port); | 1050 | tty = tty_port_tty_get(&port->port); |
1035 | if (tty && urb->actual_length) { | 1051 | if (tty && urb->actual_length) { |
1036 | tty_buffer_request_room(tty, urb->actual_length + 1); | 1052 | pl2303_push_data(tty, port, urb, line_status); |
1037 | /* overrun is special, not associated with a char */ | ||
1038 | if (line_status & UART_OVERRUN_ERROR) | ||
1039 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1040 | for (i = 0; i < urb->actual_length; ++i) | ||
1041 | if (!usb_serial_handle_sysrq_char(port, data[i])) | ||
1042 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1043 | tty_flip_buffer_push(tty); | ||
1044 | } | 1053 | } |
1045 | tty_kref_put(tty); | 1054 | tty_kref_put(tty); |
1046 | /* Schedule the next read _if_ we are still open */ | 1055 | /* Schedule the next read _if_ we are still open */ |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 1d7a22e3a9fd..12aac7d2462d 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -122,3 +122,7 @@ | |||
122 | /* Hewlett-Packard LD220-HP POS Pole Display */ | 122 | /* Hewlett-Packard LD220-HP POS Pole Display */ |
123 | #define HP_VENDOR_ID 0x03f0 | 123 | #define HP_VENDOR_ID 0x03f0 |
124 | #define HP_LD220_PRODUCT_ID 0x3524 | 124 | #define HP_LD220_PRODUCT_ID 0x3524 |
125 | |||
126 | /* Cressi Edy (diving computer) PC interface */ | ||
127 | #define CRESSI_VENDOR_ID 0x04b8 | ||
128 | #define CRESSI_EDY_PRODUCT_ID 0x0521 | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 032f7aeb40a4..f48d05e0acc1 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = { | |||
181 | }; | 181 | }; |
182 | 182 | ||
183 | static struct usb_device_id id_table [] = { | 183 | static struct usb_device_id id_table [] = { |
184 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | ||
185 | { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */ | ||
186 | { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */ | ||
187 | |||
184 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 188 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
185 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 189 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
186 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 190 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ |
187 | { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */ | ||
188 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 191 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
189 | { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ | ||
190 | { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ | 192 | { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ |
193 | { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */ | ||
194 | { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ | ||
195 | { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */ | ||
191 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 196 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
192 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 197 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
198 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
193 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ | 199 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ |
194 | /* Sierra Wireless C597 */ | 200 | /* Sierra Wireless C597 */ |
195 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, | 201 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) }, |
196 | /* Sierra Wireless Device */ | 202 | /* Sierra Wireless T598 */ |
197 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, | 203 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, |
198 | { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */ | 204 | { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */ |
199 | { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */ | 205 | { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */ |
200 | { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */ | 206 | { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */ |
207 | { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */ | ||
201 | 208 | ||
202 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 209 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
203 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
204 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 210 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
211 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
212 | { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */ | ||
213 | { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */ | ||
214 | { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */ | ||
205 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ | 215 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ |
206 | { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */ | 216 | { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ |
207 | { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ | 217 | { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ |
208 | { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */ | 218 | { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */ |
209 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 219 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
210 | { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ | 220 | { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ |
221 | { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */ | ||
211 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ | 222 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ |
212 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ | 223 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ |
224 | { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */ | ||
225 | { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */ | ||
226 | { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */ | ||
227 | { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */ | ||
213 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ | 228 | { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ |
214 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ | 229 | { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ |
215 | /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ | 230 | /* Sierra Wireless MC8790, MC8791, MC8792 Composite */ |
@@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = { | |||
227 | { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ | 242 | { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ |
228 | /* Sierra Wireless C885 */ | 243 | /* Sierra Wireless C885 */ |
229 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, | 244 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, |
230 | /* Sierra Wireless Device */ | 245 | /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ |
231 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, | 246 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, |
232 | /* Sierra Wireless Device */ | 247 | /* Sierra Wireless C22/C33 */ |
233 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, | 248 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, |
234 | /* Sierra Wireless Device */ | 249 | /* Sierra Wireless HSPA Non-Composite Device */ |
235 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, | 250 | { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, |
236 | 251 | { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ | |
237 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | ||
238 | { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ | ||
239 | |||
240 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ | 252 | { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ |
241 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist | 253 | .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist |
242 | }, | 254 | }, |
@@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial) | |||
814 | return 0; | 826 | return 0; |
815 | } | 827 | } |
816 | 828 | ||
817 | static void sierra_disconnect(struct usb_serial *serial) | 829 | static void sierra_release(struct usb_serial *serial) |
818 | { | 830 | { |
819 | int i; | 831 | int i; |
820 | struct usb_serial_port *port; | 832 | struct usb_serial_port *port; |
@@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial) | |||
830 | if (!portdata) | 842 | if (!portdata) |
831 | continue; | 843 | continue; |
832 | kfree(portdata); | 844 | kfree(portdata); |
833 | usb_set_serial_port_data(port, NULL); | ||
834 | } | 845 | } |
835 | } | 846 | } |
836 | 847 | ||
@@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = { | |||
853 | .tiocmget = sierra_tiocmget, | 864 | .tiocmget = sierra_tiocmget, |
854 | .tiocmset = sierra_tiocmset, | 865 | .tiocmset = sierra_tiocmset, |
855 | .attach = sierra_startup, | 866 | .attach = sierra_startup, |
856 | .disconnect = sierra_disconnect, | 867 | .release = sierra_release, |
857 | .read_int_callback = sierra_instat_callback, | 868 | .read_int_callback = sierra_instat_callback, |
858 | }; | 869 | }; |
859 | 870 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 991d8232e376..3bc609fe2242 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -191,7 +191,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { | |||
191 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, | 191 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, |
192 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, | 192 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, |
193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, | 193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, |
194 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, | ||
195 | }; | 194 | }; |
196 | 195 | ||
197 | static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { | 196 | static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { |
@@ -728,7 +727,7 @@ static int ti_write_room(struct tty_struct *tty) | |||
728 | dbg("%s - port %d", __func__, port->number); | 727 | dbg("%s - port %d", __func__, port->number); |
729 | 728 | ||
730 | if (tport == NULL) | 729 | if (tport == NULL) |
731 | return -ENODEV; | 730 | return 0; |
732 | 731 | ||
733 | spin_lock_irqsave(&tport->tp_lock, flags); | 732 | spin_lock_irqsave(&tport->tp_lock, flags); |
734 | room = ti_buf_space_avail(tport->tp_write_buf); | 733 | room = ti_buf_space_avail(tport->tp_write_buf); |
@@ -749,7 +748,7 @@ static int ti_chars_in_buffer(struct tty_struct *tty) | |||
749 | dbg("%s - port %d", __func__, port->number); | 748 | dbg("%s - port %d", __func__, port->number); |
750 | 749 | ||
751 | if (tport == NULL) | 750 | if (tport == NULL) |
752 | return -ENODEV; | 751 | return 0; |
753 | 752 | ||
754 | spin_lock_irqsave(&tport->tp_lock, flags); | 753 | spin_lock_irqsave(&tport->tp_lock, flags); |
755 | chars = ti_buf_data_avail(tport->tp_write_buf); | 754 | chars = ti_buf_data_avail(tport->tp_write_buf); |
@@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe, | |||
1658 | u8 cs = 0; | 1657 | u8 cs = 0; |
1659 | int done; | 1658 | int done; |
1660 | struct ti_firmware_header *header; | 1659 | struct ti_firmware_header *header; |
1661 | int status; | 1660 | int status = 0; |
1662 | int len; | 1661 | int len; |
1663 | 1662 | ||
1664 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) | 1663 | for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a84216464ca0..bd7581b3a48a 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/smp_lock.h> | ||
24 | #include <linux/tty.h> | 25 | #include <linux/tty.h> |
25 | #include <linux/tty_driver.h> | 26 | #include <linux/tty_driver.h> |
26 | #include <linux/tty_flip.h> | 27 | #include <linux/tty_flip.h> |
@@ -220,7 +221,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
220 | tty->driver_data = port; | 221 | tty->driver_data = port; |
221 | tty_port_tty_set(&port->port, tty); | 222 | tty_port_tty_set(&port->port, tty); |
222 | 223 | ||
223 | if (port->port.count == 1) { | 224 | /* If the console is attached, the device is already open */ |
225 | if (port->port.count == 1 && !port->console) { | ||
224 | 226 | ||
225 | /* lock this module before we call it | 227 | /* lock this module before we call it |
226 | * this may fail, which means we must bail out, | 228 | * this may fail, which means we must bail out, |
diff --git a/drivers/usb/storage/option_ms.c b/drivers/usb/storage/option_ms.c index d41cc0a970f7..773a5cd38c5a 100644 --- a/drivers/usb/storage/option_ms.c +++ b/drivers/usb/storage/option_ms.c | |||
@@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us) | |||
118 | 118 | ||
119 | result = memcmp(buffer+8, "Option", 6); | 119 | result = memcmp(buffer+8, "Option", 6); |
120 | 120 | ||
121 | if (result != 0) | ||
122 | result = memcmp(buffer+8, "ZCOPTION", 8); | ||
123 | |||
121 | /* Read the CSW */ | 124 | /* Read the CSW */ |
122 | usb_stor_bulk_transfer_buf(us, | 125 | usb_stor_bulk_transfer_buf(us, |
123 | us->recv_bulk_pipe, | 126 | us->recv_bulk_pipe, |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8afcf08eba98..3b54b3940178 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1119,12 +1119,13 @@ config FB_CARILLO_RANCH | |||
1119 | 1119 | ||
1120 | config FB_INTEL | 1120 | config FB_INTEL |
1121 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" | 1121 | tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" |
1122 | depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL | 1122 | depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL && EMBEDDED |
1123 | select FB_MODE_HELPERS | 1123 | select FB_MODE_HELPERS |
1124 | select FB_CFB_FILLRECT | 1124 | select FB_CFB_FILLRECT |
1125 | select FB_CFB_COPYAREA | 1125 | select FB_CFB_COPYAREA |
1126 | select FB_CFB_IMAGEBLIT | 1126 | select FB_CFB_IMAGEBLIT |
1127 | select FB_BOOT_VESA_SUPPORT if FB_INTEL = y | 1127 | select FB_BOOT_VESA_SUPPORT if FB_INTEL = y |
1128 | depends on !DRM_I915 | ||
1128 | help | 1129 | help |
1129 | This driver supports the on-board graphics built in to the Intel | 1130 | This driver supports the on-board graphics built in to the Intel |
1130 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. | 1131 | 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. |
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index e641584e212e..887166267443 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c | |||
@@ -145,6 +145,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev, | |||
145 | struct backlight_device *bl = platform_get_drvdata(pdev); | 145 | struct backlight_device *bl = platform_get_drvdata(pdev); |
146 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); | 146 | struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); |
147 | 147 | ||
148 | if (pb->notify) | ||
149 | pb->notify(0); | ||
148 | pwm_config(pb->pwm, 0, pb->period); | 150 | pwm_config(pb->pwm, 0, pb->period); |
149 | pwm_disable(pb->pwm); | 151 | pwm_disable(pb->pwm); |
150 | return 0; | 152 | return 0; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 53ea05645ff8..a85c818be945 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/compat.h> | 16 | #include <linux/compat.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/major.h> | 20 | #include <linux/major.h> |
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 5c1a2c01778f..9ae9cd32bd06 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -256,8 +256,8 @@ static void fix_edid(unsigned char *edid, int fix) | |||
256 | 256 | ||
257 | static int edid_checksum(unsigned char *edid) | 257 | static int edid_checksum(unsigned char *edid) |
258 | { | 258 | { |
259 | unsigned char i, csum = 0, all_null = 0; | 259 | unsigned char csum = 0, all_null = 0; |
260 | int err = 0, fix = check_edid(edid); | 260 | int i, err = 0, fix = check_edid(edid); |
261 | 261 | ||
262 | if (fix) | 262 | if (fix) |
263 | fix_edid(edid, fix); | 263 | fix_edid(edid, fix); |
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 567fb944bd2a..f8778cde2183 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c | |||
@@ -1365,11 +1365,6 @@ static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) | |||
1365 | init_completion(&mx3fbi->flip_cmpl); | 1365 | init_completion(&mx3fbi->flip_cmpl); |
1366 | disable_irq(ichan->eof_irq); | 1366 | disable_irq(ichan->eof_irq); |
1367 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); | 1367 | dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); |
1368 | ret = mx3fb_set_par(fbi); | ||
1369 | if (ret < 0) | ||
1370 | goto esetpar; | ||
1371 | |||
1372 | mx3fb_blank(FB_BLANK_UNBLANK, fbi); | ||
1373 | 1368 | ||
1374 | dev_info(dev, "registered, using mode %s\n", fb_mode); | 1369 | dev_info(dev, "registered, using mode %s\n", fb_mode); |
1375 | 1370 | ||
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 4ea99bfc37b4..8862233d57b6 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c | |||
@@ -1254,7 +1254,7 @@ static struct fb_ops omapfb_ops = { | |||
1254 | static ssize_t omapfb_show_caps_num(struct device *dev, | 1254 | static ssize_t omapfb_show_caps_num(struct device *dev, |
1255 | struct device_attribute *attr, char *buf) | 1255 | struct device_attribute *attr, char *buf) |
1256 | { | 1256 | { |
1257 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1257 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1258 | int plane; | 1258 | int plane; |
1259 | size_t size; | 1259 | size_t size; |
1260 | struct omapfb_caps caps; | 1260 | struct omapfb_caps caps; |
@@ -1274,7 +1274,7 @@ static ssize_t omapfb_show_caps_num(struct device *dev, | |||
1274 | static ssize_t omapfb_show_caps_text(struct device *dev, | 1274 | static ssize_t omapfb_show_caps_text(struct device *dev, |
1275 | struct device_attribute *attr, char *buf) | 1275 | struct device_attribute *attr, char *buf) |
1276 | { | 1276 | { |
1277 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1277 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1278 | int i; | 1278 | int i; |
1279 | struct omapfb_caps caps; | 1279 | struct omapfb_caps caps; |
1280 | int plane; | 1280 | int plane; |
@@ -1321,7 +1321,7 @@ static DEVICE_ATTR(caps_text, 0444, omapfb_show_caps_text, NULL); | |||
1321 | static ssize_t omapfb_show_panel_name(struct device *dev, | 1321 | static ssize_t omapfb_show_panel_name(struct device *dev, |
1322 | struct device_attribute *attr, char *buf) | 1322 | struct device_attribute *attr, char *buf) |
1323 | { | 1323 | { |
1324 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1324 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1325 | 1325 | ||
1326 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); | 1326 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); |
1327 | } | 1327 | } |
@@ -1330,7 +1330,7 @@ static ssize_t omapfb_show_bklight_level(struct device *dev, | |||
1330 | struct device_attribute *attr, | 1330 | struct device_attribute *attr, |
1331 | char *buf) | 1331 | char *buf) |
1332 | { | 1332 | { |
1333 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1333 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1334 | int r; | 1334 | int r; |
1335 | 1335 | ||
1336 | if (fbdev->panel->get_bklight_level) { | 1336 | if (fbdev->panel->get_bklight_level) { |
@@ -1345,7 +1345,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, | |||
1345 | struct device_attribute *attr, | 1345 | struct device_attribute *attr, |
1346 | const char *buf, size_t size) | 1346 | const char *buf, size_t size) |
1347 | { | 1347 | { |
1348 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1348 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1349 | int r; | 1349 | int r; |
1350 | 1350 | ||
1351 | if (fbdev->panel->set_bklight_level) { | 1351 | if (fbdev->panel->set_bklight_level) { |
@@ -1364,7 +1364,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, | |||
1364 | static ssize_t omapfb_show_bklight_max(struct device *dev, | 1364 | static ssize_t omapfb_show_bklight_max(struct device *dev, |
1365 | struct device_attribute *attr, char *buf) | 1365 | struct device_attribute *attr, char *buf) |
1366 | { | 1366 | { |
1367 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1367 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1368 | int r; | 1368 | int r; |
1369 | 1369 | ||
1370 | if (fbdev->panel->get_bklight_level) { | 1370 | if (fbdev->panel->get_bklight_level) { |
@@ -1397,7 +1397,7 @@ static struct attribute_group panel_attr_grp = { | |||
1397 | static ssize_t omapfb_show_ctrl_name(struct device *dev, | 1397 | static ssize_t omapfb_show_ctrl_name(struct device *dev, |
1398 | struct device_attribute *attr, char *buf) | 1398 | struct device_attribute *attr, char *buf) |
1399 | { | 1399 | { |
1400 | struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; | 1400 | struct omapfb_device *fbdev = dev_get_drvdata(dev); |
1401 | 1401 | ||
1402 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); | 1402 | return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); |
1403 | } | 1403 | } |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 16d4f4c7d52b..924d79462780 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -1540,9 +1540,6 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1540 | if (ret) | 1540 | if (ret) |
1541 | dev_err(info->dev, "check_var() failed on initial setup?\n"); | 1541 | dev_err(info->dev, "check_var() failed on initial setup?\n"); |
1542 | 1542 | ||
1543 | /* ensure we've activated our new configuration */ | ||
1544 | (fb->fbops->fb_set_par)(fb); | ||
1545 | |||
1546 | return 0; | 1543 | return 0; |
1547 | } | 1544 | } |
1548 | 1545 | ||
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 193c8f0e5cc5..bcec78ffc765 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -669,7 +669,7 @@ static int __init virtio_pci_init(void) | |||
669 | 669 | ||
670 | err = pci_register_driver(&virtio_pci_driver); | 670 | err = pci_register_driver(&virtio_pci_driver); |
671 | if (err) | 671 | if (err) |
672 | device_unregister(virtio_pci_root); | 672 | root_device_unregister(virtio_pci_root); |
673 | 673 | ||
674 | return err; | 674 | return err; |
675 | } | 675 | } |
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index 5c7011cda6a6..751c003864ad 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c | |||
@@ -161,7 +161,7 @@ static long bcm47xx_wdt_ioctl(struct file *file, | |||
161 | { | 161 | { |
162 | void __user *argp = (void __user *)arg; | 162 | void __user *argp = (void __user *)arg; |
163 | int __user *p = argp; | 163 | int __user *p = argp; |
164 | int new_value, retval = -EINVAL;; | 164 | int new_value, retval = -EINVAL; |
165 | 165 | ||
166 | switch (cmd) { | 166 | switch (cmd) { |
167 | case WDIOC_GETSUPPORT: | 167 | case WDIOC_GETSUPPORT: |
diff --git a/drivers/watchdog/ep93xx_wdt.c b/drivers/watchdog/ep93xx_wdt.c index e9f950ff86ea..cdd55e0d09f8 100644 --- a/drivers/watchdog/ep93xx_wdt.c +++ b/drivers/watchdog/ep93xx_wdt.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/watchdog.h> | 29 | #include <linux/watchdog.h> |
30 | #include <linux/timer.h> | 30 | #include <linux/timer.h> |
31 | #include <linux/uaccess.h> | 31 | #include <linux/uaccess.h> |
32 | #include <linux/io.h> | ||
32 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
33 | 34 | ||
34 | #define WDT_VERSION "0.3" | 35 | #define WDT_VERSION "0.3" |
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c index ee1caae4d33b..016245419fad 100644 --- a/drivers/watchdog/sa1100_wdt.c +++ b/drivers/watchdog/sa1100_wdt.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | static unsigned long oscr_freq; | 39 | static unsigned long oscr_freq; |
40 | static unsigned long sa1100wdt_users; | 40 | static unsigned long sa1100wdt_users; |
41 | static int pre_margin; | 41 | static unsigned int pre_margin; |
42 | static int boot_status; | 42 | static int boot_status; |
43 | 43 | ||
44 | /* | 44 | /* |
@@ -84,6 +84,7 @@ static const struct watchdog_info ident = { | |||
84 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | 84 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT |
85 | | WDIOF_KEEPALIVEPING, | 85 | | WDIOF_KEEPALIVEPING, |
86 | .identity = "SA1100/PXA255 Watchdog", | 86 | .identity = "SA1100/PXA255 Watchdog", |
87 | .firmware_version = 1, | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, | 90 | static long sa1100dog_ioctl(struct file *file, unsigned int cmd, |
@@ -118,7 +119,7 @@ static long sa1100dog_ioctl(struct file *file, unsigned int cmd, | |||
118 | if (ret) | 119 | if (ret) |
119 | break; | 120 | break; |
120 | 121 | ||
121 | if (time <= 0 || time > 255) { | 122 | if (time <= 0 || (oscr_freq * (long long)time >= 0xffffffff)) { |
122 | ret = -EINVAL; | 123 | ret = -EINVAL; |
123 | break; | 124 | break; |
124 | } | 125 | } |
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index 916890abffdd..f201accc4e3d 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c | |||
@@ -89,6 +89,11 @@ static void w83627hf_select_wd_register(void) | |||
89 | c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ | 89 | c = ((inb_p(WDT_EFDR) & 0xf7) | 0x04); /* select WDT0 */ |
90 | outb_p(0x2b, WDT_EFER); | 90 | outb_p(0x2b, WDT_EFER); |
91 | outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */ | 91 | outb_p(c, WDT_EFDR); /* set GPIO3 to WDT0 */ |
92 | } else if (c == 0x88) { /* W83627EHF */ | ||
93 | outb_p(0x2d, WDT_EFER); /* select GPIO5 */ | ||
94 | c = inb_p(WDT_EFDR) & ~0x01; /* PIN77 -> WDT0# */ | ||
95 | outb_p(0x2d, WDT_EFER); | ||
96 | outb_p(c, WDT_EFDR); /* set GPIO5 to WDT0 */ | ||
92 | } | 97 | } |
93 | 98 | ||
94 | outb_p(0x07, WDT_EFER); /* point to logical device number reg */ | 99 | outb_p(0x07, WDT_EFER); /* point to logical device number reg */ |
diff --git a/drivers/watchdog/w83697ug_wdt.c b/drivers/watchdog/w83697ug_wdt.c index 883b5f79673a..a6c12dec91a1 100644 --- a/drivers/watchdog/w83697ug_wdt.c +++ b/drivers/watchdog/w83697ug_wdt.c | |||
@@ -149,8 +149,10 @@ static void wdt_ctrl(int timeout) | |||
149 | { | 149 | { |
150 | spin_lock(&io_lock); | 150 | spin_lock(&io_lock); |
151 | 151 | ||
152 | if (w83697ug_select_wd_register() < 0) | 152 | if (w83697ug_select_wd_register() < 0) { |
153 | spin_unlock(&io_lock); | ||
153 | return; | 154 | return; |
155 | } | ||
154 | 156 | ||
155 | outb_p(0xF4, WDT_EFER); /* Select CRF4 */ | 157 | outb_p(0xF4, WDT_EFER); /* Select CRF4 */ |
156 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ | 158 | outb_p(timeout, WDT_EFDR); /* Write Timeout counter to CRF4 */ |
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 6fcb1e7095cf..92828281a30b 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -57,7 +57,7 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page) | |||
57 | buffer = kmap(page); | 57 | buffer = kmap(page); |
58 | offset = page_offset(page); | 58 | offset = page_offset(page); |
59 | 59 | ||
60 | retval = v9fs_file_readn(filp, buffer, NULL, offset, PAGE_CACHE_SIZE); | 60 | retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset); |
61 | if (retval < 0) | 61 | if (retval < 0) |
62 | goto done; | 62 | goto done; |
63 | 63 | ||
diff --git a/fs/Kconfig b/fs/Kconfig index a97263be6a91..0e7da7bb5d93 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -186,32 +186,7 @@ source "fs/romfs/Kconfig" | |||
186 | source "fs/sysv/Kconfig" | 186 | source "fs/sysv/Kconfig" |
187 | source "fs/ufs/Kconfig" | 187 | source "fs/ufs/Kconfig" |
188 | source "fs/exofs/Kconfig" | 188 | source "fs/exofs/Kconfig" |
189 | 189 | source "fs/nilfs2/Kconfig" | |
190 | config NILFS2_FS | ||
191 | tristate "NILFS2 file system support (EXPERIMENTAL)" | ||
192 | depends on BLOCK && EXPERIMENTAL | ||
193 | select CRC32 | ||
194 | help | ||
195 | NILFS2 is a log-structured file system (LFS) supporting continuous | ||
196 | snapshotting. In addition to versioning capability of the entire | ||
197 | file system, users can even restore files mistakenly overwritten or | ||
198 | destroyed just a few seconds ago. Since this file system can keep | ||
199 | consistency like conventional LFS, it achieves quick recovery after | ||
200 | system crashes. | ||
201 | |||
202 | NILFS2 creates a number of checkpoints every few seconds or per | ||
203 | synchronous write basis (unless there is no change). Users can | ||
204 | select significant versions among continuously created checkpoints, | ||
205 | and can change them into snapshots which will be preserved for long | ||
206 | periods until they are changed back to checkpoints. Each | ||
207 | snapshot is mountable as a read-only file system concurrently with | ||
208 | its writable mount, and this feature is convenient for online backup. | ||
209 | |||
210 | Some features including atime, extended attributes, and POSIX ACLs, | ||
211 | are not supported yet. | ||
212 | |||
213 | To compile this file system support as a module, choose M here: the | ||
214 | module will be called nilfs2. If unsure, say N. | ||
215 | 190 | ||
216 | endif # MISC_FILESYSTEMS | 191 | endif # MISC_FILESYSTEMS |
217 | 192 | ||
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index aad92f0a1048..6910a98bd73c 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/parser.h> | 13 | #include <linux/parser.h> |
14 | #include <linux/mount.h> | 14 | #include <linux/mount.h> |
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/smp_lock.h> | ||
16 | #include <linux/statfs.h> | 17 | #include <linux/statfs.h> |
17 | #include "adfs.h" | 18 | #include "adfs.h" |
18 | #include "dir_f.h" | 19 | #include "dir_f.h" |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 9bd757774c9e..88067f36e5e7 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -564,7 +564,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | |||
564 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 564 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) |
565 | { | 565 | { |
566 | struct afs_vnode *vnode, *dir; | 566 | struct afs_vnode *vnode, *dir; |
567 | struct afs_fid fid; | 567 | struct afs_fid uninitialized_var(fid); |
568 | struct dentry *parent; | 568 | struct dentry *parent; |
569 | struct key *key; | 569 | struct key *key; |
570 | void *dir_version; | 570 | void *dir_version; |
diff --git a/fs/afs/super.c b/fs/afs/super.c index ad0514d0115f..e1ea1c240b6a 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/smp_lock.h> | ||
21 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
22 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
23 | #include <linux/parser.h> | 24 | #include <linux/parser.h> |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index f3da2eb51f56..00bf8fcb245f 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
21 | #include <linux/syscalls.h> | 21 | #include <linux/syscalls.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/magic.h> | 22 | #include <linux/magic.h> |
24 | #include <linux/dcache.h> | 23 | #include <linux/dcache.h> |
25 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 54bd07d44e68..1e41aadb1068 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -8,7 +8,6 @@ | |||
8 | #include <linux/time.h> | 8 | #include <linux/time.h> |
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
13 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
14 | #include "bfs.h" | 13 | #include "bfs.h" |
diff --git a/fs/bfs/file.c b/fs/bfs/file.c index 6a021265f018..88b9a3ff44e4 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/smp_lock.h> | ||
15 | #include "bfs.h" | 14 | #include "bfs.h" |
16 | 15 | ||
17 | #undef DEBUG | 16 | #undef DEBUG |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index de1e2fd32080..9d8ba4d54a37 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
31 | #include <linux/mpage.h> | 30 | #include <linux/mpage.h> |
32 | #include <linux/swap.h> | 31 | #include <linux/swap.h> |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 7c3cd248d8d6..4b833972273a 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/smp_lock.h> | ||
26 | #include <linux/backing-dev.h> | 25 | #include <linux/backing-dev.h> |
27 | #include <linux/mpage.h> | 26 | #include <linux/mpage.h> |
28 | #include <linux/swap.h> | 27 | #include <linux/swap.h> |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 7ffa3d34ea19..791eab19e330 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
31 | #include <linux/mpage.h> | 30 | #include <linux/mpage.h> |
32 | #include <linux/swap.h> | 31 | #include <linux/swap.h> |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9f4db848db10..bd88f25889f7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
30 | #include <linux/smp_lock.h> | ||
31 | #include <linux/backing-dev.h> | 30 | #include <linux/backing-dev.h> |
32 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
33 | #include <linux/mpage.h> | 32 | #include <linux/mpage.h> |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 9f179d4832d5..6d6d06cb6dfc 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/seq_file.h> | 27 | #include <linux/seq_file.h> |
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
31 | #include <linux/mount.h> | 30 | #include <linux/mount.h> |
32 | #include <linux/mpage.h> | 31 | #include <linux/mpage.h> |
diff --git a/fs/char_dev.c b/fs/char_dev.c index b7c9d5187a75..a173551e19d7 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/major.h> | 13 | #include <linux/major.h> |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
18 | 17 | ||
19 | #include <linux/kobject.h> | 18 | #include <linux/kobject.h> |
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 7f19fefd3d45..42cec2a7c0cf 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
@@ -261,6 +261,8 @@ static ssize_t cifs_stats_proc_write(struct file *file, | |||
261 | atomic_set(&tcon->num_reads, 0); | 261 | atomic_set(&tcon->num_reads, 0); |
262 | atomic_set(&tcon->num_oplock_brks, 0); | 262 | atomic_set(&tcon->num_oplock_brks, 0); |
263 | atomic_set(&tcon->num_opens, 0); | 263 | atomic_set(&tcon->num_opens, 0); |
264 | atomic_set(&tcon->num_posixopens, 0); | ||
265 | atomic_set(&tcon->num_posixmkdirs, 0); | ||
264 | atomic_set(&tcon->num_closes, 0); | 266 | atomic_set(&tcon->num_closes, 0); |
265 | atomic_set(&tcon->num_deletes, 0); | 267 | atomic_set(&tcon->num_deletes, 0); |
266 | atomic_set(&tcon->num_mkdirs, 0); | 268 | atomic_set(&tcon->num_mkdirs, 0); |
@@ -347,11 +349,15 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) | |||
347 | atomic_read(&tcon->num_locks), | 349 | atomic_read(&tcon->num_locks), |
348 | atomic_read(&tcon->num_hardlinks), | 350 | atomic_read(&tcon->num_hardlinks), |
349 | atomic_read(&tcon->num_symlinks)); | 351 | atomic_read(&tcon->num_symlinks)); |
350 | seq_printf(m, "\nOpens: %d Closes: %d" | 352 | seq_printf(m, "\nOpens: %d Closes: %d " |
351 | "Deletes: %d", | 353 | "Deletes: %d", |
352 | atomic_read(&tcon->num_opens), | 354 | atomic_read(&tcon->num_opens), |
353 | atomic_read(&tcon->num_closes), | 355 | atomic_read(&tcon->num_closes), |
354 | atomic_read(&tcon->num_deletes)); | 356 | atomic_read(&tcon->num_deletes)); |
357 | seq_printf(m, "\nPosix Opens: %d " | ||
358 | "Posix Mkdirs: %d", | ||
359 | atomic_read(&tcon->num_posixopens), | ||
360 | atomic_read(&tcon->num_posixmkdirs)); | ||
355 | seq_printf(m, "\nMkdirs: %d Rmdirs: %d", | 361 | seq_printf(m, "\nMkdirs: %d Rmdirs: %d", |
356 | atomic_read(&tcon->num_mkdirs), | 362 | atomic_read(&tcon->num_mkdirs), |
357 | atomic_read(&tcon->num_rmdirs)); | 363 | atomic_read(&tcon->num_rmdirs)); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 63f6cdfa5638..6084d6379c03 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -260,6 +260,8 @@ struct cifsTconInfo { | |||
260 | atomic_t num_closes; | 260 | atomic_t num_closes; |
261 | atomic_t num_deletes; | 261 | atomic_t num_deletes; |
262 | atomic_t num_mkdirs; | 262 | atomic_t num_mkdirs; |
263 | atomic_t num_posixopens; | ||
264 | atomic_t num_posixmkdirs; | ||
263 | atomic_t num_rmdirs; | 265 | atomic_t num_rmdirs; |
264 | atomic_t num_renames; | 266 | atomic_t num_renames; |
265 | atomic_t num_t2renames; | 267 | atomic_t num_t2renames; |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 922f5fe2084c..1866bc2927d4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1113,7 +1113,10 @@ PsxCreat: | |||
1113 | psx_create_err: | 1113 | psx_create_err: |
1114 | cifs_buf_release(pSMB); | 1114 | cifs_buf_release(pSMB); |
1115 | 1115 | ||
1116 | cifs_stats_inc(&tcon->num_mkdirs); | 1116 | if (posix_flags & SMB_O_DIRECTORY) |
1117 | cifs_stats_inc(&tcon->num_posixmkdirs); | ||
1118 | else | ||
1119 | cifs_stats_inc(&tcon->num_posixopens); | ||
1117 | 1120 | ||
1118 | if (rc == -EAGAIN) | 1121 | if (rc == -EAGAIN) |
1119 | goto PsxCreat; | 1122 | goto PsxCreat; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e16d7592116a..9bb5c8750736 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -2726,6 +2726,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
2726 | strncpy(tcon->treeName, tree, MAX_TREE_SIZE); | 2726 | strncpy(tcon->treeName, tree, MAX_TREE_SIZE); |
2727 | 2727 | ||
2728 | /* mostly informational -- no need to fail on error here */ | 2728 | /* mostly informational -- no need to fail on error here */ |
2729 | kfree(tcon->nativeFileSystem); | ||
2729 | tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr, | 2730 | tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr, |
2730 | bytes_left, is_unicode, | 2731 | bytes_left, is_unicode, |
2731 | nls_codepage); | 2732 | nls_codepage); |
diff --git a/fs/compat.c b/fs/compat.c index fbadb947727b..94502dab972a 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/smb_mount.h> | 32 | #include <linux/smb_mount.h> |
33 | #include <linux/ncp_mount.h> | 33 | #include <linux/ncp_mount.h> |
34 | #include <linux/nfs4_mount.h> | 34 | #include <linux/nfs4_mount.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/syscalls.h> | 35 | #include <linux/syscalls.h> |
37 | #include <linux/ctype.h> | 36 | #include <linux/ctype.h> |
38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 626c7483b4de..f28f070a60fc 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/compiler.h> | 19 | #include <linux/compiler.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | #include <linux/smp_lock.h> | ||
22 | #include <linux/ioctl.h> | 23 | #include <linux/ioctl.h> |
23 | #include <linux/if.h> | 24 | #include <linux/if.h> |
24 | #include <linux/if_bridge.h> | 25 | #include <linux/if_bridge.h> |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 205ec95b347e..eb507c453c5f 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -435,7 +435,7 @@ static int search_rsb(struct dlm_ls *ls, char *name, int len, int b, | |||
435 | static int find_rsb(struct dlm_ls *ls, char *name, int namelen, | 435 | static int find_rsb(struct dlm_ls *ls, char *name, int namelen, |
436 | unsigned int flags, struct dlm_rsb **r_ret) | 436 | unsigned int flags, struct dlm_rsb **r_ret) |
437 | { | 437 | { |
438 | struct dlm_rsb *r, *tmp; | 438 | struct dlm_rsb *r = NULL, *tmp; |
439 | uint32_t hash, bucket; | 439 | uint32_t hash, bucket; |
440 | int error = -EINVAL; | 440 | int error = -EINVAL; |
441 | 441 | ||
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index cdb580a9c7a2..618a60f03886 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
@@ -902,7 +902,7 @@ static void tcp_connect_to_sock(struct connection *con) | |||
902 | int result = -EHOSTUNREACH; | 902 | int result = -EHOSTUNREACH; |
903 | struct sockaddr_storage saddr, src_addr; | 903 | struct sockaddr_storage saddr, src_addr; |
904 | int addr_len; | 904 | int addr_len; |
905 | struct socket *sock; | 905 | struct socket *sock = NULL; |
906 | 906 | ||
907 | if (con->nodeid == 0) { | 907 | if (con->nodeid == 0) { |
908 | log_print("attempt to connect sock 0 foiled"); | 908 | log_print("attempt to connect sock 0 foiled"); |
@@ -962,6 +962,8 @@ out_err: | |||
962 | if (con->sock) { | 962 | if (con->sock) { |
963 | sock_release(con->sock); | 963 | sock_release(con->sock); |
964 | con->sock = NULL; | 964 | con->sock = NULL; |
965 | } else if (sock) { | ||
966 | sock_release(sock); | ||
965 | } | 967 | } |
966 | /* | 968 | /* |
967 | * Some errors are fatal and this list might need adjusting. For other | 969 | * Some errors are fatal and this list might need adjusting. For other |
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 894a32d438d5..16f682e26c07 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c | |||
@@ -353,7 +353,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, | |||
353 | { | 353 | { |
354 | struct dlm_plock_info info; | 354 | struct dlm_plock_info info; |
355 | struct plock_op *op; | 355 | struct plock_op *op; |
356 | int found = 0; | 356 | int found = 0, do_callback = 0; |
357 | 357 | ||
358 | if (count != sizeof(info)) | 358 | if (count != sizeof(info)) |
359 | return -EINVAL; | 359 | return -EINVAL; |
@@ -366,21 +366,24 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, | |||
366 | 366 | ||
367 | spin_lock(&ops_lock); | 367 | spin_lock(&ops_lock); |
368 | list_for_each_entry(op, &recv_list, list) { | 368 | list_for_each_entry(op, &recv_list, list) { |
369 | if (op->info.fsid == info.fsid && op->info.number == info.number && | 369 | if (op->info.fsid == info.fsid && |
370 | op->info.number == info.number && | ||
370 | op->info.owner == info.owner) { | 371 | op->info.owner == info.owner) { |
372 | struct plock_xop *xop = (struct plock_xop *)op; | ||
371 | list_del_init(&op->list); | 373 | list_del_init(&op->list); |
372 | found = 1; | ||
373 | op->done = 1; | ||
374 | memcpy(&op->info, &info, sizeof(info)); | 374 | memcpy(&op->info, &info, sizeof(info)); |
375 | if (xop->callback) | ||
376 | do_callback = 1; | ||
377 | else | ||
378 | op->done = 1; | ||
379 | found = 1; | ||
375 | break; | 380 | break; |
376 | } | 381 | } |
377 | } | 382 | } |
378 | spin_unlock(&ops_lock); | 383 | spin_unlock(&ops_lock); |
379 | 384 | ||
380 | if (found) { | 385 | if (found) { |
381 | struct plock_xop *xop; | 386 | if (do_callback) |
382 | xop = (struct plock_xop *)op; | ||
383 | if (xop->callback) | ||
384 | dlm_plock_callback(op); | 387 | dlm_plock_callback(op); |
385 | else | 388 | else |
386 | wake_up(&recv_wq); | 389 | wake_up(&recv_wq); |
diff --git a/fs/exofs/common.h b/fs/exofs/common.h index 24667eedc023..c6718e4817fe 100644 --- a/fs/exofs/common.h +++ b/fs/exofs/common.h | |||
@@ -2,9 +2,7 @@ | |||
2 | * common.h - Common definitions for both Kernel and user-mode utilities | 2 | * common.h - Common definitions for both Kernel and user-mode utilities |
3 | * | 3 | * |
4 | * Copyright (C) 2005, 2006 | 4 | * Copyright (C) 2005, 2006 |
5 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 5 | * Avishay Traeger (avishay@gmail.com) |
6 | * Copyright (C) 2005, 2006 | ||
7 | * International Business Machines | ||
8 | * Copyright (C) 2008, 2009 | 6 | * Copyright (C) 2008, 2009 |
9 | * Boaz Harrosh <bharrosh@panasas.com> | 7 | * Boaz Harrosh <bharrosh@panasas.com> |
10 | * | 8 | * |
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c index 65b0c8c776a1..4cfab1cc75c0 100644 --- a/fs/exofs/dir.c +++ b/fs/exofs/dir.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index 0fd4c7859679..5ec72e020b22 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
@@ -156,6 +154,9 @@ ino_t exofs_parent_ino(struct dentry *child); | |||
156 | int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *, | 154 | int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *, |
157 | struct inode *); | 155 | struct inode *); |
158 | 156 | ||
157 | /* super.c */ | ||
158 | int exofs_sync_fs(struct super_block *sb, int wait); | ||
159 | |||
159 | /********************* | 160 | /********************* |
160 | * operation vectors * | 161 | * operation vectors * |
161 | *********************/ | 162 | *********************/ |
diff --git a/fs/exofs/file.c b/fs/exofs/file.c index 6ed7fe484752..839b9dc1e70f 100644 --- a/fs/exofs/file.c +++ b/fs/exofs/file.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
@@ -47,16 +45,23 @@ static int exofs_file_fsync(struct file *filp, struct dentry *dentry, | |||
47 | { | 45 | { |
48 | int ret; | 46 | int ret; |
49 | struct address_space *mapping = filp->f_mapping; | 47 | struct address_space *mapping = filp->f_mapping; |
48 | struct inode *inode = dentry->d_inode; | ||
49 | struct super_block *sb; | ||
50 | 50 | ||
51 | ret = filemap_write_and_wait(mapping); | 51 | ret = filemap_write_and_wait(mapping); |
52 | if (ret) | 52 | if (ret) |
53 | return ret; | 53 | return ret; |
54 | 54 | ||
55 | /*Note: file_fsync below also calles sync_blockdev, which is a no-op | 55 | /* sync the inode attributes */ |
56 | * for exofs, but other then that it does sync_inode and | 56 | ret = write_inode_now(inode, 1); |
57 | * sync_superblock which is what we need here. | 57 | |
58 | */ | 58 | /* This is a good place to write the sb */ |
59 | return file_fsync(filp, dentry, datasync); | 59 | /* TODO: Sechedule an sb-sync on create */ |
60 | sb = inode->i_sb; | ||
61 | if (sb->s_dirt) | ||
62 | exofs_sync_fs(sb, 1); | ||
63 | |||
64 | return ret; | ||
60 | } | 65 | } |
61 | 66 | ||
62 | static int exofs_flush(struct file *file, fl_owner_t id) | 67 | static int exofs_flush(struct file *file, fl_owner_t id) |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 77d0a295eb1c..6c10f7476699 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
@@ -295,6 +293,9 @@ static int read_exec(struct page_collect *pcol, bool is_sync) | |||
295 | err: | 293 | err: |
296 | if (!is_sync) | 294 | if (!is_sync) |
297 | _unlock_pcol_pages(pcol, ret, READ); | 295 | _unlock_pcol_pages(pcol, ret, READ); |
296 | else /* Pages unlocked by caller in sync mode only free bio */ | ||
297 | pcol_free(pcol); | ||
298 | |||
298 | kfree(pcol_copy); | 299 | kfree(pcol_copy); |
299 | if (or) | 300 | if (or) |
300 | osd_end_request(or); | 301 | osd_end_request(or); |
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index 77fdd765e76d..b7dd0c236863 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c index b3d2ccb87aaa..4372542df284 100644 --- a/fs/exofs/osd.c +++ b/fs/exofs/osd.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 8216c5b77b53..5ab10c3bbebe 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
@@ -33,6 +31,7 @@ | |||
33 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 31 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
34 | */ | 32 | */ |
35 | 33 | ||
34 | #include <linux/smp_lock.h> | ||
36 | #include <linux/string.h> | 35 | #include <linux/string.h> |
37 | #include <linux/parser.h> | 36 | #include <linux/parser.h> |
38 | #include <linux/vfs.h> | 37 | #include <linux/vfs.h> |
@@ -200,7 +199,7 @@ static const struct export_operations exofs_export_ops; | |||
200 | /* | 199 | /* |
201 | * Write the superblock to the OSD | 200 | * Write the superblock to the OSD |
202 | */ | 201 | */ |
203 | static int exofs_sync_fs(struct super_block *sb, int wait) | 202 | int exofs_sync_fs(struct super_block *sb, int wait) |
204 | { | 203 | { |
205 | struct exofs_sb_info *sbi; | 204 | struct exofs_sb_info *sbi; |
206 | struct exofs_fscb *fscb; | 205 | struct exofs_fscb *fscb; |
diff --git a/fs/exofs/symlink.c b/fs/exofs/symlink.c index 36e2d7bc7f7b..4dd687c3e747 100644 --- a/fs/exofs/symlink.c +++ b/fs/exofs/symlink.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
4 | * Copyright (C) 2005, 2006 | ||
5 | * International Business Machines | ||
6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
8 | * | 6 | * |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 7cb4badef927..e7431309bdca 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
15 | #include <linux/mount.h> | 15 | #include <linux/mount.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <asm/current.h> | 16 | #include <asm/current.h> |
18 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
19 | 18 | ||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0ddf7e55abe1..9714db393efe 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -93,20 +93,20 @@ typedef unsigned int ext4_group_t; | |||
93 | struct ext4_allocation_request { | 93 | struct ext4_allocation_request { |
94 | /* target inode for block we're allocating */ | 94 | /* target inode for block we're allocating */ |
95 | struct inode *inode; | 95 | struct inode *inode; |
96 | /* how many blocks we want to allocate */ | ||
97 | unsigned int len; | ||
96 | /* logical block in target inode */ | 98 | /* logical block in target inode */ |
97 | ext4_lblk_t logical; | 99 | ext4_lblk_t logical; |
98 | /* phys. target (a hint) */ | ||
99 | ext4_fsblk_t goal; | ||
100 | /* the closest logical allocated block to the left */ | 100 | /* the closest logical allocated block to the left */ |
101 | ext4_lblk_t lleft; | 101 | ext4_lblk_t lleft; |
102 | /* phys. block for ^^^ */ | ||
103 | ext4_fsblk_t pleft; | ||
104 | /* the closest logical allocated block to the right */ | 102 | /* the closest logical allocated block to the right */ |
105 | ext4_lblk_t lright; | 103 | ext4_lblk_t lright; |
106 | /* phys. block for ^^^ */ | 104 | /* phys. target (a hint) */ |
105 | ext4_fsblk_t goal; | ||
106 | /* phys. block for the closest logical allocated block to the left */ | ||
107 | ext4_fsblk_t pleft; | ||
108 | /* phys. block for the closest logical allocated block to the right */ | ||
107 | ext4_fsblk_t pright; | 109 | ext4_fsblk_t pright; |
108 | /* how many blocks we want to allocate */ | ||
109 | unsigned int len; | ||
110 | /* flags. see above EXT4_MB_HINT_* */ | 110 | /* flags. see above EXT4_MB_HINT_* */ |
111 | unsigned int flags; | 111 | unsigned int flags; |
112 | }; | 112 | }; |
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index ad13a84644e1..eb27fd0f2ee8 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c | |||
@@ -43,6 +43,8 @@ int __ext4_journal_forget(const char *where, handle_t *handle, | |||
43 | ext4_journal_abort_handle(where, __func__, bh, | 43 | ext4_journal_abort_handle(where, __func__, bh, |
44 | handle, err); | 44 | handle, err); |
45 | } | 45 | } |
46 | else | ||
47 | brelse(bh); | ||
46 | return err; | 48 | return err; |
47 | } | 49 | } |
48 | 50 | ||
@@ -57,6 +59,8 @@ int __ext4_journal_revoke(const char *where, handle_t *handle, | |||
57 | ext4_journal_abort_handle(where, __func__, bh, | 59 | ext4_journal_abort_handle(where, __func__, bh, |
58 | handle, err); | 60 | handle, err); |
59 | } | 61 | } |
62 | else | ||
63 | brelse(bh); | ||
60 | return err; | 64 | return err; |
61 | } | 65 | } |
62 | 66 | ||
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index be2f426f6805..139fb8cb87e4 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h | |||
@@ -131,9 +131,11 @@ int __ext4_journal_get_undo_access(const char *where, handle_t *handle, | |||
131 | int __ext4_journal_get_write_access(const char *where, handle_t *handle, | 131 | int __ext4_journal_get_write_access(const char *where, handle_t *handle, |
132 | struct buffer_head *bh); | 132 | struct buffer_head *bh); |
133 | 133 | ||
134 | /* When called with an invalid handle, this will still do a put on the BH */ | ||
134 | int __ext4_journal_forget(const char *where, handle_t *handle, | 135 | int __ext4_journal_forget(const char *where, handle_t *handle, |
135 | struct buffer_head *bh); | 136 | struct buffer_head *bh); |
136 | 137 | ||
138 | /* When called with an invalid handle, this will still do a put on the BH */ | ||
137 | int __ext4_journal_revoke(const char *where, handle_t *handle, | 139 | int __ext4_journal_revoke(const char *where, handle_t *handle, |
138 | ext4_fsblk_t blocknr, struct buffer_head *bh); | 140 | ext4_fsblk_t blocknr, struct buffer_head *bh); |
139 | 141 | ||
@@ -281,10 +283,10 @@ static inline int ext4_should_order_data(struct inode *inode) | |||
281 | 283 | ||
282 | static inline int ext4_should_writeback_data(struct inode *inode) | 284 | static inline int ext4_should_writeback_data(struct inode *inode) |
283 | { | 285 | { |
284 | if (EXT4_JOURNAL(inode) == NULL) | ||
285 | return 0; | ||
286 | if (!S_ISREG(inode->i_mode)) | 286 | if (!S_ISREG(inode->i_mode)) |
287 | return 0; | 287 | return 0; |
288 | if (EXT4_JOURNAL(inode) == NULL) | ||
289 | return 1; | ||
288 | if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) | 290 | if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) |
289 | return 0; | 291 | return 0; |
290 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | 292 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 50322a09bd01..73ebfb44ad75 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -1977,6 +1977,7 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks, | |||
1977 | */ | 1977 | */ |
1978 | /* 1 bitmap, 1 block group descriptor */ | 1978 | /* 1 bitmap, 1 block group descriptor */ |
1979 | ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb); | 1979 | ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb); |
1980 | return ret; | ||
1980 | } | 1981 | } |
1981 | } | 1982 | } |
1982 | 1983 | ||
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 2f645732e3b7..29e6dc7299b8 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -833,7 +833,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode, | |||
833 | if (!goal) | 833 | if (!goal) |
834 | goal = sbi->s_inode_goal; | 834 | goal = sbi->s_inode_goal; |
835 | 835 | ||
836 | if (goal && goal < le32_to_cpu(sbi->s_es->s_inodes_count)) { | 836 | if (goal && goal <= le32_to_cpu(sbi->s_es->s_inodes_count)) { |
837 | group = (goal - 1) / EXT4_INODES_PER_GROUP(sb); | 837 | group = (goal - 1) / EXT4_INODES_PER_GROUP(sb); |
838 | ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb); | 838 | ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb); |
839 | ret2 = 0; | 839 | ret2 = 0; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 60a26f3a6f8b..f9c642b22efa 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -78,16 +78,14 @@ static int ext4_inode_is_fast_symlink(struct inode *inode) | |||
78 | * but there may still be a record of it in the journal, and that record | 78 | * but there may still be a record of it in the journal, and that record |
79 | * still needs to be revoked. | 79 | * still needs to be revoked. |
80 | * | 80 | * |
81 | * If the handle isn't valid we're not journaling so there's nothing to do. | 81 | * If the handle isn't valid we're not journaling, but we still need to |
82 | * call into ext4_journal_revoke() to put the buffer head. | ||
82 | */ | 83 | */ |
83 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, | 84 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, |
84 | struct buffer_head *bh, ext4_fsblk_t blocknr) | 85 | struct buffer_head *bh, ext4_fsblk_t blocknr) |
85 | { | 86 | { |
86 | int err; | 87 | int err; |
87 | 88 | ||
88 | if (!ext4_handle_valid(handle)) | ||
89 | return 0; | ||
90 | |||
91 | might_sleep(); | 89 | might_sleep(); |
92 | 90 | ||
93 | BUFFER_TRACE(bh, "enter"); | 91 | BUFFER_TRACE(bh, "enter"); |
@@ -1513,14 +1511,14 @@ retry: | |||
1513 | * Add inode to orphan list in case we crash before | 1511 | * Add inode to orphan list in case we crash before |
1514 | * truncate finishes | 1512 | * truncate finishes |
1515 | */ | 1513 | */ |
1516 | if (pos + len > inode->i_size) | 1514 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
1517 | ext4_orphan_add(handle, inode); | 1515 | ext4_orphan_add(handle, inode); |
1518 | 1516 | ||
1519 | ext4_journal_stop(handle); | 1517 | ext4_journal_stop(handle); |
1520 | if (pos + len > inode->i_size) { | 1518 | if (pos + len > inode->i_size) { |
1521 | vmtruncate(inode, inode->i_size); | 1519 | ext4_truncate(inode); |
1522 | /* | 1520 | /* |
1523 | * If vmtruncate failed early the inode might | 1521 | * If truncate failed early the inode might |
1524 | * still be on the orphan list; we need to | 1522 | * still be on the orphan list; we need to |
1525 | * make sure the inode is removed from the | 1523 | * make sure the inode is removed from the |
1526 | * orphan list in that case. | 1524 | * orphan list in that case. |
@@ -1614,7 +1612,7 @@ static int ext4_ordered_write_end(struct file *file, | |||
1614 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, | 1612 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
1615 | page, fsdata); | 1613 | page, fsdata); |
1616 | copied = ret2; | 1614 | copied = ret2; |
1617 | if (pos + len > inode->i_size) | 1615 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
1618 | /* if we have allocated more blocks and copied | 1616 | /* if we have allocated more blocks and copied |
1619 | * less. We will have blocks allocated outside | 1617 | * less. We will have blocks allocated outside |
1620 | * inode->i_size. So truncate them | 1618 | * inode->i_size. So truncate them |
@@ -1628,9 +1626,9 @@ static int ext4_ordered_write_end(struct file *file, | |||
1628 | ret = ret2; | 1626 | ret = ret2; |
1629 | 1627 | ||
1630 | if (pos + len > inode->i_size) { | 1628 | if (pos + len > inode->i_size) { |
1631 | vmtruncate(inode, inode->i_size); | 1629 | ext4_truncate(inode); |
1632 | /* | 1630 | /* |
1633 | * If vmtruncate failed early the inode might still be | 1631 | * If truncate failed early the inode might still be |
1634 | * on the orphan list; we need to make sure the inode | 1632 | * on the orphan list; we need to make sure the inode |
1635 | * is removed from the orphan list in that case. | 1633 | * is removed from the orphan list in that case. |
1636 | */ | 1634 | */ |
@@ -1655,7 +1653,7 @@ static int ext4_writeback_write_end(struct file *file, | |||
1655 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, | 1653 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
1656 | page, fsdata); | 1654 | page, fsdata); |
1657 | copied = ret2; | 1655 | copied = ret2; |
1658 | if (pos + len > inode->i_size) | 1656 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
1659 | /* if we have allocated more blocks and copied | 1657 | /* if we have allocated more blocks and copied |
1660 | * less. We will have blocks allocated outside | 1658 | * less. We will have blocks allocated outside |
1661 | * inode->i_size. So truncate them | 1659 | * inode->i_size. So truncate them |
@@ -1670,9 +1668,9 @@ static int ext4_writeback_write_end(struct file *file, | |||
1670 | ret = ret2; | 1668 | ret = ret2; |
1671 | 1669 | ||
1672 | if (pos + len > inode->i_size) { | 1670 | if (pos + len > inode->i_size) { |
1673 | vmtruncate(inode, inode->i_size); | 1671 | ext4_truncate(inode); |
1674 | /* | 1672 | /* |
1675 | * If vmtruncate failed early the inode might still be | 1673 | * If truncate failed early the inode might still be |
1676 | * on the orphan list; we need to make sure the inode | 1674 | * on the orphan list; we need to make sure the inode |
1677 | * is removed from the orphan list in that case. | 1675 | * is removed from the orphan list in that case. |
1678 | */ | 1676 | */ |
@@ -1722,7 +1720,7 @@ static int ext4_journalled_write_end(struct file *file, | |||
1722 | 1720 | ||
1723 | unlock_page(page); | 1721 | unlock_page(page); |
1724 | page_cache_release(page); | 1722 | page_cache_release(page); |
1725 | if (pos + len > inode->i_size) | 1723 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
1726 | /* if we have allocated more blocks and copied | 1724 | /* if we have allocated more blocks and copied |
1727 | * less. We will have blocks allocated outside | 1725 | * less. We will have blocks allocated outside |
1728 | * inode->i_size. So truncate them | 1726 | * inode->i_size. So truncate them |
@@ -1733,9 +1731,9 @@ static int ext4_journalled_write_end(struct file *file, | |||
1733 | if (!ret) | 1731 | if (!ret) |
1734 | ret = ret2; | 1732 | ret = ret2; |
1735 | if (pos + len > inode->i_size) { | 1733 | if (pos + len > inode->i_size) { |
1736 | vmtruncate(inode, inode->i_size); | 1734 | ext4_truncate(inode); |
1737 | /* | 1735 | /* |
1738 | * If vmtruncate failed early the inode might still be | 1736 | * If truncate failed early the inode might still be |
1739 | * on the orphan list; we need to make sure the inode | 1737 | * on the orphan list; we need to make sure the inode |
1740 | * is removed from the orphan list in that case. | 1738 | * is removed from the orphan list in that case. |
1741 | */ | 1739 | */ |
@@ -2305,15 +2303,9 @@ flush_it: | |||
2305 | return; | 2303 | return; |
2306 | } | 2304 | } |
2307 | 2305 | ||
2308 | static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) | 2306 | static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh) |
2309 | { | 2307 | { |
2310 | /* | 2308 | return (buffer_delay(bh) || buffer_unwritten(bh)) && buffer_dirty(bh); |
2311 | * unmapped buffer is possible for holes. | ||
2312 | * delay buffer is possible with delayed allocation. | ||
2313 | * We also need to consider unwritten buffer as unmapped. | ||
2314 | */ | ||
2315 | return (!buffer_mapped(bh) || buffer_delay(bh) || | ||
2316 | buffer_unwritten(bh)) && buffer_dirty(bh); | ||
2317 | } | 2309 | } |
2318 | 2310 | ||
2319 | /* | 2311 | /* |
@@ -2398,9 +2390,9 @@ static int __mpage_da_writepage(struct page *page, | |||
2398 | * We need to try to allocate | 2390 | * We need to try to allocate |
2399 | * unmapped blocks in the same page. | 2391 | * unmapped blocks in the same page. |
2400 | * Otherwise we won't make progress | 2392 | * Otherwise we won't make progress |
2401 | * with the page in ext4_da_writepage | 2393 | * with the page in ext4_writepage |
2402 | */ | 2394 | */ |
2403 | if (ext4_bh_unmapped_or_delay(NULL, bh)) { | 2395 | if (ext4_bh_delay_or_unwritten(NULL, bh)) { |
2404 | mpage_add_bh_to_extent(mpd, logical, | 2396 | mpage_add_bh_to_extent(mpd, logical, |
2405 | bh->b_size, | 2397 | bh->b_size, |
2406 | bh->b_state); | 2398 | bh->b_state); |
@@ -2517,7 +2509,6 @@ static int noalloc_get_block_write(struct inode *inode, sector_t iblock, | |||
2517 | * so call get_block_wrap with create = 0 | 2509 | * so call get_block_wrap with create = 0 |
2518 | */ | 2510 | */ |
2519 | ret = ext4_get_blocks(NULL, inode, iblock, max_blocks, bh_result, 0); | 2511 | ret = ext4_get_blocks(NULL, inode, iblock, max_blocks, bh_result, 0); |
2520 | BUG_ON(create && ret == 0); | ||
2521 | if (ret > 0) { | 2512 | if (ret > 0) { |
2522 | bh_result->b_size = (ret << inode->i_blkbits); | 2513 | bh_result->b_size = (ret << inode->i_blkbits); |
2523 | ret = 0; | 2514 | ret = 0; |
@@ -2525,15 +2516,102 @@ static int noalloc_get_block_write(struct inode *inode, sector_t iblock, | |||
2525 | return ret; | 2516 | return ret; |
2526 | } | 2517 | } |
2527 | 2518 | ||
2519 | static int bget_one(handle_t *handle, struct buffer_head *bh) | ||
2520 | { | ||
2521 | get_bh(bh); | ||
2522 | return 0; | ||
2523 | } | ||
2524 | |||
2525 | static int bput_one(handle_t *handle, struct buffer_head *bh) | ||
2526 | { | ||
2527 | put_bh(bh); | ||
2528 | return 0; | ||
2529 | } | ||
2530 | |||
2531 | static int __ext4_journalled_writepage(struct page *page, | ||
2532 | struct writeback_control *wbc, | ||
2533 | unsigned int len) | ||
2534 | { | ||
2535 | struct address_space *mapping = page->mapping; | ||
2536 | struct inode *inode = mapping->host; | ||
2537 | struct buffer_head *page_bufs; | ||
2538 | handle_t *handle = NULL; | ||
2539 | int ret = 0; | ||
2540 | int err; | ||
2541 | |||
2542 | page_bufs = page_buffers(page); | ||
2543 | BUG_ON(!page_bufs); | ||
2544 | walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one); | ||
2545 | /* As soon as we unlock the page, it can go away, but we have | ||
2546 | * references to buffers so we are safe */ | ||
2547 | unlock_page(page); | ||
2548 | |||
2549 | handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); | ||
2550 | if (IS_ERR(handle)) { | ||
2551 | ret = PTR_ERR(handle); | ||
2552 | goto out; | ||
2553 | } | ||
2554 | |||
2555 | ret = walk_page_buffers(handle, page_bufs, 0, len, NULL, | ||
2556 | do_journal_get_write_access); | ||
2557 | |||
2558 | err = walk_page_buffers(handle, page_bufs, 0, len, NULL, | ||
2559 | write_end_fn); | ||
2560 | if (ret == 0) | ||
2561 | ret = err; | ||
2562 | err = ext4_journal_stop(handle); | ||
2563 | if (!ret) | ||
2564 | ret = err; | ||
2565 | |||
2566 | walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one); | ||
2567 | EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; | ||
2568 | out: | ||
2569 | return ret; | ||
2570 | } | ||
2571 | |||
2528 | /* | 2572 | /* |
2573 | * Note that we don't need to start a transaction unless we're journaling data | ||
2574 | * because we should have holes filled from ext4_page_mkwrite(). We even don't | ||
2575 | * need to file the inode to the transaction's list in ordered mode because if | ||
2576 | * we are writing back data added by write(), the inode is already there and if | ||
2577 | * we are writing back data modified via mmap(), noone guarantees in which | ||
2578 | * transaction the data will hit the disk. In case we are journaling data, we | ||
2579 | * cannot start transaction directly because transaction start ranks above page | ||
2580 | * lock so we have to do some magic. | ||
2581 | * | ||
2529 | * This function can get called via... | 2582 | * This function can get called via... |
2530 | * - ext4_da_writepages after taking page lock (have journal handle) | 2583 | * - ext4_da_writepages after taking page lock (have journal handle) |
2531 | * - journal_submit_inode_data_buffers (no journal handle) | 2584 | * - journal_submit_inode_data_buffers (no journal handle) |
2532 | * - shrink_page_list via pdflush (no journal handle) | 2585 | * - shrink_page_list via pdflush (no journal handle) |
2533 | * - grab_page_cache when doing write_begin (have journal handle) | 2586 | * - grab_page_cache when doing write_begin (have journal handle) |
2587 | * | ||
2588 | * We don't do any block allocation in this function. If we have page with | ||
2589 | * multiple blocks we need to write those buffer_heads that are mapped. This | ||
2590 | * is important for mmaped based write. So if we do with blocksize 1K | ||
2591 | * truncate(f, 1024); | ||
2592 | * a = mmap(f, 0, 4096); | ||
2593 | * a[0] = 'a'; | ||
2594 | * truncate(f, 4096); | ||
2595 | * we have in the page first buffer_head mapped via page_mkwrite call back | ||
2596 | * but other bufer_heads would be unmapped but dirty(dirty done via the | ||
2597 | * do_wp_page). So writepage should write the first block. If we modify | ||
2598 | * the mmap area beyond 1024 we will again get a page_fault and the | ||
2599 | * page_mkwrite callback will do the block allocation and mark the | ||
2600 | * buffer_heads mapped. | ||
2601 | * | ||
2602 | * We redirty the page if we have any buffer_heads that is either delay or | ||
2603 | * unwritten in the page. | ||
2604 | * | ||
2605 | * We can get recursively called as show below. | ||
2606 | * | ||
2607 | * ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() -> | ||
2608 | * ext4_writepage() | ||
2609 | * | ||
2610 | * But since we don't do any block allocation we should not deadlock. | ||
2611 | * Page also have the dirty flag cleared so we don't get recurive page_lock. | ||
2534 | */ | 2612 | */ |
2535 | static int ext4_da_writepage(struct page *page, | 2613 | static int ext4_writepage(struct page *page, |
2536 | struct writeback_control *wbc) | 2614 | struct writeback_control *wbc) |
2537 | { | 2615 | { |
2538 | int ret = 0; | 2616 | int ret = 0; |
2539 | loff_t size; | 2617 | loff_t size; |
@@ -2541,7 +2619,7 @@ static int ext4_da_writepage(struct page *page, | |||
2541 | struct buffer_head *page_bufs; | 2619 | struct buffer_head *page_bufs; |
2542 | struct inode *inode = page->mapping->host; | 2620 | struct inode *inode = page->mapping->host; |
2543 | 2621 | ||
2544 | trace_ext4_da_writepage(inode, page); | 2622 | trace_ext4_writepage(inode, page); |
2545 | size = i_size_read(inode); | 2623 | size = i_size_read(inode); |
2546 | if (page->index == size >> PAGE_CACHE_SHIFT) | 2624 | if (page->index == size >> PAGE_CACHE_SHIFT) |
2547 | len = size & ~PAGE_CACHE_MASK; | 2625 | len = size & ~PAGE_CACHE_MASK; |
@@ -2551,7 +2629,7 @@ static int ext4_da_writepage(struct page *page, | |||
2551 | if (page_has_buffers(page)) { | 2629 | if (page_has_buffers(page)) { |
2552 | page_bufs = page_buffers(page); | 2630 | page_bufs = page_buffers(page); |
2553 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, | 2631 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, |
2554 | ext4_bh_unmapped_or_delay)) { | 2632 | ext4_bh_delay_or_unwritten)) { |
2555 | /* | 2633 | /* |
2556 | * We don't want to do block allocation | 2634 | * We don't want to do block allocation |
2557 | * So redirty the page and return | 2635 | * So redirty the page and return |
@@ -2578,13 +2656,13 @@ static int ext4_da_writepage(struct page *page, | |||
2578 | * all are mapped and non delay. We don't want to | 2656 | * all are mapped and non delay. We don't want to |
2579 | * do block allocation here. | 2657 | * do block allocation here. |
2580 | */ | 2658 | */ |
2581 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, | 2659 | ret = block_prepare_write(page, 0, len, |
2582 | noalloc_get_block_write); | 2660 | noalloc_get_block_write); |
2583 | if (!ret) { | 2661 | if (!ret) { |
2584 | page_bufs = page_buffers(page); | 2662 | page_bufs = page_buffers(page); |
2585 | /* check whether all are mapped and non delay */ | 2663 | /* check whether all are mapped and non delay */ |
2586 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, | 2664 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, |
2587 | ext4_bh_unmapped_or_delay)) { | 2665 | ext4_bh_delay_or_unwritten)) { |
2588 | redirty_page_for_writepage(wbc, page); | 2666 | redirty_page_for_writepage(wbc, page); |
2589 | unlock_page(page); | 2667 | unlock_page(page); |
2590 | return 0; | 2668 | return 0; |
@@ -2600,7 +2678,16 @@ static int ext4_da_writepage(struct page *page, | |||
2600 | return 0; | 2678 | return 0; |
2601 | } | 2679 | } |
2602 | /* now mark the buffer_heads as dirty and uptodate */ | 2680 | /* now mark the buffer_heads as dirty and uptodate */ |
2603 | block_commit_write(page, 0, PAGE_CACHE_SIZE); | 2681 | block_commit_write(page, 0, len); |
2682 | } | ||
2683 | |||
2684 | if (PageChecked(page) && ext4_should_journal_data(inode)) { | ||
2685 | /* | ||
2686 | * It's mmapped pagecache. Add buffers and journal it. There | ||
2687 | * doesn't seem much point in redirtying the page here. | ||
2688 | */ | ||
2689 | ClearPageChecked(page); | ||
2690 | return __ext4_journalled_writepage(page, wbc, len); | ||
2604 | } | 2691 | } |
2605 | 2692 | ||
2606 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) | 2693 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) |
@@ -2907,7 +2994,7 @@ retry: | |||
2907 | * i_size_read because we hold i_mutex. | 2994 | * i_size_read because we hold i_mutex. |
2908 | */ | 2995 | */ |
2909 | if (pos + len > inode->i_size) | 2996 | if (pos + len > inode->i_size) |
2910 | vmtruncate(inode, inode->i_size); | 2997 | ext4_truncate(inode); |
2911 | } | 2998 | } |
2912 | 2999 | ||
2913 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 3000 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
@@ -3130,222 +3217,6 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) | |||
3130 | return generic_block_bmap(mapping, block, ext4_get_block); | 3217 | return generic_block_bmap(mapping, block, ext4_get_block); |
3131 | } | 3218 | } |
3132 | 3219 | ||
3133 | static int bget_one(handle_t *handle, struct buffer_head *bh) | ||
3134 | { | ||
3135 | get_bh(bh); | ||
3136 | return 0; | ||
3137 | } | ||
3138 | |||
3139 | static int bput_one(handle_t *handle, struct buffer_head *bh) | ||
3140 | { | ||
3141 | put_bh(bh); | ||
3142 | return 0; | ||
3143 | } | ||
3144 | |||
3145 | /* | ||
3146 | * Note that we don't need to start a transaction unless we're journaling data | ||
3147 | * because we should have holes filled from ext4_page_mkwrite(). We even don't | ||
3148 | * need to file the inode to the transaction's list in ordered mode because if | ||
3149 | * we are writing back data added by write(), the inode is already there and if | ||
3150 | * we are writing back data modified via mmap(), noone guarantees in which | ||
3151 | * transaction the data will hit the disk. In case we are journaling data, we | ||
3152 | * cannot start transaction directly because transaction start ranks above page | ||
3153 | * lock so we have to do some magic. | ||
3154 | * | ||
3155 | * In all journaling modes block_write_full_page() will start the I/O. | ||
3156 | * | ||
3157 | * Problem: | ||
3158 | * | ||
3159 | * ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() -> | ||
3160 | * ext4_writepage() | ||
3161 | * | ||
3162 | * Similar for: | ||
3163 | * | ||
3164 | * ext4_file_write() -> generic_file_write() -> __alloc_pages() -> ... | ||
3165 | * | ||
3166 | * Same applies to ext4_get_block(). We will deadlock on various things like | ||
3167 | * lock_journal and i_data_sem | ||
3168 | * | ||
3169 | * Setting PF_MEMALLOC here doesn't work - too many internal memory | ||
3170 | * allocations fail. | ||
3171 | * | ||
3172 | * 16May01: If we're reentered then journal_current_handle() will be | ||
3173 | * non-zero. We simply *return*. | ||
3174 | * | ||
3175 | * 1 July 2001: @@@ FIXME: | ||
3176 | * In journalled data mode, a data buffer may be metadata against the | ||
3177 | * current transaction. But the same file is part of a shared mapping | ||
3178 | * and someone does a writepage() on it. | ||
3179 | * | ||
3180 | * We will move the buffer onto the async_data list, but *after* it has | ||
3181 | * been dirtied. So there's a small window where we have dirty data on | ||
3182 | * BJ_Metadata. | ||
3183 | * | ||
3184 | * Note that this only applies to the last partial page in the file. The | ||
3185 | * bit which block_write_full_page() uses prepare/commit for. (That's | ||
3186 | * broken code anyway: it's wrong for msync()). | ||
3187 | * | ||
3188 | * It's a rare case: affects the final partial page, for journalled data | ||
3189 | * where the file is subject to bith write() and writepage() in the same | ||
3190 | * transction. To fix it we'll need a custom block_write_full_page(). | ||
3191 | * We'll probably need that anyway for journalling writepage() output. | ||
3192 | * | ||
3193 | * We don't honour synchronous mounts for writepage(). That would be | ||
3194 | * disastrous. Any write() or metadata operation will sync the fs for | ||
3195 | * us. | ||
3196 | * | ||
3197 | */ | ||
3198 | static int __ext4_normal_writepage(struct page *page, | ||
3199 | struct writeback_control *wbc) | ||
3200 | { | ||
3201 | struct inode *inode = page->mapping->host; | ||
3202 | |||
3203 | if (test_opt(inode->i_sb, NOBH)) | ||
3204 | return nobh_writepage(page, noalloc_get_block_write, wbc); | ||
3205 | else | ||
3206 | return block_write_full_page(page, noalloc_get_block_write, | ||
3207 | wbc); | ||
3208 | } | ||
3209 | |||
3210 | static int ext4_normal_writepage(struct page *page, | ||
3211 | struct writeback_control *wbc) | ||
3212 | { | ||
3213 | struct inode *inode = page->mapping->host; | ||
3214 | loff_t size = i_size_read(inode); | ||
3215 | loff_t len; | ||
3216 | |||
3217 | trace_ext4_normal_writepage(inode, page); | ||
3218 | J_ASSERT(PageLocked(page)); | ||
3219 | if (page->index == size >> PAGE_CACHE_SHIFT) | ||
3220 | len = size & ~PAGE_CACHE_MASK; | ||
3221 | else | ||
3222 | len = PAGE_CACHE_SIZE; | ||
3223 | |||
3224 | if (page_has_buffers(page)) { | ||
3225 | /* if page has buffers it should all be mapped | ||
3226 | * and allocated. If there are not buffers attached | ||
3227 | * to the page we know the page is dirty but it lost | ||
3228 | * buffers. That means that at some moment in time | ||
3229 | * after write_begin() / write_end() has been called | ||
3230 | * all buffers have been clean and thus they must have been | ||
3231 | * written at least once. So they are all mapped and we can | ||
3232 | * happily proceed with mapping them and writing the page. | ||
3233 | */ | ||
3234 | BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, | ||
3235 | ext4_bh_unmapped_or_delay)); | ||
3236 | } | ||
3237 | |||
3238 | if (!ext4_journal_current_handle()) | ||
3239 | return __ext4_normal_writepage(page, wbc); | ||
3240 | |||
3241 | redirty_page_for_writepage(wbc, page); | ||
3242 | unlock_page(page); | ||
3243 | return 0; | ||
3244 | } | ||
3245 | |||
3246 | static int __ext4_journalled_writepage(struct page *page, | ||
3247 | struct writeback_control *wbc) | ||
3248 | { | ||
3249 | struct address_space *mapping = page->mapping; | ||
3250 | struct inode *inode = mapping->host; | ||
3251 | struct buffer_head *page_bufs; | ||
3252 | handle_t *handle = NULL; | ||
3253 | int ret = 0; | ||
3254 | int err; | ||
3255 | |||
3256 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, | ||
3257 | noalloc_get_block_write); | ||
3258 | if (ret != 0) | ||
3259 | goto out_unlock; | ||
3260 | |||
3261 | page_bufs = page_buffers(page); | ||
3262 | walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL, | ||
3263 | bget_one); | ||
3264 | /* As soon as we unlock the page, it can go away, but we have | ||
3265 | * references to buffers so we are safe */ | ||
3266 | unlock_page(page); | ||
3267 | |||
3268 | handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); | ||
3269 | if (IS_ERR(handle)) { | ||
3270 | ret = PTR_ERR(handle); | ||
3271 | goto out; | ||
3272 | } | ||
3273 | |||
3274 | ret = walk_page_buffers(handle, page_bufs, 0, | ||
3275 | PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); | ||
3276 | |||
3277 | err = walk_page_buffers(handle, page_bufs, 0, | ||
3278 | PAGE_CACHE_SIZE, NULL, write_end_fn); | ||
3279 | if (ret == 0) | ||
3280 | ret = err; | ||
3281 | err = ext4_journal_stop(handle); | ||
3282 | if (!ret) | ||
3283 | ret = err; | ||
3284 | |||
3285 | walk_page_buffers(handle, page_bufs, 0, | ||
3286 | PAGE_CACHE_SIZE, NULL, bput_one); | ||
3287 | EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; | ||
3288 | goto out; | ||
3289 | |||
3290 | out_unlock: | ||
3291 | unlock_page(page); | ||
3292 | out: | ||
3293 | return ret; | ||
3294 | } | ||
3295 | |||
3296 | static int ext4_journalled_writepage(struct page *page, | ||
3297 | struct writeback_control *wbc) | ||
3298 | { | ||
3299 | struct inode *inode = page->mapping->host; | ||
3300 | loff_t size = i_size_read(inode); | ||
3301 | loff_t len; | ||
3302 | |||
3303 | trace_ext4_journalled_writepage(inode, page); | ||
3304 | J_ASSERT(PageLocked(page)); | ||
3305 | if (page->index == size >> PAGE_CACHE_SHIFT) | ||
3306 | len = size & ~PAGE_CACHE_MASK; | ||
3307 | else | ||
3308 | len = PAGE_CACHE_SIZE; | ||
3309 | |||
3310 | if (page_has_buffers(page)) { | ||
3311 | /* if page has buffers it should all be mapped | ||
3312 | * and allocated. If there are not buffers attached | ||
3313 | * to the page we know the page is dirty but it lost | ||
3314 | * buffers. That means that at some moment in time | ||
3315 | * after write_begin() / write_end() has been called | ||
3316 | * all buffers have been clean and thus they must have been | ||
3317 | * written at least once. So they are all mapped and we can | ||
3318 | * happily proceed with mapping them and writing the page. | ||
3319 | */ | ||
3320 | BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, | ||
3321 | ext4_bh_unmapped_or_delay)); | ||
3322 | } | ||
3323 | |||
3324 | if (ext4_journal_current_handle()) | ||
3325 | goto no_write; | ||
3326 | |||
3327 | if (PageChecked(page)) { | ||
3328 | /* | ||
3329 | * It's mmapped pagecache. Add buffers and journal it. There | ||
3330 | * doesn't seem much point in redirtying the page here. | ||
3331 | */ | ||
3332 | ClearPageChecked(page); | ||
3333 | return __ext4_journalled_writepage(page, wbc); | ||
3334 | } else { | ||
3335 | /* | ||
3336 | * It may be a page full of checkpoint-mode buffers. We don't | ||
3337 | * really know unless we go poke around in the buffer_heads. | ||
3338 | * But block_write_full_page will do the right thing. | ||
3339 | */ | ||
3340 | return block_write_full_page(page, noalloc_get_block_write, | ||
3341 | wbc); | ||
3342 | } | ||
3343 | no_write: | ||
3344 | redirty_page_for_writepage(wbc, page); | ||
3345 | unlock_page(page); | ||
3346 | return 0; | ||
3347 | } | ||
3348 | |||
3349 | static int ext4_readpage(struct file *file, struct page *page) | 3220 | static int ext4_readpage(struct file *file, struct page *page) |
3350 | { | 3221 | { |
3351 | return mpage_readpage(page, ext4_get_block); | 3222 | return mpage_readpage(page, ext4_get_block); |
@@ -3492,7 +3363,7 @@ static int ext4_journalled_set_page_dirty(struct page *page) | |||
3492 | static const struct address_space_operations ext4_ordered_aops = { | 3363 | static const struct address_space_operations ext4_ordered_aops = { |
3493 | .readpage = ext4_readpage, | 3364 | .readpage = ext4_readpage, |
3494 | .readpages = ext4_readpages, | 3365 | .readpages = ext4_readpages, |
3495 | .writepage = ext4_normal_writepage, | 3366 | .writepage = ext4_writepage, |
3496 | .sync_page = block_sync_page, | 3367 | .sync_page = block_sync_page, |
3497 | .write_begin = ext4_write_begin, | 3368 | .write_begin = ext4_write_begin, |
3498 | .write_end = ext4_ordered_write_end, | 3369 | .write_end = ext4_ordered_write_end, |
@@ -3507,7 +3378,7 @@ static const struct address_space_operations ext4_ordered_aops = { | |||
3507 | static const struct address_space_operations ext4_writeback_aops = { | 3378 | static const struct address_space_operations ext4_writeback_aops = { |
3508 | .readpage = ext4_readpage, | 3379 | .readpage = ext4_readpage, |
3509 | .readpages = ext4_readpages, | 3380 | .readpages = ext4_readpages, |
3510 | .writepage = ext4_normal_writepage, | 3381 | .writepage = ext4_writepage, |
3511 | .sync_page = block_sync_page, | 3382 | .sync_page = block_sync_page, |
3512 | .write_begin = ext4_write_begin, | 3383 | .write_begin = ext4_write_begin, |
3513 | .write_end = ext4_writeback_write_end, | 3384 | .write_end = ext4_writeback_write_end, |
@@ -3522,7 +3393,7 @@ static const struct address_space_operations ext4_writeback_aops = { | |||
3522 | static const struct address_space_operations ext4_journalled_aops = { | 3393 | static const struct address_space_operations ext4_journalled_aops = { |
3523 | .readpage = ext4_readpage, | 3394 | .readpage = ext4_readpage, |
3524 | .readpages = ext4_readpages, | 3395 | .readpages = ext4_readpages, |
3525 | .writepage = ext4_journalled_writepage, | 3396 | .writepage = ext4_writepage, |
3526 | .sync_page = block_sync_page, | 3397 | .sync_page = block_sync_page, |
3527 | .write_begin = ext4_write_begin, | 3398 | .write_begin = ext4_write_begin, |
3528 | .write_end = ext4_journalled_write_end, | 3399 | .write_end = ext4_journalled_write_end, |
@@ -3536,7 +3407,7 @@ static const struct address_space_operations ext4_journalled_aops = { | |||
3536 | static const struct address_space_operations ext4_da_aops = { | 3407 | static const struct address_space_operations ext4_da_aops = { |
3537 | .readpage = ext4_readpage, | 3408 | .readpage = ext4_readpage, |
3538 | .readpages = ext4_readpages, | 3409 | .readpages = ext4_readpages, |
3539 | .writepage = ext4_da_writepage, | 3410 | .writepage = ext4_writepage, |
3540 | .writepages = ext4_da_writepages, | 3411 | .writepages = ext4_da_writepages, |
3541 | .sync_page = block_sync_page, | 3412 | .sync_page = block_sync_page, |
3542 | .write_begin = ext4_da_write_begin, | 3413 | .write_begin = ext4_da_write_begin, |
@@ -3583,7 +3454,8 @@ int ext4_block_truncate_page(handle_t *handle, | |||
3583 | struct page *page; | 3454 | struct page *page; |
3584 | int err = 0; | 3455 | int err = 0; |
3585 | 3456 | ||
3586 | page = grab_cache_page(mapping, from >> PAGE_CACHE_SHIFT); | 3457 | page = find_or_create_page(mapping, from >> PAGE_CACHE_SHIFT, |
3458 | mapping_gfp_mask(mapping) & ~__GFP_FS); | ||
3587 | if (!page) | 3459 | if (!page) |
3588 | return -EINVAL; | 3460 | return -EINVAL; |
3589 | 3461 | ||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index bb415408fdb6..7050a9cd04a4 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/mount.h> | 15 | #include <linux/mount.h> |
17 | #include <linux/file.h> | 16 | #include <linux/file.h> |
18 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
@@ -192,7 +191,7 @@ setversion_out: | |||
192 | case EXT4_IOC_GROUP_EXTEND: { | 191 | case EXT4_IOC_GROUP_EXTEND: { |
193 | ext4_fsblk_t n_blocks_count; | 192 | ext4_fsblk_t n_blocks_count; |
194 | struct super_block *sb = inode->i_sb; | 193 | struct super_block *sb = inode->i_sb; |
195 | int err, err2; | 194 | int err, err2=0; |
196 | 195 | ||
197 | if (!capable(CAP_SYS_RESOURCE)) | 196 | if (!capable(CAP_SYS_RESOURCE)) |
198 | return -EPERM; | 197 | return -EPERM; |
@@ -205,9 +204,11 @@ setversion_out: | |||
205 | return err; | 204 | return err; |
206 | 205 | ||
207 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); | 206 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); |
208 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 207 | if (EXT4_SB(sb)->s_journal) { |
209 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 208 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
210 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 209 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
210 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
211 | } | ||
211 | if (err == 0) | 212 | if (err == 0) |
212 | err = err2; | 213 | err = err2; |
213 | mnt_drop_write(filp->f_path.mnt); | 214 | mnt_drop_write(filp->f_path.mnt); |
@@ -252,7 +253,7 @@ setversion_out: | |||
252 | case EXT4_IOC_GROUP_ADD: { | 253 | case EXT4_IOC_GROUP_ADD: { |
253 | struct ext4_new_group_data input; | 254 | struct ext4_new_group_data input; |
254 | struct super_block *sb = inode->i_sb; | 255 | struct super_block *sb = inode->i_sb; |
255 | int err, err2; | 256 | int err, err2=0; |
256 | 257 | ||
257 | if (!capable(CAP_SYS_RESOURCE)) | 258 | if (!capable(CAP_SYS_RESOURCE)) |
258 | return -EPERM; | 259 | return -EPERM; |
@@ -266,9 +267,11 @@ setversion_out: | |||
266 | return err; | 267 | return err; |
267 | 268 | ||
268 | err = ext4_group_add(sb, &input); | 269 | err = ext4_group_add(sb, &input); |
269 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 270 | if (EXT4_SB(sb)->s_journal) { |
270 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 271 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
271 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 272 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
273 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
274 | } | ||
272 | if (err == 0) | 275 | if (err == 0) |
273 | err = err2; | 276 | err = err2; |
274 | mnt_drop_write(filp->f_path.mnt); | 277 | mnt_drop_write(filp->f_path.mnt); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 519a0a686d94..cd258463e2a9 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -657,7 +657,8 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, | |||
657 | } | 657 | } |
658 | } | 658 | } |
659 | 659 | ||
660 | static void ext4_mb_generate_buddy(struct super_block *sb, | 660 | static noinline_for_stack |
661 | void ext4_mb_generate_buddy(struct super_block *sb, | ||
661 | void *buddy, void *bitmap, ext4_group_t group) | 662 | void *buddy, void *bitmap, ext4_group_t group) |
662 | { | 663 | { |
663 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); | 664 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); |
@@ -1480,7 +1481,8 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac, | |||
1480 | ext4_mb_check_limits(ac, e4b, 0); | 1481 | ext4_mb_check_limits(ac, e4b, 0); |
1481 | } | 1482 | } |
1482 | 1483 | ||
1483 | static int ext4_mb_try_best_found(struct ext4_allocation_context *ac, | 1484 | static noinline_for_stack |
1485 | int ext4_mb_try_best_found(struct ext4_allocation_context *ac, | ||
1484 | struct ext4_buddy *e4b) | 1486 | struct ext4_buddy *e4b) |
1485 | { | 1487 | { |
1486 | struct ext4_free_extent ex = ac->ac_b_ex; | 1488 | struct ext4_free_extent ex = ac->ac_b_ex; |
@@ -1507,7 +1509,8 @@ static int ext4_mb_try_best_found(struct ext4_allocation_context *ac, | |||
1507 | return 0; | 1509 | return 0; |
1508 | } | 1510 | } |
1509 | 1511 | ||
1510 | static int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, | 1512 | static noinline_for_stack |
1513 | int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, | ||
1511 | struct ext4_buddy *e4b) | 1514 | struct ext4_buddy *e4b) |
1512 | { | 1515 | { |
1513 | ext4_group_t group = ac->ac_g_ex.fe_group; | 1516 | ext4_group_t group = ac->ac_g_ex.fe_group; |
@@ -1566,7 +1569,8 @@ static int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, | |||
1566 | * The routine scans buddy structures (not bitmap!) from given order | 1569 | * The routine scans buddy structures (not bitmap!) from given order |
1567 | * to max order and tries to find big enough chunk to satisfy the req | 1570 | * to max order and tries to find big enough chunk to satisfy the req |
1568 | */ | 1571 | */ |
1569 | static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | 1572 | static noinline_for_stack |
1573 | void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | ||
1570 | struct ext4_buddy *e4b) | 1574 | struct ext4_buddy *e4b) |
1571 | { | 1575 | { |
1572 | struct super_block *sb = ac->ac_sb; | 1576 | struct super_block *sb = ac->ac_sb; |
@@ -1609,7 +1613,8 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | |||
1609 | * In order to optimize scanning, caller must pass number of | 1613 | * In order to optimize scanning, caller must pass number of |
1610 | * free blocks in the group, so the routine can know upper limit. | 1614 | * free blocks in the group, so the routine can know upper limit. |
1611 | */ | 1615 | */ |
1612 | static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | 1616 | static noinline_for_stack |
1617 | void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | ||
1613 | struct ext4_buddy *e4b) | 1618 | struct ext4_buddy *e4b) |
1614 | { | 1619 | { |
1615 | struct super_block *sb = ac->ac_sb; | 1620 | struct super_block *sb = ac->ac_sb; |
@@ -1668,7 +1673,8 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
1668 | * we try to find stripe-aligned chunks for stripe-size requests | 1673 | * we try to find stripe-aligned chunks for stripe-size requests |
1669 | * XXX should do so at least for multiples of stripe size as well | 1674 | * XXX should do so at least for multiples of stripe size as well |
1670 | */ | 1675 | */ |
1671 | static void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, | 1676 | static noinline_for_stack |
1677 | void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, | ||
1672 | struct ext4_buddy *e4b) | 1678 | struct ext4_buddy *e4b) |
1673 | { | 1679 | { |
1674 | struct super_block *sb = ac->ac_sb; | 1680 | struct super_block *sb = ac->ac_sb; |
@@ -1831,7 +1837,8 @@ void ext4_mb_put_buddy_cache_lock(struct super_block *sb, | |||
1831 | 1837 | ||
1832 | } | 1838 | } |
1833 | 1839 | ||
1834 | static int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) | 1840 | static noinline_for_stack |
1841 | int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) | ||
1835 | { | 1842 | { |
1836 | 1843 | ||
1837 | int ret; | 1844 | int ret; |
@@ -2902,7 +2909,11 @@ int __init init_ext4_mballoc(void) | |||
2902 | 2909 | ||
2903 | void exit_ext4_mballoc(void) | 2910 | void exit_ext4_mballoc(void) |
2904 | { | 2911 | { |
2905 | /* XXX: synchronize_rcu(); */ | 2912 | /* |
2913 | * Wait for completion of call_rcu()'s on ext4_pspace_cachep | ||
2914 | * before destroying the slab cache. | ||
2915 | */ | ||
2916 | rcu_barrier(); | ||
2906 | kmem_cache_destroy(ext4_pspace_cachep); | 2917 | kmem_cache_destroy(ext4_pspace_cachep); |
2907 | kmem_cache_destroy(ext4_ac_cachep); | 2918 | kmem_cache_destroy(ext4_ac_cachep); |
2908 | kmem_cache_destroy(ext4_free_ext_cachep); | 2919 | kmem_cache_destroy(ext4_free_ext_cachep); |
@@ -3457,7 +3468,8 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, | |||
3457 | * used in in-core bitmap. buddy must be generated from this bitmap | 3468 | * used in in-core bitmap. buddy must be generated from this bitmap |
3458 | * Need to be called with ext4 group lock held | 3469 | * Need to be called with ext4 group lock held |
3459 | */ | 3470 | */ |
3460 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | 3471 | static noinline_for_stack |
3472 | void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | ||
3461 | ext4_group_t group) | 3473 | ext4_group_t group) |
3462 | { | 3474 | { |
3463 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); | 3475 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); |
@@ -4215,14 +4227,9 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac, | |||
4215 | ext4_get_group_no_and_offset(sb, goal, &group, &block); | 4227 | ext4_get_group_no_and_offset(sb, goal, &group, &block); |
4216 | 4228 | ||
4217 | /* set up allocation goals */ | 4229 | /* set up allocation goals */ |
4230 | memset(ac, 0, sizeof(struct ext4_allocation_context)); | ||
4218 | ac->ac_b_ex.fe_logical = ar->logical; | 4231 | ac->ac_b_ex.fe_logical = ar->logical; |
4219 | ac->ac_b_ex.fe_group = 0; | ||
4220 | ac->ac_b_ex.fe_start = 0; | ||
4221 | ac->ac_b_ex.fe_len = 0; | ||
4222 | ac->ac_status = AC_STATUS_CONTINUE; | 4232 | ac->ac_status = AC_STATUS_CONTINUE; |
4223 | ac->ac_groups_scanned = 0; | ||
4224 | ac->ac_ex_scanned = 0; | ||
4225 | ac->ac_found = 0; | ||
4226 | ac->ac_sb = sb; | 4233 | ac->ac_sb = sb; |
4227 | ac->ac_inode = ar->inode; | 4234 | ac->ac_inode = ar->inode; |
4228 | ac->ac_o_ex.fe_logical = ar->logical; | 4235 | ac->ac_o_ex.fe_logical = ar->logical; |
@@ -4233,15 +4240,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac, | |||
4233 | ac->ac_g_ex.fe_group = group; | 4240 | ac->ac_g_ex.fe_group = group; |
4234 | ac->ac_g_ex.fe_start = block; | 4241 | ac->ac_g_ex.fe_start = block; |
4235 | ac->ac_g_ex.fe_len = len; | 4242 | ac->ac_g_ex.fe_len = len; |
4236 | ac->ac_f_ex.fe_len = 0; | ||
4237 | ac->ac_flags = ar->flags; | 4243 | ac->ac_flags = ar->flags; |
4238 | ac->ac_2order = 0; | ||
4239 | ac->ac_criteria = 0; | ||
4240 | ac->ac_pa = NULL; | ||
4241 | ac->ac_bitmap_page = NULL; | ||
4242 | ac->ac_buddy_page = NULL; | ||
4243 | ac->alloc_semp = NULL; | ||
4244 | ac->ac_lg = NULL; | ||
4245 | 4244 | ||
4246 | /* we have to define context: we'll we work with a file or | 4245 | /* we have to define context: we'll we work with a file or |
4247 | * locality group. this is a policy, actually */ | 4246 | * locality group. this is a policy, actually */ |
@@ -4509,10 +4508,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
4509 | } | 4508 | } |
4510 | 4509 | ||
4511 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); | 4510 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); |
4512 | if (ac) { | 4511 | if (!ac) { |
4513 | ac->ac_sb = sb; | ||
4514 | ac->ac_inode = ar->inode; | ||
4515 | } else { | ||
4516 | ar->len = 0; | 4512 | ar->len = 0; |
4517 | *errp = -ENOMEM; | 4513 | *errp = -ENOMEM; |
4518 | goto out1; | 4514 | goto out1; |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 38ff75a0fe22..530b4ca01510 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/time.h> | 18 | #include <linux/time.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
21 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
22 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 82f88733b681..bbc94ae4fd77 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/time.h> | 10 | #include <linux/time.h> |
11 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
12 | #include <linux/smp_lock.h> | ||
13 | #include "fat.h" | 12 | #include "fat.h" |
14 | 13 | ||
15 | /* Characters that are undesirable in an MS-DOS file name */ | 14 | /* Characters that are undesirable in an MS-DOS file name */ |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 73471b7ecc8c..cb6e83557112 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/buffer_head.h> | 22 | #include <linux/buffer_head.h> |
24 | #include <linux/namei.h> | 23 | #include <linux/namei.h> |
25 | #include "fat.h" | 24 | #include "fat.h" |
diff --git a/fs/fcntl.c b/fs/fcntl.c index a040b764f8e3..ae413086db97 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/signal.h> | 19 | #include <linux/signal.h> |
20 | #include <linux/rcupdate.h> | 20 | #include <linux/rcupdate.h> |
21 | #include <linux/pid_namespace.h> | 21 | #include <linux/pid_namespace.h> |
22 | #include <linux/smp_lock.h> | ||
23 | 22 | ||
24 | #include <asm/poll.h> | 23 | #include <asm/poll.h> |
25 | #include <asm/siginfo.h> | 24 | #include <asm/siginfo.h> |
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index cdbd1654e4cd..1e8af939b3e4 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/buffer_head.h> | 38 | #include <linux/buffer_head.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include <linux/smp_lock.h> | ||
41 | #include <linux/stat.h> | 42 | #include <linux/stat.h> |
42 | #include <linux/vfs.h> | 43 | #include <linux/vfs.h> |
43 | #include <linux/mount.h> | 44 | #include <linux/mount.h> |
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index 98d6ef1c1dc0..148d55c14171 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h | |||
@@ -1,12 +1,11 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM gfs2 | ||
3 | |||
1 | #if !defined(_TRACE_GFS2_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_GFS2_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_GFS2_H | 5 | #define _TRACE_GFS2_H |
3 | 6 | ||
4 | #include <linux/tracepoint.h> | 7 | #include <linux/tracepoint.h> |
5 | 8 | ||
6 | #undef TRACE_SYSTEM | ||
7 | #define TRACE_SYSTEM gfs2 | ||
8 | #define TRACE_INCLUDE_FILE trace_gfs2 | ||
9 | |||
10 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
11 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
12 | #include <linux/dlmconstants.h> | 11 | #include <linux/dlmconstants.h> |
@@ -403,5 +402,6 @@ TRACE_EVENT(gfs2_block_alloc, | |||
403 | /* This part must be outside protection */ | 402 | /* This part must be outside protection */ |
404 | #undef TRACE_INCLUDE_PATH | 403 | #undef TRACE_INCLUDE_PATH |
405 | #define TRACE_INCLUDE_PATH . | 404 | #define TRACE_INCLUDE_PATH . |
405 | #define TRACE_INCLUDE_FILE trace_gfs2 | ||
406 | #include <trace/define_trace.h> | 406 | #include <trace/define_trace.h> |
407 | 407 | ||
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 6f833dc8e910..f7fcbe49da72 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/nls.h> | 19 | #include <linux/nls.h> |
20 | #include <linux/parser.h> | 20 | #include <linux/parser.h> |
21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
22 | #include <linux/smp_lock.h> | ||
22 | #include <linux/vfs.h> | 23 | #include <linux/vfs.h> |
23 | 24 | ||
24 | #include "hfs_fs.h" | 25 | #include "hfs_fs.h" |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 9fc3af0c0dab..c0759fe0855b 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/smp_lock.h> | ||
15 | #include <linux/vfs.h> | 16 | #include <linux/vfs.h> |
16 | #include <linux/nls.h> | 17 | #include <linux/nls.h> |
17 | 18 | ||
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index 6916c41d7017..8865c94f55f6 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * directory VFS functions | 6 | * directory VFS functions |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/smp_lock.h> | ||
9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
10 | 11 | ||
11 | static int hpfs_dir_release(struct inode *inode, struct file *filp) | 12 | static int hpfs_dir_release(struct inode *inode, struct file *filp) |
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 64ab52259204..3efabff00367 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * file VFS functions | 6 | * file VFS functions |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/smp_lock.h> | ||
9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
10 | 11 | ||
11 | #define BLOCKS(size) (((size) + 511) >> 9) | 12 | #define BLOCKS(size) (((size) + 511) >> 9) |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index c2ea31bae313..701ca54c0867 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/pagemap.h> | 13 | #include <linux/pagemap.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/smp_lock.h> | ||
17 | 16 | ||
18 | #include "hpfs.h" | 17 | #include "hpfs.h" |
19 | 18 | ||
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 39a1bfbea312..fe703ae46bc7 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * inode VFS functions | 6 | * inode VFS functions |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/smp_lock.h> | ||
9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
10 | 11 | ||
11 | void hpfs_init_inode(struct inode *i) | 12 | void hpfs_init_inode(struct inode *i) |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index b649232dde97..82b9c4ba9ed0 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * adding & removing files & directories | 6 | * adding & removing files & directories |
7 | */ | 7 | */ |
8 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
9 | #include <linux/smp_lock.h> | ||
9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
10 | 11 | ||
11 | static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 12 | static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 58a7963e168a..85f96bc651c7 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -142,6 +142,7 @@ static const struct dentry_operations isofs_dentry_ops[] = { | |||
142 | 142 | ||
143 | struct iso9660_options{ | 143 | struct iso9660_options{ |
144 | unsigned int rock:1; | 144 | unsigned int rock:1; |
145 | unsigned int joliet:1; | ||
145 | unsigned int cruft:1; | 146 | unsigned int cruft:1; |
146 | unsigned int hide:1; | 147 | unsigned int hide:1; |
147 | unsigned int showassoc:1; | 148 | unsigned int showassoc:1; |
@@ -151,7 +152,6 @@ struct iso9660_options{ | |||
151 | unsigned int gid_set:1; | 152 | unsigned int gid_set:1; |
152 | unsigned int utf8:1; | 153 | unsigned int utf8:1; |
153 | unsigned char map; | 154 | unsigned char map; |
154 | char joliet; | ||
155 | unsigned char check; | 155 | unsigned char check; |
156 | unsigned int blocksize; | 156 | unsigned int blocksize; |
157 | mode_t fmode; | 157 | mode_t fmode; |
@@ -632,7 +632,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
632 | else if (isonum_711(vdp->type) == ISO_VD_SUPPLEMENTARY) { | 632 | else if (isonum_711(vdp->type) == ISO_VD_SUPPLEMENTARY) { |
633 | sec = (struct iso_supplementary_descriptor *)vdp; | 633 | sec = (struct iso_supplementary_descriptor *)vdp; |
634 | if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) { | 634 | if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) { |
635 | if (opt.joliet == 'y') { | 635 | if (opt.joliet) { |
636 | if (sec->escape[2] == 0x40) | 636 | if (sec->escape[2] == 0x40) |
637 | joliet_level = 1; | 637 | joliet_level = 1; |
638 | else if (sec->escape[2] == 0x43) | 638 | else if (sec->escape[2] == 0x43) |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 18bfd5dab642..e378cb383979 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -297,6 +297,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
297 | unsigned int new_offset; | 297 | unsigned int new_offset; |
298 | struct buffer_head *bh_in = jh2bh(jh_in); | 298 | struct buffer_head *bh_in = jh2bh(jh_in); |
299 | struct jbd2_buffer_trigger_type *triggers; | 299 | struct jbd2_buffer_trigger_type *triggers; |
300 | journal_t *journal = transaction->t_journal; | ||
300 | 301 | ||
301 | /* | 302 | /* |
302 | * The buffer really shouldn't be locked: only the current committing | 303 | * The buffer really shouldn't be locked: only the current committing |
@@ -310,6 +311,11 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
310 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); | 311 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); |
311 | 312 | ||
312 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); | 313 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); |
314 | /* keep subsequent assertions sane */ | ||
315 | new_bh->b_state = 0; | ||
316 | init_buffer(new_bh, NULL, NULL); | ||
317 | atomic_set(&new_bh->b_count, 1); | ||
318 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ | ||
313 | 319 | ||
314 | /* | 320 | /* |
315 | * If a new transaction has already done a buffer copy-out, then | 321 | * If a new transaction has already done a buffer copy-out, then |
@@ -388,14 +394,6 @@ repeat: | |||
388 | kunmap_atomic(mapped_data, KM_USER0); | 394 | kunmap_atomic(mapped_data, KM_USER0); |
389 | } | 395 | } |
390 | 396 | ||
391 | /* keep subsequent assertions sane */ | ||
392 | new_bh->b_state = 0; | ||
393 | init_buffer(new_bh, NULL, NULL); | ||
394 | atomic_set(&new_bh->b_count, 1); | ||
395 | jbd_unlock_bh_state(bh_in); | ||
396 | |||
397 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ | ||
398 | |||
399 | set_bh_page(new_bh, new_page, new_offset); | 397 | set_bh_page(new_bh, new_page, new_offset); |
400 | new_jh->b_transaction = NULL; | 398 | new_jh->b_transaction = NULL; |
401 | new_bh->b_size = jh2bh(jh_in)->b_size; | 399 | new_bh->b_size = jh2bh(jh_in)->b_size; |
@@ -412,7 +410,11 @@ repeat: | |||
412 | * copying is moved to the transaction's shadow queue. | 410 | * copying is moved to the transaction's shadow queue. |
413 | */ | 411 | */ |
414 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); | 412 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); |
415 | jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); | 413 | spin_lock(&journal->j_list_lock); |
414 | __jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); | ||
415 | spin_unlock(&journal->j_list_lock); | ||
416 | jbd_unlock_bh_state(bh_in); | ||
417 | |||
416 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); | 418 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); |
417 | jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); | 419 | jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); |
418 | 420 | ||
@@ -2410,6 +2412,7 @@ const char *jbd2_dev_to_name(dev_t device) | |||
2410 | int i = hash_32(device, CACHE_SIZE_BITS); | 2412 | int i = hash_32(device, CACHE_SIZE_BITS); |
2411 | char *ret; | 2413 | char *ret; |
2412 | struct block_device *bd; | 2414 | struct block_device *bd; |
2415 | static struct devname_cache *new_dev; | ||
2413 | 2416 | ||
2414 | rcu_read_lock(); | 2417 | rcu_read_lock(); |
2415 | if (devcache[i] && devcache[i]->device == device) { | 2418 | if (devcache[i] && devcache[i]->device == device) { |
@@ -2419,20 +2422,20 @@ const char *jbd2_dev_to_name(dev_t device) | |||
2419 | } | 2422 | } |
2420 | rcu_read_unlock(); | 2423 | rcu_read_unlock(); |
2421 | 2424 | ||
2425 | new_dev = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); | ||
2426 | if (!new_dev) | ||
2427 | return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ | ||
2422 | spin_lock(&devname_cache_lock); | 2428 | spin_lock(&devname_cache_lock); |
2423 | if (devcache[i]) { | 2429 | if (devcache[i]) { |
2424 | if (devcache[i]->device == device) { | 2430 | if (devcache[i]->device == device) { |
2431 | kfree(new_dev); | ||
2425 | ret = devcache[i]->devname; | 2432 | ret = devcache[i]->devname; |
2426 | spin_unlock(&devname_cache_lock); | 2433 | spin_unlock(&devname_cache_lock); |
2427 | return ret; | 2434 | return ret; |
2428 | } | 2435 | } |
2429 | call_rcu(&devcache[i]->rcu, free_devcache); | 2436 | call_rcu(&devcache[i]->rcu, free_devcache); |
2430 | } | 2437 | } |
2431 | devcache[i] = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); | 2438 | devcache[i] = new_dev; |
2432 | if (!devcache[i]) { | ||
2433 | spin_unlock(&devname_cache_lock); | ||
2434 | return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ | ||
2435 | } | ||
2436 | devcache[i]->device = device; | 2439 | devcache[i]->device = device; |
2437 | bd = bdget(device); | 2440 | bd = bdget(device); |
2438 | if (bd) { | 2441 | if (bd) { |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 494501edba6b..6213ac728f30 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -499,34 +499,15 @@ void jbd2_journal_unlock_updates (journal_t *journal) | |||
499 | wake_up(&journal->j_wait_transaction_locked); | 499 | wake_up(&journal->j_wait_transaction_locked); |
500 | } | 500 | } |
501 | 501 | ||
502 | /* | 502 | static void warn_dirty_buffer(struct buffer_head *bh) |
503 | * Report any unexpected dirty buffers which turn up. Normally those | ||
504 | * indicate an error, but they can occur if the user is running (say) | ||
505 | * tune2fs to modify the live filesystem, so we need the option of | ||
506 | * continuing as gracefully as possible. # | ||
507 | * | ||
508 | * The caller should already hold the journal lock and | ||
509 | * j_list_lock spinlock: most callers will need those anyway | ||
510 | * in order to probe the buffer's journaling state safely. | ||
511 | */ | ||
512 | static void jbd_unexpected_dirty_buffer(struct journal_head *jh) | ||
513 | { | 503 | { |
514 | int jlist; | 504 | char b[BDEVNAME_SIZE]; |
515 | |||
516 | /* If this buffer is one which might reasonably be dirty | ||
517 | * --- ie. data, or not part of this journal --- then | ||
518 | * we're OK to leave it alone, but otherwise we need to | ||
519 | * move the dirty bit to the journal's own internal | ||
520 | * JBDDirty bit. */ | ||
521 | jlist = jh->b_jlist; | ||
522 | 505 | ||
523 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | 506 | printk(KERN_WARNING |
524 | jlist == BJ_Shadow || jlist == BJ_Forget) { | 507 | "JBD: Spotted dirty metadata buffer (dev = %s, blocknr = %llu). " |
525 | struct buffer_head *bh = jh2bh(jh); | 508 | "There's a risk of filesystem corruption in case of system " |
526 | 509 | "crash.\n", | |
527 | if (test_clear_buffer_dirty(bh)) | 510 | bdevname(bh->b_bdev, b), (unsigned long long)bh->b_blocknr); |
528 | set_buffer_jbddirty(bh); | ||
529 | } | ||
530 | } | 511 | } |
531 | 512 | ||
532 | /* | 513 | /* |
@@ -593,14 +574,16 @@ repeat: | |||
593 | if (jh->b_next_transaction) | 574 | if (jh->b_next_transaction) |
594 | J_ASSERT_JH(jh, jh->b_next_transaction == | 575 | J_ASSERT_JH(jh, jh->b_next_transaction == |
595 | transaction); | 576 | transaction); |
577 | warn_dirty_buffer(bh); | ||
596 | } | 578 | } |
597 | /* | 579 | /* |
598 | * In any case we need to clean the dirty flag and we must | 580 | * In any case we need to clean the dirty flag and we must |
599 | * do it under the buffer lock to be sure we don't race | 581 | * do it under the buffer lock to be sure we don't race |
600 | * with running write-out. | 582 | * with running write-out. |
601 | */ | 583 | */ |
602 | JBUFFER_TRACE(jh, "Unexpected dirty buffer"); | 584 | JBUFFER_TRACE(jh, "Journalling dirty buffer"); |
603 | jbd_unexpected_dirty_buffer(jh); | 585 | clear_buffer_dirty(bh); |
586 | set_buffer_jbddirty(bh); | ||
604 | } | 587 | } |
605 | 588 | ||
606 | unlock_buffer(bh); | 589 | unlock_buffer(bh); |
@@ -843,6 +826,15 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) | |||
843 | J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); | 826 | J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); |
844 | 827 | ||
845 | if (jh->b_transaction == NULL) { | 828 | if (jh->b_transaction == NULL) { |
829 | /* | ||
830 | * Previous jbd2_journal_forget() could have left the buffer | ||
831 | * with jbddirty bit set because it was being committed. When | ||
832 | * the commit finished, we've filed the buffer for | ||
833 | * checkpointing and marked it dirty. Now we are reallocating | ||
834 | * the buffer so the transaction freeing it must have | ||
835 | * committed and so it's safe to clear the dirty bit. | ||
836 | */ | ||
837 | clear_buffer_dirty(jh2bh(jh)); | ||
846 | jh->b_transaction = transaction; | 838 | jh->b_transaction = transaction; |
847 | 839 | ||
848 | /* first access by this transaction */ | 840 | /* first access by this transaction */ |
@@ -1644,8 +1636,13 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) | |||
1644 | 1636 | ||
1645 | if (jh->b_cp_transaction) { | 1637 | if (jh->b_cp_transaction) { |
1646 | JBUFFER_TRACE(jh, "on running+cp transaction"); | 1638 | JBUFFER_TRACE(jh, "on running+cp transaction"); |
1639 | /* | ||
1640 | * We don't want to write the buffer anymore, clear the | ||
1641 | * bit so that we don't confuse checks in | ||
1642 | * __journal_file_buffer | ||
1643 | */ | ||
1644 | clear_buffer_dirty(bh); | ||
1647 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); | 1645 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); |
1648 | clear_buffer_jbddirty(bh); | ||
1649 | may_free = 0; | 1646 | may_free = 0; |
1650 | } else { | 1647 | } else { |
1651 | JBUFFER_TRACE(jh, "on running transaction"); | 1648 | JBUFFER_TRACE(jh, "on running transaction"); |
@@ -1896,12 +1893,17 @@ void __jbd2_journal_file_buffer(struct journal_head *jh, | |||
1896 | if (jh->b_transaction && jh->b_jlist == jlist) | 1893 | if (jh->b_transaction && jh->b_jlist == jlist) |
1897 | return; | 1894 | return; |
1898 | 1895 | ||
1899 | /* The following list of buffer states needs to be consistent | ||
1900 | * with __jbd_unexpected_dirty_buffer()'s handling of dirty | ||
1901 | * state. */ | ||
1902 | |||
1903 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | 1896 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || |
1904 | jlist == BJ_Shadow || jlist == BJ_Forget) { | 1897 | jlist == BJ_Shadow || jlist == BJ_Forget) { |
1898 | /* | ||
1899 | * For metadata buffers, we track dirty bit in buffer_jbddirty | ||
1900 | * instead of buffer_dirty. We should not see a dirty bit set | ||
1901 | * here because we clear it in do_get_write_access but e.g. | ||
1902 | * tune2fs can modify the sb and set the dirty bit at any time | ||
1903 | * so we try to gracefully handle that. | ||
1904 | */ | ||
1905 | if (buffer_dirty(bh)) | ||
1906 | warn_dirty_buffer(bh); | ||
1905 | if (test_clear_buffer_dirty(bh) || | 1907 | if (test_clear_buffer_dirty(bh) || |
1906 | test_clear_buffer_jbddirty(bh)) | 1908 | test_clear_buffer_jbddirty(bh)) |
1907 | was_dirty = 1; | 1909 | was_dirty = 1; |
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 07a22caf2687..0035c021395a 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/smp_lock.h> | ||
15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
16 | #include <linux/list.h> | 17 | #include <linux/list.h> |
17 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index f2fdcbce143e..4336adba952a 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/smp_lock.h> | ||
10 | #include <linux/types.h> | 11 | #include <linux/types.h> |
11 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 1725037374c5..bd173a6ca3b1 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/smp_lock.h> | ||
13 | #include <linux/in.h> | 14 | #include <linux/in.h> |
14 | #include <linux/sunrpc/svc.h> | 15 | #include <linux/sunrpc/svc.h> |
15 | #include <linux/sunrpc/clnt.h> | 16 | #include <linux/sunrpc/clnt.h> |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 3688e55901fc..e1d28ddd2169 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/smp_lock.h> | ||
13 | #include <linux/in.h> | 14 | #include <linux/in.h> |
14 | #include <linux/sunrpc/svc.h> | 15 | #include <linux/sunrpc/svc.h> |
15 | #include <linux/sunrpc/clnt.h> | 16 | #include <linux/sunrpc/clnt.h> |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index c2d061675d80..8d25ccb2d51d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -1242,20 +1242,6 @@ error: | |||
1242 | return error; | 1242 | return error; |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | /* | ||
1246 | * Initialize a session. | ||
1247 | * Note: save the mount rsize and wsize for create_server negotiation. | ||
1248 | */ | ||
1249 | static void nfs4_init_session(struct nfs_client *clp, | ||
1250 | unsigned int wsize, unsigned int rsize) | ||
1251 | { | ||
1252 | #if defined(CONFIG_NFS_V4_1) | ||
1253 | if (nfs4_has_session(clp)) { | ||
1254 | clp->cl_session->fc_attrs.max_rqst_sz = wsize; | ||
1255 | clp->cl_session->fc_attrs.max_resp_sz = rsize; | ||
1256 | } | ||
1257 | #endif /* CONFIG_NFS_V4_1 */ | ||
1258 | } | ||
1259 | 1245 | ||
1260 | /* | 1246 | /* |
1261 | * Session has been established, and the client marked ready. | 1247 | * Session has been established, and the client marked ready. |
@@ -1350,7 +1336,9 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, | |||
1350 | BUG_ON(!server->nfs_client->rpc_ops); | 1336 | BUG_ON(!server->nfs_client->rpc_ops); |
1351 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | 1337 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); |
1352 | 1338 | ||
1353 | nfs4_init_session(server->nfs_client, server->wsize, server->rsize); | 1339 | error = nfs4_init_session(server); |
1340 | if (error < 0) | ||
1341 | goto error; | ||
1354 | 1342 | ||
1355 | /* Probe the root fh to retrieve its FSID */ | 1343 | /* Probe the root fh to retrieve its FSID */ |
1356 | error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); | 1344 | error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index af05b918cb5b..6dd48a4405b4 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/kthread.h> | 10 | #include <linux/kthread.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/smp_lock.h> | ||
13 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
14 | 15 | ||
15 | #include <linux/nfs4.h> | 16 | #include <linux/nfs4.h> |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 89f98e9a024b..32062c33c859 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/nfs_fs.h> | 29 | #include <linux/nfs_fs.h> |
30 | #include <linux/nfs_mount.h> | 30 | #include <linux/nfs_mount.h> |
31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
32 | #include <linux/smp_lock.h> | ||
33 | #include <linux/pagevec.h> | 32 | #include <linux/pagevec.h> |
34 | #include <linux/namei.h> | 33 | #include <linux/namei.h> |
35 | #include <linux/mount.h> | 34 | #include <linux/mount.h> |
@@ -1026,12 +1025,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
1026 | res = NULL; | 1025 | res = NULL; |
1027 | goto out; | 1026 | goto out; |
1028 | /* This turned out not to be a regular file */ | 1027 | /* This turned out not to be a regular file */ |
1029 | case -EISDIR: | ||
1030 | case -ENOTDIR: | 1028 | case -ENOTDIR: |
1031 | goto no_open; | 1029 | goto no_open; |
1032 | case -ELOOP: | 1030 | case -ELOOP: |
1033 | if (!(nd->intent.open.flags & O_NOFOLLOW)) | 1031 | if (!(nd->intent.open.flags & O_NOFOLLOW)) |
1034 | goto no_open; | 1032 | goto no_open; |
1033 | /* case -EISDIR: */ | ||
1035 | /* case -EINVAL: */ | 1034 | /* case -EINVAL: */ |
1036 | default: | 1035 | default: |
1037 | goto out; | 1036 | goto out; |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 0055b813ec2c..05062329b678 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/pagemap.h> | 28 | #include <linux/pagemap.h> |
29 | #include <linux/smp_lock.h> | ||
30 | #include <linux/aio.h> | 29 | #include <linux/aio.h> |
31 | 30 | ||
32 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 64f87194d390..bd7938eda6a8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/nfs_mount.h> | 30 | #include <linux/nfs_mount.h> |
31 | #include <linux/nfs4_mount.h> | 31 | #include <linux/nfs4_mount.h> |
32 | #include <linux/lockd/bind.h> | 32 | #include <linux/lockd/bind.h> |
33 | #include <linux/smp_lock.h> | ||
34 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
35 | #include <linux/mount.h> | 34 | #include <linux/mount.h> |
36 | #include <linux/nfs_idmap.h> | 35 | #include <linux/nfs_idmap.h> |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 61bc3a32e1e2..6ea07a3c75d4 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -220,6 +220,7 @@ extern void nfs4_destroy_session(struct nfs4_session *session); | |||
220 | extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp); | 220 | extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp); |
221 | extern int nfs4_proc_create_session(struct nfs_client *, int reset); | 221 | extern int nfs4_proc_create_session(struct nfs_client *, int reset); |
222 | extern int nfs4_proc_destroy_session(struct nfs4_session *); | 222 | extern int nfs4_proc_destroy_session(struct nfs4_session *); |
223 | extern int nfs4_init_session(struct nfs_server *server); | ||
223 | #else /* CONFIG_NFS_v4_1 */ | 224 | #else /* CONFIG_NFS_v4_1 */ |
224 | static inline int nfs4_setup_sequence(struct nfs_client *clp, | 225 | static inline int nfs4_setup_sequence(struct nfs_client *clp, |
225 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, | 226 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, |
@@ -227,6 +228,11 @@ static inline int nfs4_setup_sequence(struct nfs_client *clp, | |||
227 | { | 228 | { |
228 | return 0; | 229 | return 0; |
229 | } | 230 | } |
231 | |||
232 | static inline int nfs4_init_session(struct nfs_server *server) | ||
233 | { | ||
234 | return 0; | ||
235 | } | ||
230 | #endif /* CONFIG_NFS_V4_1 */ | 236 | #endif /* CONFIG_NFS_V4_1 */ |
231 | 237 | ||
232 | extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[]; | 238 | extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[]; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 92ce43517814..6917311f201c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <linux/nfs4.h> | 45 | #include <linux/nfs4.h> |
46 | #include <linux/nfs_fs.h> | 46 | #include <linux/nfs_fs.h> |
47 | #include <linux/nfs_page.h> | 47 | #include <linux/nfs_page.h> |
48 | #include <linux/smp_lock.h> | ||
49 | #include <linux/namei.h> | 48 | #include <linux/namei.h> |
50 | #include <linux/mount.h> | 49 | #include <linux/mount.h> |
51 | #include <linux/module.h> | 50 | #include <linux/module.h> |
@@ -2041,15 +2040,9 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, | |||
2041 | .rpc_argp = &args, | 2040 | .rpc_argp = &args, |
2042 | .rpc_resp = &res, | 2041 | .rpc_resp = &res, |
2043 | }; | 2042 | }; |
2044 | int status; | ||
2045 | 2043 | ||
2046 | nfs_fattr_init(info->fattr); | 2044 | nfs_fattr_init(info->fattr); |
2047 | status = nfs4_recover_expired_lease(server); | 2045 | return nfs4_call_sync(server, &msg, &args, &res, 0); |
2048 | if (!status) | ||
2049 | status = nfs4_check_client_ready(server->nfs_client); | ||
2050 | if (!status) | ||
2051 | status = nfs4_call_sync(server, &msg, &args, &res, 0); | ||
2052 | return status; | ||
2053 | } | 2046 | } |
2054 | 2047 | ||
2055 | static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, | 2048 | static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, |
@@ -4100,15 +4093,23 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request) | |||
4100 | if (request->fl_start < 0 || request->fl_end < 0) | 4093 | if (request->fl_start < 0 || request->fl_end < 0) |
4101 | return -EINVAL; | 4094 | return -EINVAL; |
4102 | 4095 | ||
4103 | if (IS_GETLK(cmd)) | 4096 | if (IS_GETLK(cmd)) { |
4104 | return nfs4_proc_getlk(state, F_GETLK, request); | 4097 | if (state != NULL) |
4098 | return nfs4_proc_getlk(state, F_GETLK, request); | ||
4099 | return 0; | ||
4100 | } | ||
4105 | 4101 | ||
4106 | if (!(IS_SETLK(cmd) || IS_SETLKW(cmd))) | 4102 | if (!(IS_SETLK(cmd) || IS_SETLKW(cmd))) |
4107 | return -EINVAL; | 4103 | return -EINVAL; |
4108 | 4104 | ||
4109 | if (request->fl_type == F_UNLCK) | 4105 | if (request->fl_type == F_UNLCK) { |
4110 | return nfs4_proc_unlck(state, cmd, request); | 4106 | if (state != NULL) |
4107 | return nfs4_proc_unlck(state, cmd, request); | ||
4108 | return 0; | ||
4109 | } | ||
4111 | 4110 | ||
4111 | if (state == NULL) | ||
4112 | return -ENOLCK; | ||
4112 | do { | 4113 | do { |
4113 | status = nfs4_proc_setlk(state, cmd, request); | 4114 | status = nfs4_proc_setlk(state, cmd, request); |
4114 | if ((status != -EAGAIN) || IS_SETLK(cmd)) | 4115 | if ((status != -EAGAIN) || IS_SETLK(cmd)) |
@@ -4794,6 +4795,22 @@ int nfs4_proc_destroy_session(struct nfs4_session *session) | |||
4794 | return status; | 4795 | return status; |
4795 | } | 4796 | } |
4796 | 4797 | ||
4798 | int nfs4_init_session(struct nfs_server *server) | ||
4799 | { | ||
4800 | struct nfs_client *clp = server->nfs_client; | ||
4801 | int ret; | ||
4802 | |||
4803 | if (!nfs4_has_session(clp)) | ||
4804 | return 0; | ||
4805 | |||
4806 | clp->cl_session->fc_attrs.max_rqst_sz = server->wsize; | ||
4807 | clp->cl_session->fc_attrs.max_resp_sz = server->rsize; | ||
4808 | ret = nfs4_recover_expired_lease(server); | ||
4809 | if (!ret) | ||
4810 | ret = nfs4_check_client_ready(clp); | ||
4811 | return ret; | ||
4812 | } | ||
4813 | |||
4797 | /* | 4814 | /* |
4798 | * Renew the cl_session lease. | 4815 | * Renew the cl_session lease. |
4799 | */ | 4816 | */ |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index b73c5a728655..65ca8c18476f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -553,6 +553,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f | |||
553 | INIT_LIST_HEAD(&lsp->ls_sequence.list); | 553 | INIT_LIST_HEAD(&lsp->ls_sequence.list); |
554 | lsp->ls_seqid.sequence = &lsp->ls_sequence; | 554 | lsp->ls_seqid.sequence = &lsp->ls_sequence; |
555 | atomic_set(&lsp->ls_count, 1); | 555 | atomic_set(&lsp->ls_count, 1); |
556 | lsp->ls_state = state; | ||
556 | lsp->ls_owner = fl_owner; | 557 | lsp->ls_owner = fl_owner; |
557 | spin_lock(&clp->cl_lock); | 558 | spin_lock(&clp->cl_lock); |
558 | nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64); | 559 | nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64); |
@@ -587,7 +588,6 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_ | |||
587 | if (lsp != NULL) | 588 | if (lsp != NULL) |
588 | break; | 589 | break; |
589 | if (new != NULL) { | 590 | if (new != NULL) { |
590 | new->ls_state = state; | ||
591 | list_add(&new->ls_locks, &state->lock_states); | 591 | list_add(&new->ls_locks, &state->lock_states); |
592 | set_bit(LK_STATE_IN_USE, &state->flags); | 592 | set_bit(LK_STATE_IN_USE, &state->flags); |
593 | lsp = new; | 593 | lsp = new; |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 96c4ebfa46f4..73ea5e8d66ce 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/sunrpc/clnt.h> | 18 | #include <linux/sunrpc/clnt.h> |
19 | #include <linux/nfs_fs.h> | 19 | #include <linux/nfs_fs.h> |
20 | #include <linux/nfs_page.h> | 20 | #include <linux/nfs_page.h> |
21 | #include <linux/smp_lock.h> | ||
22 | 21 | ||
23 | #include <asm/system.h> | 22 | #include <asm/system.h> |
24 | 23 | ||
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 1250fb978ac1..6d0847562d87 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/inet.h> | 26 | #include <linux/inet.h> |
27 | #include <linux/string.h> | 27 | #include <linux/string.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
30 | 29 | ||
31 | #include <linux/nfs.h> | 30 | #include <linux/nfs.h> |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index d4c9884cd54b..492c79b7800b 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/unistd.h> | 18 | #include <linux/unistd.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/freezer.h> | 21 | #include <linux/freezer.h> |
23 | #include <linux/fs_struct.h> | 22 | #include <linux/fs_struct.h> |
24 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig new file mode 100644 index 000000000000..72da095d4009 --- /dev/null +++ b/fs/nilfs2/Kconfig | |||
@@ -0,0 +1,25 @@ | |||
1 | config NILFS2_FS | ||
2 | tristate "NILFS2 file system support (EXPERIMENTAL)" | ||
3 | depends on BLOCK && EXPERIMENTAL | ||
4 | select CRC32 | ||
5 | help | ||
6 | NILFS2 is a log-structured file system (LFS) supporting continuous | ||
7 | snapshotting. In addition to versioning capability of the entire | ||
8 | file system, users can even restore files mistakenly overwritten or | ||
9 | destroyed just a few seconds ago. Since this file system can keep | ||
10 | consistency like conventional LFS, it achieves quick recovery after | ||
11 | system crashes. | ||
12 | |||
13 | NILFS2 creates a number of checkpoints every few seconds or per | ||
14 | synchronous write basis (unless there is no change). Users can | ||
15 | select significant versions among continuously created checkpoints, | ||
16 | and can change them into snapshots which will be preserved for long | ||
17 | periods until they are changed back to checkpoints. Each | ||
18 | snapshot is mountable as a read-only file system concurrently with | ||
19 | its writable mount, and this feature is convenient for online backup. | ||
20 | |||
21 | Some features including atime, extended attributes, and POSIX ACLs, | ||
22 | are not supported yet. | ||
23 | |||
24 | To compile this file system support as a module, choose M here: the | ||
25 | module will be called nilfs2. If unsure, say N. | ||
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index 36df60b6d8a4..99d58a028b94 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
@@ -568,6 +568,7 @@ void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap, | |||
568 | } | 568 | } |
569 | 569 | ||
570 | static struct lock_class_key nilfs_bmap_dat_lock_key; | 570 | static struct lock_class_key nilfs_bmap_dat_lock_key; |
571 | static struct lock_class_key nilfs_bmap_mdt_lock_key; | ||
571 | 572 | ||
572 | /** | 573 | /** |
573 | * nilfs_bmap_read - read a bmap from an inode | 574 | * nilfs_bmap_read - read a bmap from an inode |
@@ -603,7 +604,11 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode) | |||
603 | bmap->b_ptr_type = NILFS_BMAP_PTR_VS; | 604 | bmap->b_ptr_type = NILFS_BMAP_PTR_VS; |
604 | bmap->b_last_allocated_key = 0; | 605 | bmap->b_last_allocated_key = 0; |
605 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; | 606 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; |
607 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key); | ||
606 | break; | 608 | break; |
609 | case NILFS_IFILE_INO: | ||
610 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key); | ||
611 | /* Fall through */ | ||
607 | default: | 612 | default: |
608 | bmap->b_ptr_type = NILFS_BMAP_PTR_VM; | 613 | bmap->b_ptr_type = NILFS_BMAP_PTR_VM; |
609 | bmap->b_last_allocated_key = 0; | 614 | bmap->b_last_allocated_key = 0; |
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 7d49813f66d6..aec942cf79e3 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
@@ -307,7 +307,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
307 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); | 307 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); |
308 | if (ret < 0) { | 308 | if (ret < 0) { |
309 | if (ret != -ENOENT) | 309 | if (ret != -ENOENT) |
310 | goto out_header; | 310 | break; |
311 | /* skip hole */ | 311 | /* skip hole */ |
312 | ret = 0; | 312 | ret = 0; |
313 | continue; | 313 | continue; |
@@ -340,7 +340,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
340 | continue; | 340 | continue; |
341 | printk(KERN_ERR "%s: cannot delete block\n", | 341 | printk(KERN_ERR "%s: cannot delete block\n", |
342 | __func__); | 342 | __func__); |
343 | goto out_header; | 343 | break; |
344 | } | 344 | } |
345 | } | 345 | } |
346 | 346 | ||
@@ -358,7 +358,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
358 | kunmap_atomic(kaddr, KM_USER0); | 358 | kunmap_atomic(kaddr, KM_USER0); |
359 | } | 359 | } |
360 | 360 | ||
361 | out_header: | ||
362 | brelse(header_bh); | 361 | brelse(header_bh); |
363 | 362 | ||
364 | out_sem: | 363 | out_sem: |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 0b2710e2d565..8927ca27e6f7 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
@@ -134,15 +134,6 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req, | |||
134 | entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, | 134 | entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, |
135 | req->pr_entry_bh, kaddr); | 135 | req->pr_entry_bh, kaddr); |
136 | entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat)); | 136 | entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat)); |
137 | if (entry->de_blocknr != cpu_to_le64(0) || | ||
138 | entry->de_end != cpu_to_le64(NILFS_CNO_MAX)) { | ||
139 | printk(KERN_CRIT | ||
140 | "%s: vbn = %llu, start = %llu, end = %llu, pbn = %llu\n", | ||
141 | __func__, (unsigned long long)req->pr_entry_nr, | ||
142 | (unsigned long long)le64_to_cpu(entry->de_start), | ||
143 | (unsigned long long)le64_to_cpu(entry->de_end), | ||
144 | (unsigned long long)le64_to_cpu(entry->de_blocknr)); | ||
145 | } | ||
146 | entry->de_blocknr = cpu_to_le64(blocknr); | 137 | entry->de_blocknr = cpu_to_le64(blocknr); |
147 | kunmap_atomic(kaddr, KM_USER0); | 138 | kunmap_atomic(kaddr, KM_USER0); |
148 | 139 | ||
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c index 54100acc1102..1a4fa04cf071 100644 --- a/fs/nilfs2/dir.c +++ b/fs/nilfs2/dir.c | |||
@@ -43,7 +43,6 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/pagemap.h> | 45 | #include <linux/pagemap.h> |
46 | #include <linux/smp_lock.h> | ||
47 | #include "nilfs.h" | 46 | #include "nilfs.h" |
48 | #include "page.h" | 47 | #include "page.h" |
49 | 48 | ||
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index aa977549919e..8b5e4778cf28 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -1829,26 +1829,13 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci, | |||
1829 | err = nilfs_segbuf_write(segbuf, &wi); | 1829 | err = nilfs_segbuf_write(segbuf, &wi); |
1830 | 1830 | ||
1831 | res = nilfs_segbuf_wait(segbuf, &wi); | 1831 | res = nilfs_segbuf_wait(segbuf, &wi); |
1832 | err = unlikely(err) ? : res; | 1832 | err = err ? : res; |
1833 | if (unlikely(err)) | 1833 | if (err) |
1834 | return err; | 1834 | return err; |
1835 | } | 1835 | } |
1836 | return 0; | 1836 | return 0; |
1837 | } | 1837 | } |
1838 | 1838 | ||
1839 | static int nilfs_page_has_uncleared_buffer(struct page *page) | ||
1840 | { | ||
1841 | struct buffer_head *head, *bh; | ||
1842 | |||
1843 | head = bh = page_buffers(page); | ||
1844 | do { | ||
1845 | if (buffer_dirty(bh) && !list_empty(&bh->b_assoc_buffers)) | ||
1846 | return 1; | ||
1847 | bh = bh->b_this_page; | ||
1848 | } while (bh != head); | ||
1849 | return 0; | ||
1850 | } | ||
1851 | |||
1852 | static void __nilfs_end_page_io(struct page *page, int err) | 1839 | static void __nilfs_end_page_io(struct page *page, int err) |
1853 | { | 1840 | { |
1854 | if (!err) { | 1841 | if (!err) { |
@@ -1872,12 +1859,11 @@ static void nilfs_end_page_io(struct page *page, int err) | |||
1872 | if (!page) | 1859 | if (!page) |
1873 | return; | 1860 | return; |
1874 | 1861 | ||
1875 | if (buffer_nilfs_node(page_buffers(page)) && | 1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) |
1876 | nilfs_page_has_uncleared_buffer(page)) | 1863 | /* |
1877 | /* For b-tree node pages, this function may be called twice | 1864 | * For b-tree node pages, this function may be called twice |
1878 | or more because they might be split in a segment. | 1865 | * or more because they might be split in a segment. |
1879 | This check assures that cleanup has been done for all | 1866 | */ |
1880 | buffers in a split btnode page. */ | ||
1881 | return; | 1867 | return; |
1882 | 1868 | ||
1883 | __nilfs_end_page_io(page, err); | 1869 | __nilfs_end_page_io(page, err); |
@@ -1940,7 +1926,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | |||
1940 | } | 1926 | } |
1941 | if (bh->b_page != fs_page) { | 1927 | if (bh->b_page != fs_page) { |
1942 | nilfs_end_page_io(fs_page, err); | 1928 | nilfs_end_page_io(fs_page, err); |
1943 | if (unlikely(fs_page == failed_page)) | 1929 | if (fs_page && fs_page == failed_page) |
1944 | goto done; | 1930 | goto done; |
1945 | fs_page = bh->b_page; | 1931 | fs_page = bh->b_page; |
1946 | } | 1932 | } |
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 9fcd36dcc9a0..467b413bec21 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -7,7 +7,6 @@ | |||
7 | 7 | ||
8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
9 | #include <linux/mount.h> | 9 | #include <linux/mount.h> |
10 | #include <linux/smp_lock.h> | ||
11 | 10 | ||
12 | #define MLOG_MASK_PREFIX ML_INODE | 11 | #define MLOG_MASK_PREFIX ML_INODE |
13 | #include <cluster/masklog.h> | 12 | #include <cluster/masklog.h> |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 1a9c7878f864..ea4e6cb29e13 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -436,7 +436,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
436 | rcu_assign_pointer(ptbl->part[partno], p); | 436 | rcu_assign_pointer(ptbl->part[partno], p); |
437 | 437 | ||
438 | /* suppress uevent if the disk supresses it */ | 438 | /* suppress uevent if the disk supresses it */ |
439 | if (!dev_get_uevent_suppress(pdev)) | 439 | if (!dev_get_uevent_suppress(ddev)) |
440 | kobject_uevent(&pdev->kobj, KOBJ_ADD); | 440 | kobject_uevent(&pdev->kobj, KOBJ_ADD); |
441 | 441 | ||
442 | return p; | 442 | return p; |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index f3d47d856848..6925b835a43b 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/reiserfs_acl.h> | 46 | #include <linux/reiserfs_acl.h> |
47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
48 | #include <net/checksum.h> | 48 | #include <net/checksum.h> |
49 | #include <linux/smp_lock.h> | ||
50 | #include <linux/stat.h> | 49 | #include <linux/stat.h> |
51 | #include <linux/quotaops.h> | 50 | #include <linux/quotaops.h> |
52 | 51 | ||
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 3b52770f46ff..cb5fc57e370b 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <linux/vfs.h> | 31 | #include <linux/vfs.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/smp_lock.h> | ||
33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
34 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index bc5857199ec2..762a7d6cec73 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -297,6 +297,7 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer) | |||
297 | { | 297 | { |
298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); | 298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); |
299 | 299 | ||
300 | dbg_io("jhead %d", wbuf->jhead); | ||
300 | wbuf->need_sync = 1; | 301 | wbuf->need_sync = 1; |
301 | wbuf->c->need_wbuf_sync = 1; | 302 | wbuf->c->need_wbuf_sync = 1; |
302 | ubifs_wake_up_bgt(wbuf->c); | 303 | ubifs_wake_up_bgt(wbuf->c); |
@@ -311,8 +312,12 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
311 | { | 312 | { |
312 | ubifs_assert(!hrtimer_active(&wbuf->timer)); | 313 | ubifs_assert(!hrtimer_active(&wbuf->timer)); |
313 | 314 | ||
314 | if (!ktime_to_ns(wbuf->softlimit)) | 315 | if (wbuf->no_timer) |
315 | return; | 316 | return; |
317 | dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead, | ||
318 | div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC), | ||
319 | div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta, | ||
320 | USEC_PER_SEC)); | ||
316 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, | 321 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, |
317 | HRTIMER_MODE_REL); | 322 | HRTIMER_MODE_REL); |
318 | } | 323 | } |
@@ -323,11 +328,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
323 | */ | 328 | */ |
324 | static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | 329 | static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) |
325 | { | 330 | { |
326 | /* | 331 | if (wbuf->no_timer) |
327 | * If the syncer is waiting for the lock (from the background thread's | 332 | return; |
328 | * context) and another task is changing write-buffer then the syncing | ||
329 | * should be canceled. | ||
330 | */ | ||
331 | wbuf->need_sync = 0; | 333 | wbuf->need_sync = 0; |
332 | hrtimer_cancel(&wbuf->timer); | 334 | hrtimer_cancel(&wbuf->timer); |
333 | } | 335 | } |
@@ -349,8 +351,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
349 | /* Write-buffer is empty or not seeked */ | 351 | /* Write-buffer is empty or not seeked */ |
350 | return 0; | 352 | return 0; |
351 | 353 | ||
352 | dbg_io("LEB %d:%d, %d bytes", | 354 | dbg_io("LEB %d:%d, %d bytes, jhead %d", |
353 | wbuf->lnum, wbuf->offs, wbuf->used); | 355 | wbuf->lnum, wbuf->offs, wbuf->used, wbuf->jhead); |
354 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); | 356 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); |
355 | ubifs_assert(!(wbuf->avail & 7)); | 357 | ubifs_assert(!(wbuf->avail & 7)); |
356 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); | 358 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); |
@@ -390,7 +392,7 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
390 | * @offs: logical eraseblock offset to seek to | 392 | * @offs: logical eraseblock offset to seek to |
391 | * @dtype: data type | 393 | * @dtype: data type |
392 | * | 394 | * |
393 | * This function targets the write buffer to logical eraseblock @lnum:@offs. | 395 | * This function targets the write-buffer to logical eraseblock @lnum:@offs. |
394 | * The write-buffer is synchronized if it is not empty. Returns zero in case of | 396 | * The write-buffer is synchronized if it is not empty. Returns zero in case of |
395 | * success and a negative error code in case of failure. | 397 | * success and a negative error code in case of failure. |
396 | */ | 398 | */ |
@@ -399,7 +401,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | |||
399 | { | 401 | { |
400 | const struct ubifs_info *c = wbuf->c; | 402 | const struct ubifs_info *c = wbuf->c; |
401 | 403 | ||
402 | dbg_io("LEB %d:%d", lnum, offs); | 404 | dbg_io("LEB %d:%d, jhead %d", lnum, offs, wbuf->jhead); |
403 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); | 405 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); |
404 | ubifs_assert(offs >= 0 && offs <= c->leb_size); | 406 | ubifs_assert(offs >= 0 && offs <= c->leb_size); |
405 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); | 407 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); |
@@ -506,9 +508,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
506 | struct ubifs_info *c = wbuf->c; | 508 | struct ubifs_info *c = wbuf->c; |
507 | int err, written, n, aligned_len = ALIGN(len, 8), offs; | 509 | int err, written, n, aligned_len = ALIGN(len, 8), offs; |
508 | 510 | ||
509 | dbg_io("%d bytes (%s) to wbuf at LEB %d:%d", len, | 511 | dbg_io("%d bytes (%s) to jhead %d wbuf at LEB %d:%d", len, |
510 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->lnum, | 512 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->jhead, |
511 | wbuf->offs + wbuf->used); | 513 | wbuf->lnum, wbuf->offs + wbuf->used); |
512 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); | 514 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); |
513 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); | 515 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); |
514 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); | 516 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); |
@@ -533,8 +535,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
533 | memcpy(wbuf->buf + wbuf->used, buf, len); | 535 | memcpy(wbuf->buf + wbuf->used, buf, len); |
534 | 536 | ||
535 | if (aligned_len == wbuf->avail) { | 537 | if (aligned_len == wbuf->avail) { |
536 | dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, | 538 | dbg_io("flush jhead %d wbuf to LEB %d:%d", |
537 | wbuf->offs); | 539 | wbuf->jhead, wbuf->lnum, wbuf->offs); |
538 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, | 540 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, |
539 | wbuf->offs, c->min_io_size, | 541 | wbuf->offs, c->min_io_size, |
540 | wbuf->dtype); | 542 | wbuf->dtype); |
@@ -562,7 +564,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
562 | * minimal I/O unit. We have to fill and flush write-buffer and switch | 564 | * minimal I/O unit. We have to fill and flush write-buffer and switch |
563 | * to the next min. I/O unit. | 565 | * to the next min. I/O unit. |
564 | */ | 566 | */ |
565 | dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, wbuf->offs); | 567 | dbg_io("flush jhead %d wbuf to LEB %d:%d", |
568 | wbuf->jhead, wbuf->lnum, wbuf->offs); | ||
566 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); | 569 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); |
567 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, | 570 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, |
568 | c->min_io_size, wbuf->dtype); | 571 | c->min_io_size, wbuf->dtype); |
@@ -695,7 +698,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, | |||
695 | int err, rlen, overlap; | 698 | int err, rlen, overlap; |
696 | struct ubifs_ch *ch = buf; | 699 | struct ubifs_ch *ch = buf; |
697 | 700 | ||
698 | dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); | 701 | dbg_io("LEB %d:%d, %s, length %d, jhead %d", lnum, offs, |
702 | dbg_ntype(type), len, wbuf->jhead); | ||
699 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); | 703 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); |
700 | ubifs_assert(!(offs & 7) && offs < c->leb_size); | 704 | ubifs_assert(!(offs & 7) && offs < c->leb_size); |
701 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); | 705 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); |
@@ -819,13 +823,12 @@ out: | |||
819 | * @c: UBIFS file-system description object | 823 | * @c: UBIFS file-system description object |
820 | * @wbuf: write-buffer to initialize | 824 | * @wbuf: write-buffer to initialize |
821 | * | 825 | * |
822 | * This function initializes write buffer. Returns zero in case of success | 826 | * This function initializes write-buffer. Returns zero in case of success |
823 | * %-ENOMEM in case of failure. | 827 | * %-ENOMEM in case of failure. |
824 | */ | 828 | */ |
825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | 829 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) |
826 | { | 830 | { |
827 | size_t size; | 831 | size_t size; |
828 | ktime_t hardlimit; | ||
829 | 832 | ||
830 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); | 833 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); |
831 | if (!wbuf->buf) | 834 | if (!wbuf->buf) |
@@ -851,22 +854,16 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
851 | 854 | ||
852 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 855 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
853 | wbuf->timer.function = wbuf_timer_callback_nolock; | 856 | wbuf->timer.function = wbuf_timer_callback_nolock; |
854 | /* | 857 | wbuf->softlimit = ktime_set(WBUF_TIMEOUT_SOFTLIMIT, 0); |
855 | * Make write-buffer soft limit to be 20% of the hard limit. The | 858 | wbuf->delta = WBUF_TIMEOUT_HARDLIMIT - WBUF_TIMEOUT_SOFTLIMIT; |
856 | * write-buffer timer is allowed to expire any time between the soft | 859 | wbuf->delta *= 1000000000ULL; |
857 | * and hard limits. | 860 | ubifs_assert(wbuf->delta <= ULONG_MAX); |
858 | */ | ||
859 | hardlimit = ktime_set(DEFAULT_WBUF_TIMEOUT_SECS, 0); | ||
860 | wbuf->delta = (DEFAULT_WBUF_TIMEOUT_SECS * NSEC_PER_SEC) * 2 / 10; | ||
861 | wbuf->softlimit = ktime_sub_ns(hardlimit, wbuf->delta); | ||
862 | hrtimer_set_expires_range_ns(&wbuf->timer, wbuf->softlimit, | ||
863 | wbuf->delta); | ||
864 | return 0; | 861 | return 0; |
865 | } | 862 | } |
866 | 863 | ||
867 | /** | 864 | /** |
868 | * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. | 865 | * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. |
869 | * @wbuf: the write-buffer whereto add | 866 | * @wbuf: the write-buffer where to add |
870 | * @inum: the inode number | 867 | * @inum: the inode number |
871 | * | 868 | * |
872 | * This function adds an inode number to the inode array of the write-buffer. | 869 | * This function adds an inode number to the inode array of the write-buffer. |
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 6db7a6be6c97..8aacd64957a2 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c | |||
@@ -25,7 +25,6 @@ | |||
25 | /* This file implements EXT2-compatible extended attribute ioctl() calls */ | 25 | /* This file implements EXT2-compatible extended attribute ioctl() calls */ |
26 | 26 | ||
27 | #include <linux/compat.h> | 27 | #include <linux/compat.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
30 | #include "ubifs.h" | 29 | #include "ubifs.h" |
31 | 30 | ||
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 805605250f12..e5f6cf8a1155 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
@@ -53,6 +53,25 @@ static int is_empty(void *buf, int len) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * first_non_ff - find offset of the first non-0xff byte. | ||
57 | * @buf: buffer to search in | ||
58 | * @len: length of buffer | ||
59 | * | ||
60 | * This function returns offset of the first non-0xff byte in @buf or %-1 if | ||
61 | * the buffer contains only 0xff bytes. | ||
62 | */ | ||
63 | static int first_non_ff(void *buf, int len) | ||
64 | { | ||
65 | uint8_t *p = buf; | ||
66 | int i; | ||
67 | |||
68 | for (i = 0; i < len; i++) | ||
69 | if (*p++ != 0xff) | ||
70 | return i; | ||
71 | return -1; | ||
72 | } | ||
73 | |||
74 | /** | ||
56 | * get_master_node - get the last valid master node allowing for corruption. | 75 | * get_master_node - get the last valid master node allowing for corruption. |
57 | * @c: UBIFS file-system description object | 76 | * @c: UBIFS file-system description object |
58 | * @lnum: LEB number | 77 | * @lnum: LEB number |
@@ -357,11 +376,7 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs) | |||
357 | empty_offs = ALIGN(offs + 1, c->min_io_size); | 376 | empty_offs = ALIGN(offs + 1, c->min_io_size); |
358 | check_len = c->leb_size - empty_offs; | 377 | check_len = c->leb_size - empty_offs; |
359 | p = buf + empty_offs - offs; | 378 | p = buf + empty_offs - offs; |
360 | 379 | return is_empty(p, check_len); | |
361 | for (; check_len > 0; check_len--) | ||
362 | if (*p++ != 0xff) | ||
363 | return 0; | ||
364 | return 1; | ||
365 | } | 380 | } |
366 | 381 | ||
367 | /** | 382 | /** |
@@ -543,8 +558,8 @@ static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs) | |||
543 | * | 558 | * |
544 | * This function does a scan of a LEB, but caters for errors that might have | 559 | * This function does a scan of a LEB, but caters for errors that might have |
545 | * been caused by the unclean unmount from which we are attempting to recover. | 560 | * been caused by the unclean unmount from which we are attempting to recover. |
546 | * | 561 | * Returns %0 in case of success, %-EUCLEAN if an unrecoverable corruption is |
547 | * This function returns %0 on success and a negative error code on failure. | 562 | * found, and a negative error code in case of failure. |
548 | */ | 563 | */ |
549 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | 564 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, |
550 | int offs, void *sbuf, int grouped) | 565 | int offs, void *sbuf, int grouped) |
@@ -643,7 +658,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
643 | goto corrupted; | 658 | goto corrupted; |
644 | default: | 659 | default: |
645 | dbg_err("unknown"); | 660 | dbg_err("unknown"); |
646 | goto corrupted; | 661 | err = -EINVAL; |
662 | goto error; | ||
647 | } | 663 | } |
648 | } | 664 | } |
649 | 665 | ||
@@ -652,8 +668,13 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
652 | clean_buf(c, &buf, lnum, &offs, &len); | 668 | clean_buf(c, &buf, lnum, &offs, &len); |
653 | need_clean = 1; | 669 | need_clean = 1; |
654 | } else { | 670 | } else { |
655 | ubifs_err("corrupt empty space at LEB %d:%d", | 671 | int corruption = first_non_ff(buf, len); |
656 | lnum, offs); | 672 | |
673 | ubifs_err("corrupt empty space LEB %d:%d, corruption " | ||
674 | "starts at %d", lnum, offs, corruption); | ||
675 | /* Make sure we dump interesting non-0xFF data */ | ||
676 | offs = corruption; | ||
677 | buf += corruption; | ||
657 | goto corrupted; | 678 | goto corrupted; |
658 | } | 679 | } |
659 | } | 680 | } |
@@ -813,7 +834,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | |||
813 | static int recover_head(const struct ubifs_info *c, int lnum, int offs, | 834 | static int recover_head(const struct ubifs_info *c, int lnum, int offs, |
814 | void *sbuf) | 835 | void *sbuf) |
815 | { | 836 | { |
816 | int len, err, need_clean = 0; | 837 | int len, err; |
817 | 838 | ||
818 | if (c->min_io_size > 1) | 839 | if (c->min_io_size > 1) |
819 | len = c->min_io_size; | 840 | len = c->min_io_size; |
@@ -827,19 +848,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs, | |||
827 | 848 | ||
828 | /* Read at the head location and check it is empty flash */ | 849 | /* Read at the head location and check it is empty flash */ |
829 | err = ubi_read(c->ubi, lnum, sbuf, offs, len); | 850 | err = ubi_read(c->ubi, lnum, sbuf, offs, len); |
830 | if (err) | 851 | if (err || !is_empty(sbuf, len)) { |
831 | need_clean = 1; | ||
832 | else { | ||
833 | uint8_t *p = sbuf; | ||
834 | |||
835 | while (len--) | ||
836 | if (*p++ != 0xff) { | ||
837 | need_clean = 1; | ||
838 | break; | ||
839 | } | ||
840 | } | ||
841 | |||
842 | if (need_clean) { | ||
843 | dbg_rcvry("cleaning head at %d:%d", lnum, offs); | 852 | dbg_rcvry("cleaning head at %d:%d", lnum, offs); |
844 | if (offs == 0) | 853 | if (offs == 0) |
845 | return ubifs_leb_unmap(c, lnum); | 854 | return ubifs_leb_unmap(c, lnum); |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 11cc80125a49..2970500f32df 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
@@ -837,9 +837,10 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |||
837 | 837 | ||
838 | dbg_mnt("replay log LEB %d:%d", lnum, offs); | 838 | dbg_mnt("replay log LEB %d:%d", lnum, offs); |
839 | sleb = ubifs_scan(c, lnum, offs, sbuf); | 839 | sleb = ubifs_scan(c, lnum, offs, sbuf); |
840 | if (IS_ERR(sleb)) { | 840 | if (IS_ERR(sleb) ) { |
841 | if (c->need_recovery) | 841 | if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery) |
842 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); | 842 | return PTR_ERR(sleb); |
843 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); | ||
843 | if (IS_ERR(sleb)) | 844 | if (IS_ERR(sleb)) |
844 | return PTR_ERR(sleb); | 845 | return PTR_ERR(sleb); |
845 | } | 846 | } |
@@ -957,7 +958,7 @@ out: | |||
957 | return err; | 958 | return err; |
958 | 959 | ||
959 | out_dump: | 960 | out_dump: |
960 | ubifs_err("log error detected while replying the log at LEB %d:%d", | 961 | ubifs_err("log error detected while replaying the log at LEB %d:%d", |
961 | lnum, offs + snod->offs); | 962 | lnum, offs + snod->offs); |
962 | dbg_dump_node(c, snod->node); | 963 | dbg_dump_node(c, snod->node); |
963 | ubifs_scan_destroy(sleb); | 964 | ubifs_scan_destroy(sleb); |
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index 0ed82479b44b..892ebfee4fe5 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c | |||
@@ -238,12 +238,12 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, | |||
238 | { | 238 | { |
239 | int len; | 239 | int len; |
240 | 240 | ||
241 | ubifs_err("corrupted data at LEB %d:%d", lnum, offs); | 241 | ubifs_err("corruption at LEB %d:%d", lnum, offs); |
242 | if (dbg_failure_mode) | 242 | if (dbg_failure_mode) |
243 | return; | 243 | return; |
244 | len = c->leb_size - offs; | 244 | len = c->leb_size - offs; |
245 | if (len > 4096) | 245 | if (len > 8192) |
246 | len = 4096; | 246 | len = 8192; |
247 | dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs); | 247 | dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs); |
248 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); | 248 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); |
249 | } | 249 | } |
@@ -256,7 +256,9 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, | |||
256 | * @sbuf: scan buffer (must be c->leb_size) | 256 | * @sbuf: scan buffer (must be c->leb_size) |
257 | * | 257 | * |
258 | * This function scans LEB number @lnum and returns complete information about | 258 | * This function scans LEB number @lnum and returns complete information about |
259 | * its contents. Returns an error code in case of failure. | 259 | * its contents. Returns the scaned information in case of success and, |
260 | * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case | ||
261 | * of failure. | ||
260 | */ | 262 | */ |
261 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | 263 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, |
262 | int offs, void *sbuf) | 264 | int offs, void *sbuf) |
@@ -279,7 +281,6 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
279 | cond_resched(); | 281 | cond_resched(); |
280 | 282 | ||
281 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); | 283 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); |
282 | |||
283 | if (ret > 0) { | 284 | if (ret > 0) { |
284 | /* Padding bytes or a valid padding node */ | 285 | /* Padding bytes or a valid padding node */ |
285 | offs += ret; | 286 | offs += ret; |
@@ -304,7 +305,8 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
304 | goto corrupted; | 305 | goto corrupted; |
305 | default: | 306 | default: |
306 | dbg_err("unknown"); | 307 | dbg_err("unknown"); |
307 | goto corrupted; | 308 | err = -EINVAL; |
309 | goto error; | ||
308 | } | 310 | } |
309 | 311 | ||
310 | err = ubifs_add_snod(c, sleb, buf, offs); | 312 | err = ubifs_add_snod(c, sleb, buf, offs); |
@@ -317,8 +319,10 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
317 | len -= node_len; | 319 | len -= node_len; |
318 | } | 320 | } |
319 | 321 | ||
320 | if (offs % c->min_io_size) | 322 | if (offs % c->min_io_size) { |
321 | goto corrupted; | 323 | ubifs_err("empty space starts at non-aligned offset %d", offs); |
324 | goto corrupted;; | ||
325 | } | ||
322 | 326 | ||
323 | ubifs_end_scan(c, sleb, lnum, offs); | 327 | ubifs_end_scan(c, sleb, lnum, offs); |
324 | 328 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 79fad43f3c57..26d2e0d80465 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -797,7 +797,7 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
797 | * does not need to be synchronized by timer. | 797 | * does not need to be synchronized by timer. |
798 | */ | 798 | */ |
799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; | 799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; |
800 | c->jheads[GCHD].wbuf.softlimit = ktime_set(0, 0); | 800 | c->jheads[GCHD].wbuf.no_timer = 1; |
801 | 801 | ||
802 | return 0; | 802 | return 0; |
803 | } | 803 | } |
@@ -986,7 +986,7 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
986 | switch (token) { | 986 | switch (token) { |
987 | /* | 987 | /* |
988 | * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. | 988 | * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. |
989 | * We accepte them in order to be backware-compatible. But this | 989 | * We accept them in order to be backward-compatible. But this |
990 | * should be removed at some point. | 990 | * should be removed at some point. |
991 | */ | 991 | */ |
992 | case Opt_fast_unmount: | 992 | case Opt_fast_unmount: |
@@ -1287,6 +1287,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
1287 | if (err) | 1287 | if (err) |
1288 | goto out_journal; | 1288 | goto out_journal; |
1289 | 1289 | ||
1290 | /* Calculate 'min_idx_lebs' after journal replay */ | ||
1291 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); | ||
1292 | |||
1290 | err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); | 1293 | err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); |
1291 | if (err) | 1294 | if (err) |
1292 | goto out_orphans; | 1295 | goto out_orphans; |
@@ -1754,10 +1757,8 @@ static void ubifs_put_super(struct super_block *sb) | |||
1754 | 1757 | ||
1755 | /* Synchronize write-buffers */ | 1758 | /* Synchronize write-buffers */ |
1756 | if (c->jheads) | 1759 | if (c->jheads) |
1757 | for (i = 0; i < c->jhead_cnt; i++) { | 1760 | for (i = 0; i < c->jhead_cnt; i++) |
1758 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1761 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
1759 | hrtimer_cancel(&c->jheads[i].wbuf.timer); | ||
1760 | } | ||
1761 | 1762 | ||
1762 | /* | 1763 | /* |
1763 | * On fatal errors c->ro_media is set to 1, in which case we do | 1764 | * On fatal errors c->ro_media is set to 1, in which case we do |
@@ -1975,7 +1976,8 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
1975 | err = bdi_init(&c->bdi); | 1976 | err = bdi_init(&c->bdi); |
1976 | if (err) | 1977 | if (err) |
1977 | goto out_close; | 1978 | goto out_close; |
1978 | err = bdi_register(&c->bdi, NULL, "ubifs"); | 1979 | err = bdi_register(&c->bdi, NULL, "ubifs_%d_%d", |
1980 | c->vi.ubi_num, c->vi.vol_id); | ||
1979 | if (err) | 1981 | if (err) |
1980 | goto out_bdi; | 1982 | goto out_bdi; |
1981 | 1983 | ||
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 1bf01d820066..a29349094422 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -95,8 +95,9 @@ | |||
95 | */ | 95 | */ |
96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" | 96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" |
97 | 97 | ||
98 | /* Default write-buffer synchronization timeout in seconds */ | 98 | /* Write-buffer synchronization timeout interval in seconds */ |
99 | #define DEFAULT_WBUF_TIMEOUT_SECS 5 | 99 | #define WBUF_TIMEOUT_SOFTLIMIT 3 |
100 | #define WBUF_TIMEOUT_HARDLIMIT 5 | ||
100 | 101 | ||
101 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ | 102 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ |
102 | #define MAX_INUM 0xFFFFFFFF | 103 | #define MAX_INUM 0xFFFFFFFF |
@@ -654,7 +655,8 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, | |||
654 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit | 655 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit |
655 | * and @softlimit + @delta) | 656 | * and @softlimit + @delta) |
656 | * @timer: write-buffer timer | 657 | * @timer: write-buffer timer |
657 | * @need_sync: it is set if its timer expired and needs sync | 658 | * @no_timer: non-zero if this write-buffer does not have a timer |
659 | * @need_sync: non-zero if the timer expired and the wbuf needs sync'ing | ||
658 | * @next_ino: points to the next position of the following inode number | 660 | * @next_ino: points to the next position of the following inode number |
659 | * @inodes: stores the inode numbers of the nodes which are in wbuf | 661 | * @inodes: stores the inode numbers of the nodes which are in wbuf |
660 | * | 662 | * |
@@ -683,7 +685,8 @@ struct ubifs_wbuf { | |||
683 | ktime_t softlimit; | 685 | ktime_t softlimit; |
684 | unsigned long long delta; | 686 | unsigned long long delta; |
685 | struct hrtimer timer; | 687 | struct hrtimer timer; |
686 | int need_sync; | 688 | unsigned int no_timer:1; |
689 | unsigned int need_sync:1; | ||
687 | int next_ino; | 690 | int next_ino; |
688 | ino_t *inodes; | 691 | ino_t *inodes; |
689 | }; | 692 | }; |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index f4e255441574..0542fd507649 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include "xfs_ioctl.h" | 41 | #include "xfs_ioctl.h" |
42 | 42 | ||
43 | #include <linux/dcache.h> | 43 | #include <linux/dcache.h> |
44 | #include <linux/smp_lock.h> | ||
45 | 44 | ||
46 | static struct vm_operations_struct xfs_file_vm_ops; | 45 | static struct vm_operations_struct xfs_file_vm_ops; |
47 | 46 | ||
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index a553f1041cf1..6ad76bf5fb40 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -30,9 +30,7 @@ | |||
30 | * EXCEPTION_TABLE(...) | 30 | * EXCEPTION_TABLE(...) |
31 | * NOTES | 31 | * NOTES |
32 | * | 32 | * |
33 | * __bss_start = .; | 33 | * BSS_SECTION(0, 0, 0) |
34 | * BSS_SECTION(0, 0) | ||
35 | * __bss_stop = .; | ||
36 | * _end = .; | 34 | * _end = .; |
37 | * | 35 | * |
38 | * /DISCARD/ : { | 36 | * /DISCARD/ : { |
@@ -489,7 +487,8 @@ | |||
489 | * bss (Block Started by Symbol) - uninitialized data | 487 | * bss (Block Started by Symbol) - uninitialized data |
490 | * zeroed during startup | 488 | * zeroed during startup |
491 | */ | 489 | */ |
492 | #define SBSS \ | 490 | #define SBSS(sbss_align) \ |
491 | . = ALIGN(sbss_align); \ | ||
493 | .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) { \ | 492 | .sbss : AT(ADDR(.sbss) - LOAD_OFFSET) { \ |
494 | *(.sbss) \ | 493 | *(.sbss) \ |
495 | *(.scommon) \ | 494 | *(.scommon) \ |
@@ -498,12 +497,10 @@ | |||
498 | #define BSS(bss_align) \ | 497 | #define BSS(bss_align) \ |
499 | . = ALIGN(bss_align); \ | 498 | . = ALIGN(bss_align); \ |
500 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \ | 499 | .bss : AT(ADDR(.bss) - LOAD_OFFSET) { \ |
501 | VMLINUX_SYMBOL(__bss_start) = .; \ | ||
502 | *(.bss.page_aligned) \ | 500 | *(.bss.page_aligned) \ |
503 | *(.dynbss) \ | 501 | *(.dynbss) \ |
504 | *(.bss) \ | 502 | *(.bss) \ |
505 | *(COMMON) \ | 503 | *(COMMON) \ |
506 | VMLINUX_SYMBOL(__bss_stop) = .; \ | ||
507 | } | 504 | } |
508 | 505 | ||
509 | /* | 506 | /* |
@@ -735,8 +732,10 @@ | |||
735 | INIT_RAM_FS \ | 732 | INIT_RAM_FS \ |
736 | } | 733 | } |
737 | 734 | ||
738 | #define BSS_SECTION(sbss_align, bss_align) \ | 735 | #define BSS_SECTION(sbss_align, bss_align, stop_align) \ |
739 | SBSS \ | 736 | . = ALIGN(sbss_align); \ |
737 | VMLINUX_SYMBOL(__bss_start) = .; \ | ||
738 | SBSS(sbss_align) \ | ||
740 | BSS(bss_align) \ | 739 | BSS(bss_align) \ |
741 | . = ALIGN(4); | 740 | . = ALIGN(stop_align); \ |
742 | 741 | VMLINUX_SYMBOL(__bss_stop) = .; | |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 45c18672b093..7174818c2c13 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -43,6 +43,7 @@ | |||
43 | {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 43 | {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
44 | {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 44 | {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
45 | {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 45 | {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
46 | {0x1002, 0x4B48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | ||
46 | {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 47 | {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
47 | {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 48 | {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
48 | {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ | 49 | {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ |
@@ -262,6 +263,7 @@ | |||
262 | {0x1002, 0x9440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ | 263 | {0x1002, 0x9440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ |
263 | {0x1002, 0x9441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ | 264 | {0x1002, 0x9441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ |
264 | {0x1002, 0x9442, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ | 265 | {0x1002, 0x9442, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ |
266 | {0x1002, 0x9443, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ | ||
265 | {0x1002, 0x9444, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ | 267 | {0x1002, 0x9444, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ |
266 | {0x1002, 0x9446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ | 268 | {0x1002, 0x9446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ |
267 | {0x1002, 0x944A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 269 | {0x1002, 0x944A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
@@ -346,12 +348,12 @@ | |||
346 | {0x1002, 0x9599, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ | 348 | {0x1002, 0x9599, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ |
347 | {0x1002, 0x959B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 349 | {0x1002, 0x959B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
348 | {0x1002, 0x95C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 350 | {0x1002, 0x95C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
351 | {0x1002, 0x95C2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
352 | {0x1002, 0x95C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
349 | {0x1002, 0x95C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 353 | {0x1002, 0x95C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
350 | {0x1002, 0x95C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 354 | {0x1002, 0x95C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
351 | {0x1002, 0x95C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 355 | {0x1002, 0x95C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
352 | {0x1002, 0x95C9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 356 | {0x1002, 0x95C9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
353 | {0x1002, 0x95C2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
354 | {0x1002, 0x95C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | ||
355 | {0x1002, 0x95CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 357 | {0x1002, 0x95CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
356 | {0x1002, 0x95CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 358 | {0x1002, 0x95CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
357 | {0x1002, 0x95CE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ | 359 | {0x1002, 0x95CE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ |
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 3a52a63c1351..1d52425a6118 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h | |||
@@ -229,6 +229,11 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi) | |||
229 | (1 << BDI_async_congested)); | 229 | (1 << BDI_async_congested)); |
230 | } | 230 | } |
231 | 231 | ||
232 | enum { | ||
233 | BLK_RW_ASYNC = 0, | ||
234 | BLK_RW_SYNC = 1, | ||
235 | }; | ||
236 | |||
232 | void clear_bdi_congested(struct backing_dev_info *bdi, int sync); | 237 | void clear_bdi_congested(struct backing_dev_info *bdi, int sync); |
233 | void set_bdi_congested(struct backing_dev_info *bdi, int sync); | 238 | void set_bdi_congested(struct backing_dev_info *bdi, int sync); |
234 | long congestion_wait(int sync, long timeout); | 239 | long congestion_wait(int sync, long timeout); |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 0146e0fecf1a..e7cb5dbf6c26 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -70,11 +70,6 @@ enum rq_cmd_type_bits { | |||
70 | REQ_TYPE_ATA_PC, | 70 | REQ_TYPE_ATA_PC, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | enum { | ||
74 | BLK_RW_ASYNC = 0, | ||
75 | BLK_RW_SYNC = 1, | ||
76 | }; | ||
77 | |||
78 | /* | 73 | /* |
79 | * For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being | 74 | * For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being |
80 | * sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a | 75 | * sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a |
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index 20a100fe2b4f..3a1dbba4d3ae 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h | |||
@@ -143,12 +143,3 @@ extern void clockevents_notify(unsigned long reason, void *arg); | |||
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | #endif | 145 | #endif |
146 | |||
147 | #ifdef CONFIG_GENERIC_CLOCKEVENTS | ||
148 | extern ktime_t clockevents_get_next_event(int cpu); | ||
149 | #else | ||
150 | static inline ktime_t clockevents_get_next_event(int cpu) | ||
151 | { | ||
152 | return (ktime_t) { .tv64 = KTIME_MAX }; | ||
153 | } | ||
154 | #endif | ||
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index d71f7c0f931b..38fe59dc89ae 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h | |||
@@ -89,7 +89,6 @@ struct vc_data { | |||
89 | unsigned int vc_need_wrap : 1; | 89 | unsigned int vc_need_wrap : 1; |
90 | unsigned int vc_can_do_color : 1; | 90 | unsigned int vc_can_do_color : 1; |
91 | unsigned int vc_report_mouse : 2; | 91 | unsigned int vc_report_mouse : 2; |
92 | unsigned int vc_kmalloced : 1; | ||
93 | unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */ | 92 | unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */ |
94 | unsigned char vc_utf_count; | 93 | unsigned char vc_utf_count; |
95 | int vc_utf_char; | 94 | int vc_utf_char; |
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 2dac064d8359..0026f267da20 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h | |||
@@ -3,7 +3,6 @@ | |||
3 | 3 | ||
4 | #ifdef CONFIG_CRASH_DUMP | 4 | #ifdef CONFIG_CRASH_DUMP |
5 | #include <linux/kexec.h> | 5 | #include <linux/kexec.h> |
6 | #include <linux/smp_lock.h> | ||
7 | #include <linux/device.h> | 6 | #include <linux/device.h> |
8 | #include <linux/proc_fs.h> | 7 | #include <linux/proc_fs.h> |
9 | 8 | ||
diff --git a/include/linux/device.h b/include/linux/device.h index ed4e39f2c423..aebb81036db2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -25,8 +25,6 @@ | |||
25 | #include <asm/atomic.h> | 25 | #include <asm/atomic.h> |
26 | #include <asm/device.h> | 26 | #include <asm/device.h> |
27 | 27 | ||
28 | #define BUS_ID_SIZE 20 | ||
29 | |||
30 | struct device; | 28 | struct device; |
31 | struct device_private; | 29 | struct device_private; |
32 | struct device_driver; | 30 | struct device_driver; |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 45257475623c..8246c697863d 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -2,7 +2,9 @@ | |||
2 | #define LINUX_HARDIRQ_H | 2 | #define LINUX_HARDIRQ_H |
3 | 3 | ||
4 | #include <linux/preempt.h> | 4 | #include <linux/preempt.h> |
5 | #ifdef CONFIG_PREEMPT | ||
5 | #include <linux/smp_lock.h> | 6 | #include <linux/smp_lock.h> |
7 | #endif | ||
6 | #include <linux/lockdep.h> | 8 | #include <linux/lockdep.h> |
7 | #include <linux/ftrace_irq.h> | 9 | #include <linux/ftrace_irq.h> |
8 | #include <asm/hardirq.h> | 10 | #include <asm/hardirq.h> |
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 54648e625efd..4759917adc71 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -448,7 +448,7 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | |||
448 | 448 | ||
449 | static inline void timer_stats_account_hrtimer(struct hrtimer *timer) | 449 | static inline void timer_stats_account_hrtimer(struct hrtimer *timer) |
450 | { | 450 | { |
451 | if (likely(!timer->start_pid)) | 451 | if (likely(!timer->start_site)) |
452 | return; | 452 | return; |
453 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, | 453 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, |
454 | timer->function, timer->start_comm, 0); | 454 | timer->function, timer->start_comm, 0); |
diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h index 7796aed6cdd5..6a63807f714e 100644 --- a/include/linux/kmemleak.h +++ b/include/linux/kmemleak.h | |||
@@ -27,6 +27,7 @@ extern void kmemleak_init(void); | |||
27 | extern void kmemleak_alloc(const void *ptr, size_t size, int min_count, | 27 | extern void kmemleak_alloc(const void *ptr, size_t size, int min_count, |
28 | gfp_t gfp); | 28 | gfp_t gfp); |
29 | extern void kmemleak_free(const void *ptr); | 29 | extern void kmemleak_free(const void *ptr); |
30 | extern void kmemleak_free_part(const void *ptr, size_t size); | ||
30 | extern void kmemleak_padding(const void *ptr, unsigned long offset, | 31 | extern void kmemleak_padding(const void *ptr, unsigned long offset, |
31 | size_t size); | 32 | size_t size); |
32 | extern void kmemleak_not_leak(const void *ptr); | 33 | extern void kmemleak_not_leak(const void *ptr); |
@@ -71,6 +72,9 @@ static inline void kmemleak_alloc_recursive(const void *ptr, size_t size, | |||
71 | static inline void kmemleak_free(const void *ptr) | 72 | static inline void kmemleak_free(const void *ptr) |
72 | { | 73 | { |
73 | } | 74 | } |
75 | static inline void kmemleak_free_part(const void *ptr, size_t size) | ||
76 | { | ||
77 | } | ||
74 | static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags) | 78 | static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags) |
75 | { | 79 | { |
76 | } | 80 | } |
diff --git a/include/linux/lguest.h b/include/linux/lguest.h index 7bc1440fc473..dbf2479e808e 100644 --- a/include/linux/lguest.h +++ b/include/linux/lguest.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #define LG_CLOCK_MIN_DELTA 100UL | 11 | #define LG_CLOCK_MIN_DELTA 100UL |
12 | #define LG_CLOCK_MAX_DELTA ULONG_MAX | 12 | #define LG_CLOCK_MAX_DELTA ULONG_MAX |
13 | 13 | ||
14 | /*G:032 The second method of communicating with the Host is to via "struct | 14 | /*G:031 The second method of communicating with the Host is to via "struct |
15 | * lguest_data". Once the Guest's initialization hypercall tells the Host where | 15 | * lguest_data". Once the Guest's initialization hypercall tells the Host where |
16 | * this is, the Guest and Host both publish information in it. :*/ | 16 | * this is, the Guest and Host both publish information in it. :*/ |
17 | struct lguest_data | 17 | struct lguest_data |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 3d501db36a26..79b6d7fd4ac2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -385,6 +385,7 @@ enum { | |||
385 | not multiple of 16 bytes */ | 385 | not multiple of 16 bytes */ |
386 | ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firmware update warning */ | 386 | ATA_HORKAGE_FIRMWARE_WARN = (1 << 12), /* firmware update warning */ |
387 | ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ | 387 | ATA_HORKAGE_1_5_GBPS = (1 << 13), /* force 1.5 Gbps */ |
388 | ATA_HORKAGE_NOSETXFER = (1 << 14), /* skip SETXFER, SATA only */ | ||
388 | 389 | ||
389 | /* DMA mask for user DMA control: User visible values; DO NOT | 390 | /* DMA mask for user DMA control: User visible values; DO NOT |
390 | renumber */ | 391 | renumber */ |
diff --git a/include/linux/personality.h b/include/linux/personality.h index a84e9ff9b27e..126120819a0d 100644 --- a/include/linux/personality.h +++ b/include/linux/personality.h | |||
@@ -40,7 +40,10 @@ enum { | |||
40 | * Security-relevant compatibility flags that must be | 40 | * Security-relevant compatibility flags that must be |
41 | * cleared upon setuid or setgid exec: | 41 | * cleared upon setuid or setgid exec: |
42 | */ | 42 | */ |
43 | #define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC|ADDR_NO_RANDOMIZE) | 43 | #define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC | \ |
44 | ADDR_NO_RANDOMIZE | \ | ||
45 | ADDR_COMPAT_LAYOUT | \ | ||
46 | MMAP_PAGE_ZERO) | ||
44 | 47 | ||
45 | /* | 48 | /* |
46 | * Personality types. | 49 | * Personality types. |
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 7bc457593684..26361c4c037a 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
@@ -7,7 +7,6 @@ | |||
7 | #ifndef _LINUX_QUOTAOPS_ | 7 | #ifndef _LINUX_QUOTAOPS_ |
8 | #define _LINUX_QUOTAOPS_ | 8 | #define _LINUX_QUOTAOPS_ |
9 | 9 | ||
10 | #include <linux/smp_lock.h> | ||
11 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
12 | 11 | ||
13 | static inline struct quota_info *sb_dqopt(struct super_block *sb) | 12 | static inline struct quota_info *sb_dqopt(struct super_block *sb) |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 0085d758d645..16a982e389fb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -498,6 +498,15 @@ struct task_cputime { | |||
498 | .sum_exec_runtime = 0, \ | 498 | .sum_exec_runtime = 0, \ |
499 | } | 499 | } |
500 | 500 | ||
501 | /* | ||
502 | * Disable preemption until the scheduler is running. | ||
503 | * Reset by start_kernel()->sched_init()->init_idle(). | ||
504 | * | ||
505 | * We include PREEMPT_ACTIVE to avoid cond_resched() from working | ||
506 | * before the scheduler is active -- see should_resched(). | ||
507 | */ | ||
508 | #define INIT_PREEMPT_COUNT (1 + PREEMPT_ACTIVE) | ||
509 | |||
501 | /** | 510 | /** |
502 | * struct thread_group_cputimer - thread group interval timer counts | 511 | * struct thread_group_cputimer - thread group interval timer counts |
503 | * @cputime: thread group interval timers. | 512 | * @cputime: thread group interval timers. |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b47b3f039d14..f2c69a2cca17 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -1342,12 +1342,12 @@ static inline int skb_network_offset(const struct sk_buff *skb) | |||
1342 | * shifting the start of the packet by 2 bytes. Drivers should do this | 1342 | * shifting the start of the packet by 2 bytes. Drivers should do this |
1343 | * with: | 1343 | * with: |
1344 | * | 1344 | * |
1345 | * skb_reserve(NET_IP_ALIGN); | 1345 | * skb_reserve(skb, NET_IP_ALIGN); |
1346 | * | 1346 | * |
1347 | * The downside to this alignment of the IP header is that the DMA is now | 1347 | * The downside to this alignment of the IP header is that the DMA is now |
1348 | * unaligned. On some architectures the cost of an unaligned DMA is high | 1348 | * unaligned. On some architectures the cost of an unaligned DMA is high |
1349 | * and this cost outweighs the gains made by aligning the IP header. | 1349 | * and this cost outweighs the gains made by aligning the IP header. |
1350 | * | 1350 | * |
1351 | * Since this trade off varies between architectures, we allow NET_IP_ALIGN | 1351 | * Since this trade off varies between architectures, we allow NET_IP_ALIGN |
1352 | * to be overridden. | 1352 | * to be overridden. |
1353 | */ | 1353 | */ |
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 4dcbc2c71491..c1c862b1d01a 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/workqueue.h> | 11 | #include <linux/workqueue.h> |
12 | #include <linux/kobject.h> | 12 | #include <linux/kobject.h> |
13 | #include <linux/kmemtrace.h> | 13 | #include <linux/kmemtrace.h> |
14 | #include <linux/kmemleak.h> | ||
14 | 15 | ||
15 | enum stat_item { | 16 | enum stat_item { |
16 | ALLOC_FASTPATH, /* Allocation from cpu slab */ | 17 | ALLOC_FASTPATH, /* Allocation from cpu slab */ |
@@ -233,6 +234,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags) | |||
233 | unsigned int order = get_order(size); | 234 | unsigned int order = get_order(size); |
234 | void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order); | 235 | void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order); |
235 | 236 | ||
237 | kmemleak_alloc(ret, size, 1, flags); | ||
236 | trace_kmalloc(_THIS_IP_, ret, size, PAGE_SIZE << order, flags); | 238 | trace_kmalloc(_THIS_IP_, ret, size, PAGE_SIZE << order, flags); |
237 | 239 | ||
238 | return ret; | 240 | return ret; |
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index d8910b68e1bd..b99c625fddfe 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/uio.h> | 12 | #include <linux/uio.h> |
13 | #include <asm/byteorder.h> | 13 | #include <asm/byteorder.h> |
14 | #include <linux/scatterlist.h> | 14 | #include <linux/scatterlist.h> |
15 | #include <linux/smp_lock.h> | ||
16 | 15 | ||
17 | /* | 16 | /* |
18 | * Buffer adjustment | 17 | * Buffer adjustment |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index fa4242cdade8..80de7003d8c2 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -321,6 +321,8 @@ asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese, | |||
321 | siginfo_t __user *uinfo, | 321 | siginfo_t __user *uinfo, |
322 | const struct timespec __user *uts, | 322 | const struct timespec __user *uts, |
323 | size_t sigsetsize); | 323 | size_t sigsetsize); |
324 | asmlinkage long sys_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, | ||
325 | siginfo_t __user *uinfo); | ||
324 | asmlinkage long sys_kill(int pid, int sig); | 326 | asmlinkage long sys_kill(int pid, int sig); |
325 | asmlinkage long sys_tgkill(int tgid, int pid, int sig); | 327 | asmlinkage long sys_tgkill(int tgid, int pid, int sig); |
326 | asmlinkage long sys_tkill(int pid, int sig); | 328 | asmlinkage long sys_tkill(int pid, int sig); |
diff --git a/include/linux/usb.h b/include/linux/usb.h index 84929e914034..b1e3c2fbfe11 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h | |||
@@ -888,8 +888,6 @@ struct usb_driver { | |||
888 | * struct usb_device_driver - identifies USB device driver to usbcore | 888 | * struct usb_device_driver - identifies USB device driver to usbcore |
889 | * @name: The driver name should be unique among USB drivers, | 889 | * @name: The driver name should be unique among USB drivers, |
890 | * and should normally be the same as the module name. | 890 | * and should normally be the same as the module name. |
891 | * @nodename: Callback to provide a naming hint for a possible | ||
892 | * device node to create. | ||
893 | * @probe: Called to see if the driver is willing to manage a particular | 891 | * @probe: Called to see if the driver is willing to manage a particular |
894 | * device. If it is, probe returns zero and uses dev_set_drvdata() | 892 | * device. If it is, probe returns zero and uses dev_set_drvdata() |
895 | * to associate driver-specific data with the device. If unwilling | 893 | * to associate driver-specific data with the device. If unwilling |
@@ -924,6 +922,8 @@ extern struct bus_type usb_bus_type; | |||
924 | /** | 922 | /** |
925 | * struct usb_class_driver - identifies a USB driver that wants to use the USB major number | 923 | * struct usb_class_driver - identifies a USB driver that wants to use the USB major number |
926 | * @name: the usb class device name for this driver. Will show up in sysfs. | 924 | * @name: the usb class device name for this driver. Will show up in sysfs. |
925 | * @nodename: Callback to provide a naming hint for a possible | ||
926 | * device node to create. | ||
927 | * @fops: pointer to the struct file_operations of this driver. | 927 | * @fops: pointer to the struct file_operations of this driver. |
928 | * @minor_base: the start of the minor range for this driver. | 928 | * @minor_base: the start of the minor range for this driver. |
929 | * | 929 | * |
@@ -1046,6 +1046,8 @@ typedef void (*usb_complete_t)(struct urb *); | |||
1046 | * the device driver is saying that it provided this DMA address, | 1046 | * the device driver is saying that it provided this DMA address, |
1047 | * which the host controller driver should use in preference to the | 1047 | * which the host controller driver should use in preference to the |
1048 | * transfer_buffer. | 1048 | * transfer_buffer. |
1049 | * @sg: scatter gather buffer list | ||
1050 | * @num_sgs: number of entries in the sg list | ||
1049 | * @transfer_buffer_length: How big is transfer_buffer. The transfer may | 1051 | * @transfer_buffer_length: How big is transfer_buffer. The transfer may |
1050 | * be broken up into chunks according to the current maximum packet | 1052 | * be broken up into chunks according to the current maximum packet |
1051 | * size for the endpoint, which is a function of the configuration | 1053 | * size for the endpoint, which is a function of the configuration |
diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h deleted file mode 100644 index e115ae6df1da..000000000000 --- a/include/linux/usb/langwell_otg.h +++ /dev/null | |||
@@ -1,177 +0,0 @@ | |||
1 | /* | ||
2 | * Intel Langwell USB OTG transceiver driver | ||
3 | * Copyright (C) 2008, Intel Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #ifndef __LANGWELL_OTG_H__ | ||
21 | #define __LANGWELL_OTG_H__ | ||
22 | |||
23 | /* notify transceiver driver about OTG events */ | ||
24 | extern void langwell_update_transceiver(void); | ||
25 | /* HCD register bus driver */ | ||
26 | extern int langwell_register_host(struct pci_driver *host_driver); | ||
27 | /* HCD unregister bus driver */ | ||
28 | extern void langwell_unregister_host(struct pci_driver *host_driver); | ||
29 | /* DCD register bus driver */ | ||
30 | extern int langwell_register_peripheral(struct pci_driver *client_driver); | ||
31 | /* DCD unregister bus driver */ | ||
32 | extern void langwell_unregister_peripheral(struct pci_driver *client_driver); | ||
33 | /* No silent failure, output warning message */ | ||
34 | extern void langwell_otg_nsf_msg(unsigned long message); | ||
35 | |||
36 | #define CI_USBCMD 0x30 | ||
37 | # define USBCMD_RST BIT(1) | ||
38 | # define USBCMD_RS BIT(0) | ||
39 | #define CI_USBSTS 0x34 | ||
40 | # define USBSTS_SLI BIT(8) | ||
41 | # define USBSTS_URI BIT(6) | ||
42 | # define USBSTS_PCI BIT(2) | ||
43 | #define CI_PORTSC1 0x74 | ||
44 | # define PORTSC_PP BIT(12) | ||
45 | # define PORTSC_LS (BIT(11) | BIT(10)) | ||
46 | # define PORTSC_SUSP BIT(7) | ||
47 | # define PORTSC_CCS BIT(0) | ||
48 | #define CI_HOSTPC1 0xb4 | ||
49 | # define HOSTPC1_PHCD BIT(22) | ||
50 | #define CI_OTGSC 0xf4 | ||
51 | # define OTGSC_DPIE BIT(30) | ||
52 | # define OTGSC_1MSE BIT(29) | ||
53 | # define OTGSC_BSEIE BIT(28) | ||
54 | # define OTGSC_BSVIE BIT(27) | ||
55 | # define OTGSC_ASVIE BIT(26) | ||
56 | # define OTGSC_AVVIE BIT(25) | ||
57 | # define OTGSC_IDIE BIT(24) | ||
58 | # define OTGSC_DPIS BIT(22) | ||
59 | # define OTGSC_1MSS BIT(21) | ||
60 | # define OTGSC_BSEIS BIT(20) | ||
61 | # define OTGSC_BSVIS BIT(19) | ||
62 | # define OTGSC_ASVIS BIT(18) | ||
63 | # define OTGSC_AVVIS BIT(17) | ||
64 | # define OTGSC_IDIS BIT(16) | ||
65 | # define OTGSC_DPS BIT(14) | ||
66 | # define OTGSC_1MST BIT(13) | ||
67 | # define OTGSC_BSE BIT(12) | ||
68 | # define OTGSC_BSV BIT(11) | ||
69 | # define OTGSC_ASV BIT(10) | ||
70 | # define OTGSC_AVV BIT(9) | ||
71 | # define OTGSC_ID BIT(8) | ||
72 | # define OTGSC_HABA BIT(7) | ||
73 | # define OTGSC_HADP BIT(6) | ||
74 | # define OTGSC_IDPU BIT(5) | ||
75 | # define OTGSC_DP BIT(4) | ||
76 | # define OTGSC_OT BIT(3) | ||
77 | # define OTGSC_HAAR BIT(2) | ||
78 | # define OTGSC_VC BIT(1) | ||
79 | # define OTGSC_VD BIT(0) | ||
80 | # define OTGSC_INTEN_MASK (0x7f << 24) | ||
81 | # define OTGSC_INTSTS_MASK (0x7f << 16) | ||
82 | #define CI_USBMODE 0xf8 | ||
83 | # define USBMODE_CM (BIT(1) | BIT(0)) | ||
84 | # define USBMODE_IDLE 0 | ||
85 | # define USBMODE_DEVICE 0x2 | ||
86 | # define USBMODE_HOST 0x3 | ||
87 | |||
88 | #define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI) | ||
89 | |||
90 | struct otg_hsm { | ||
91 | /* Input */ | ||
92 | int a_bus_resume; | ||
93 | int a_bus_suspend; | ||
94 | int a_conn; | ||
95 | int a_sess_vld; | ||
96 | int a_srp_det; | ||
97 | int a_vbus_vld; | ||
98 | int b_bus_resume; | ||
99 | int b_bus_suspend; | ||
100 | int b_conn; | ||
101 | int b_se0_srp; | ||
102 | int b_sess_end; | ||
103 | int b_sess_vld; | ||
104 | int id; | ||
105 | |||
106 | /* Internal variables */ | ||
107 | int a_set_b_hnp_en; | ||
108 | int b_srp_done; | ||
109 | int b_hnp_enable; | ||
110 | |||
111 | /* Timeout indicator for timers */ | ||
112 | int a_wait_vrise_tmout; | ||
113 | int a_wait_bcon_tmout; | ||
114 | int a_aidl_bdis_tmout; | ||
115 | int b_ase0_brst_tmout; | ||
116 | int b_bus_suspend_tmout; | ||
117 | int b_srp_res_tmout; | ||
118 | |||
119 | /* Informative variables */ | ||
120 | int a_bus_drop; | ||
121 | int a_bus_req; | ||
122 | int a_clr_err; | ||
123 | int a_suspend_req; | ||
124 | int b_bus_req; | ||
125 | |||
126 | /* Output */ | ||
127 | int drv_vbus; | ||
128 | int loc_conn; | ||
129 | int loc_sof; | ||
130 | |||
131 | /* Others */ | ||
132 | int b_bus_suspend_vld; | ||
133 | }; | ||
134 | |||
135 | #define TA_WAIT_VRISE 100 | ||
136 | #define TA_WAIT_BCON 30000 | ||
137 | #define TA_AIDL_BDIS 15000 | ||
138 | #define TB_ASE0_BRST 5000 | ||
139 | #define TB_SE0_SRP 2 | ||
140 | #define TB_SRP_RES 100 | ||
141 | #define TB_BUS_SUSPEND 500 | ||
142 | |||
143 | struct langwell_otg_timer { | ||
144 | unsigned long expires; /* Number of count increase to timeout */ | ||
145 | unsigned long count; /* Tick counter */ | ||
146 | void (*function)(unsigned long); /* Timeout function */ | ||
147 | unsigned long data; /* Data passed to function */ | ||
148 | struct list_head list; | ||
149 | }; | ||
150 | |||
151 | struct langwell_otg { | ||
152 | struct otg_transceiver otg; | ||
153 | struct otg_hsm hsm; | ||
154 | void __iomem *regs; | ||
155 | unsigned region; | ||
156 | struct pci_driver *host_ops; | ||
157 | struct pci_driver *client_ops; | ||
158 | struct pci_dev *pdev; | ||
159 | struct work_struct work; | ||
160 | struct workqueue_struct *qwork; | ||
161 | spinlock_t lock; | ||
162 | spinlock_t wq_lock; | ||
163 | }; | ||
164 | |||
165 | static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg) | ||
166 | { | ||
167 | return container_of(otg, struct langwell_otg, otg); | ||
168 | } | ||
169 | |||
170 | #ifdef DEBUG | ||
171 | #define otg_dbg(fmt, args...) \ | ||
172 | printk(KERN_DEBUG fmt , ## args) | ||
173 | #else | ||
174 | #define otg_dbg(fmt, args...) \ | ||
175 | do { } while (0) | ||
176 | #endif /* DEBUG */ | ||
177 | #endif /* __LANGWELL_OTG_H__ */ | ||
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 44801d26a37a..0ec50ba62139 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -317,7 +317,8 @@ extern int usb_serial_generic_register(int debug); | |||
317 | extern void usb_serial_generic_deregister(void); | 317 | extern void usb_serial_generic_deregister(void); |
318 | extern void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, | 318 | extern void usb_serial_generic_resubmit_read_urb(struct usb_serial_port *port, |
319 | gfp_t mem_flags); | 319 | gfp_t mem_flags); |
320 | extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, | 320 | extern int usb_serial_handle_sysrq_char(struct tty_struct *tty, |
321 | struct usb_serial_port *port, | ||
321 | unsigned int ch); | 322 | unsigned int ch); |
322 | extern int usb_serial_handle_break(struct usb_serial_port *port); | 323 | extern int usb_serial_handle_break(struct usb_serial_port *port); |
323 | 324 | ||
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h index cec79adbe3ea..9c543d6ac535 100644 --- a/include/linux/virtio_net.h +++ b/include/linux/virtio_net.h | |||
@@ -27,6 +27,7 @@ | |||
27 | #define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ | 27 | #define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ |
28 | #define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ | 28 | #define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ |
29 | #define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */ | 29 | #define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */ |
30 | #define VIRTIO_NET_F_CTRL_RX_EXTRA 20 /* Extra RX mode control support */ | ||
30 | 31 | ||
31 | #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ | 32 | #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ |
32 | 33 | ||
@@ -81,14 +82,19 @@ typedef __u8 virtio_net_ctrl_ack; | |||
81 | #define VIRTIO_NET_ERR 1 | 82 | #define VIRTIO_NET_ERR 1 |
82 | 83 | ||
83 | /* | 84 | /* |
84 | * Control the RX mode, ie. promisucous and allmulti. PROMISC and | 85 | * Control the RX mode, ie. promisucous, allmulti, etc... |
85 | * ALLMULTI commands require an "out" sg entry containing a 1 byte | 86 | * All commands require an "out" sg entry containing a 1 byte |
86 | * state value, zero = disable, non-zero = enable. These commands | 87 | * state value, zero = disable, non-zero = enable. Commands |
87 | * are supported with the VIRTIO_NET_F_CTRL_RX feature. | 88 | * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature. |
89 | * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA. | ||
88 | */ | 90 | */ |
89 | #define VIRTIO_NET_CTRL_RX 0 | 91 | #define VIRTIO_NET_CTRL_RX 0 |
90 | #define VIRTIO_NET_CTRL_RX_PROMISC 0 | 92 | #define VIRTIO_NET_CTRL_RX_PROMISC 0 |
91 | #define VIRTIO_NET_CTRL_RX_ALLMULTI 1 | 93 | #define VIRTIO_NET_CTRL_RX_ALLMULTI 1 |
94 | #define VIRTIO_NET_CTRL_RX_ALLUNI 2 | ||
95 | #define VIRTIO_NET_CTRL_RX_NOMULTI 3 | ||
96 | #define VIRTIO_NET_CTRL_RX_NOUNI 4 | ||
97 | #define VIRTIO_NET_CTRL_RX_NOBCAST 5 | ||
92 | 98 | ||
93 | /* | 99 | /* |
94 | * Control the MAC filter table. | 100 | * Control the MAC filter table. |
diff --git a/include/net/sock.h b/include/net/sock.h index 2c0da9239b95..950409dcec3d 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -104,15 +104,15 @@ struct net; | |||
104 | 104 | ||
105 | /** | 105 | /** |
106 | * struct sock_common - minimal network layer representation of sockets | 106 | * struct sock_common - minimal network layer representation of sockets |
107 | * @skc_node: main hash linkage for various protocol lookup tables | ||
108 | * @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol | ||
109 | * @skc_refcnt: reference count | ||
110 | * @skc_hash: hash value used with various protocol lookup tables | ||
107 | * @skc_family: network address family | 111 | * @skc_family: network address family |
108 | * @skc_state: Connection state | 112 | * @skc_state: Connection state |
109 | * @skc_reuse: %SO_REUSEADDR setting | 113 | * @skc_reuse: %SO_REUSEADDR setting |
110 | * @skc_bound_dev_if: bound device index if != 0 | 114 | * @skc_bound_dev_if: bound device index if != 0 |
111 | * @skc_node: main hash linkage for various protocol lookup tables | ||
112 | * @skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol | ||
113 | * @skc_bind_node: bind hash linkage for various protocol lookup tables | 115 | * @skc_bind_node: bind hash linkage for various protocol lookup tables |
114 | * @skc_refcnt: reference count | ||
115 | * @skc_hash: hash value used with various protocol lookup tables | ||
116 | * @skc_prot: protocol handlers inside a network family | 116 | * @skc_prot: protocol handlers inside a network family |
117 | * @skc_net: reference to the network namespace of this socket | 117 | * @skc_net: reference to the network namespace of this socket |
118 | * | 118 | * |
@@ -120,17 +120,21 @@ struct net; | |||
120 | * for struct sock and struct inet_timewait_sock. | 120 | * for struct sock and struct inet_timewait_sock. |
121 | */ | 121 | */ |
122 | struct sock_common { | 122 | struct sock_common { |
123 | unsigned short skc_family; | 123 | /* |
124 | volatile unsigned char skc_state; | 124 | * first fields are not copied in sock_copy() |
125 | unsigned char skc_reuse; | 125 | */ |
126 | int skc_bound_dev_if; | ||
127 | union { | 126 | union { |
128 | struct hlist_node skc_node; | 127 | struct hlist_node skc_node; |
129 | struct hlist_nulls_node skc_nulls_node; | 128 | struct hlist_nulls_node skc_nulls_node; |
130 | }; | 129 | }; |
131 | struct hlist_node skc_bind_node; | ||
132 | atomic_t skc_refcnt; | 130 | atomic_t skc_refcnt; |
131 | |||
133 | unsigned int skc_hash; | 132 | unsigned int skc_hash; |
133 | unsigned short skc_family; | ||
134 | volatile unsigned char skc_state; | ||
135 | unsigned char skc_reuse; | ||
136 | int skc_bound_dev_if; | ||
137 | struct hlist_node skc_bind_node; | ||
134 | struct proto *skc_prot; | 138 | struct proto *skc_prot; |
135 | #ifdef CONFIG_NET_NS | 139 | #ifdef CONFIG_NET_NS |
136 | struct net *skc_net; | 140 | struct net *skc_net; |
@@ -208,15 +212,17 @@ struct sock { | |||
208 | * don't add nothing before this first member (__sk_common) --acme | 212 | * don't add nothing before this first member (__sk_common) --acme |
209 | */ | 213 | */ |
210 | struct sock_common __sk_common; | 214 | struct sock_common __sk_common; |
215 | #define sk_node __sk_common.skc_node | ||
216 | #define sk_nulls_node __sk_common.skc_nulls_node | ||
217 | #define sk_refcnt __sk_common.skc_refcnt | ||
218 | |||
219 | #define sk_copy_start __sk_common.skc_hash | ||
220 | #define sk_hash __sk_common.skc_hash | ||
211 | #define sk_family __sk_common.skc_family | 221 | #define sk_family __sk_common.skc_family |
212 | #define sk_state __sk_common.skc_state | 222 | #define sk_state __sk_common.skc_state |
213 | #define sk_reuse __sk_common.skc_reuse | 223 | #define sk_reuse __sk_common.skc_reuse |
214 | #define sk_bound_dev_if __sk_common.skc_bound_dev_if | 224 | #define sk_bound_dev_if __sk_common.skc_bound_dev_if |
215 | #define sk_node __sk_common.skc_node | ||
216 | #define sk_nulls_node __sk_common.skc_nulls_node | ||
217 | #define sk_bind_node __sk_common.skc_bind_node | 225 | #define sk_bind_node __sk_common.skc_bind_node |
218 | #define sk_refcnt __sk_common.skc_refcnt | ||
219 | #define sk_hash __sk_common.skc_hash | ||
220 | #define sk_prot __sk_common.skc_prot | 226 | #define sk_prot __sk_common.skc_prot |
221 | #define sk_net __sk_common.skc_net | 227 | #define sk_net __sk_common.skc_net |
222 | kmemcheck_bitfield_begin(flags); | 228 | kmemcheck_bitfield_begin(flags); |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 19f4150f4d4d..88af84306471 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1425,6 +1425,11 @@ struct tcp_request_sock_ops { | |||
1425 | #ifdef CONFIG_TCP_MD5SIG | 1425 | #ifdef CONFIG_TCP_MD5SIG |
1426 | struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, | 1426 | struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, |
1427 | struct request_sock *req); | 1427 | struct request_sock *req); |
1428 | int (*calc_md5_hash) (char *location, | ||
1429 | struct tcp_md5sig_key *md5, | ||
1430 | struct sock *sk, | ||
1431 | struct request_sock *req, | ||
1432 | struct sk_buff *skb); | ||
1428 | #endif | 1433 | #endif |
1429 | }; | 1434 | }; |
1430 | 1435 | ||
diff --git a/include/trace/events/block.h b/include/trace/events/block.h index d6b05f42dd44..9a74b468a229 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h | |||
@@ -1,3 +1,6 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM block | ||
3 | |||
1 | #if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_BLOCK_H | 5 | #define _TRACE_BLOCK_H |
3 | 6 | ||
@@ -5,9 +8,6 @@ | |||
5 | #include <linux/blkdev.h> | 8 | #include <linux/blkdev.h> |
6 | #include <linux/tracepoint.h> | 9 | #include <linux/tracepoint.h> |
7 | 10 | ||
8 | #undef TRACE_SYSTEM | ||
9 | #define TRACE_SYSTEM block | ||
10 | |||
11 | TRACE_EVENT(block_rq_abort, | 11 | TRACE_EVENT(block_rq_abort, |
12 | 12 | ||
13 | TP_PROTO(struct request_queue *q, struct request *rq), | 13 | TP_PROTO(struct request_queue *q, struct request *rq), |
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index acf4cc9cd36d..7d8b5bc74185 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h | |||
@@ -1,9 +1,9 @@ | |||
1 | #if !defined(_TRACE_EXT4_H) || defined(TRACE_HEADER_MULTI_READ) | ||
2 | #define _TRACE_EXT4_H | ||
3 | |||
4 | #undef TRACE_SYSTEM | 1 | #undef TRACE_SYSTEM |
5 | #define TRACE_SYSTEM ext4 | 2 | #define TRACE_SYSTEM ext4 |
6 | 3 | ||
4 | #if !defined(_TRACE_EXT4_H) || defined(TRACE_HEADER_MULTI_READ) | ||
5 | #define _TRACE_EXT4_H | ||
6 | |||
7 | #include <linux/writeback.h> | 7 | #include <linux/writeback.h> |
8 | #include "../../../fs/ext4/ext4.h" | 8 | #include "../../../fs/ext4/ext4.h" |
9 | #include "../../../fs/ext4/mballoc.h" | 9 | #include "../../../fs/ext4/mballoc.h" |
@@ -34,7 +34,8 @@ TRACE_EVENT(ext4_free_inode, | |||
34 | 34 | ||
35 | TP_printk("dev %s ino %lu mode %d uid %u gid %u blocks %llu", | 35 | TP_printk("dev %s ino %lu mode %d uid %u gid %u blocks %llu", |
36 | jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->mode, | 36 | jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->mode, |
37 | __entry->uid, __entry->gid, __entry->blocks) | 37 | __entry->uid, __entry->gid, |
38 | (unsigned long long) __entry->blocks) | ||
38 | ); | 39 | ); |
39 | 40 | ||
40 | TRACE_EVENT(ext4_request_inode, | 41 | TRACE_EVENT(ext4_request_inode, |
@@ -189,7 +190,7 @@ TRACE_EVENT(ext4_journalled_write_end, | |||
189 | __entry->copied) | 190 | __entry->copied) |
190 | ); | 191 | ); |
191 | 192 | ||
192 | TRACE_EVENT(ext4_da_writepage, | 193 | TRACE_EVENT(ext4_writepage, |
193 | TP_PROTO(struct inode *inode, struct page *page), | 194 | TP_PROTO(struct inode *inode, struct page *page), |
194 | 195 | ||
195 | TP_ARGS(inode, page), | 196 | TP_ARGS(inode, page), |
@@ -341,49 +342,6 @@ TRACE_EVENT(ext4_da_write_end, | |||
341 | __entry->copied) | 342 | __entry->copied) |
342 | ); | 343 | ); |
343 | 344 | ||
344 | TRACE_EVENT(ext4_normal_writepage, | ||
345 | TP_PROTO(struct inode *inode, struct page *page), | ||
346 | |||
347 | TP_ARGS(inode, page), | ||
348 | |||
349 | TP_STRUCT__entry( | ||
350 | __field( dev_t, dev ) | ||
351 | __field( ino_t, ino ) | ||
352 | __field( pgoff_t, index ) | ||
353 | ), | ||
354 | |||
355 | TP_fast_assign( | ||
356 | __entry->dev = inode->i_sb->s_dev; | ||
357 | __entry->ino = inode->i_ino; | ||
358 | __entry->index = page->index; | ||
359 | ), | ||
360 | |||
361 | TP_printk("dev %s ino %lu page_index %lu", | ||
362 | jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index) | ||
363 | ); | ||
364 | |||
365 | TRACE_EVENT(ext4_journalled_writepage, | ||
366 | TP_PROTO(struct inode *inode, struct page *page), | ||
367 | |||
368 | TP_ARGS(inode, page), | ||
369 | |||
370 | TP_STRUCT__entry( | ||
371 | __field( dev_t, dev ) | ||
372 | __field( ino_t, ino ) | ||
373 | __field( pgoff_t, index ) | ||
374 | |||
375 | ), | ||
376 | |||
377 | TP_fast_assign( | ||
378 | __entry->dev = inode->i_sb->s_dev; | ||
379 | __entry->ino = inode->i_ino; | ||
380 | __entry->index = page->index; | ||
381 | ), | ||
382 | |||
383 | TP_printk("dev %s ino %lu page_index %lu", | ||
384 | jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index) | ||
385 | ); | ||
386 | |||
387 | TRACE_EVENT(ext4_discard_blocks, | 345 | TRACE_EVENT(ext4_discard_blocks, |
388 | TP_PROTO(struct super_block *sb, unsigned long long blk, | 346 | TP_PROTO(struct super_block *sb, unsigned long long blk, |
389 | unsigned long long count), | 347 | unsigned long long count), |
diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h index b0c7ede55eb1..1cb0c3aa11e6 100644 --- a/include/trace/events/irq.h +++ b/include/trace/events/irq.h | |||
@@ -1,12 +1,12 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM irq | ||
3 | |||
1 | #if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_IRQ_H | 5 | #define _TRACE_IRQ_H |
3 | 6 | ||
4 | #include <linux/tracepoint.h> | 7 | #include <linux/tracepoint.h> |
5 | #include <linux/interrupt.h> | 8 | #include <linux/interrupt.h> |
6 | 9 | ||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM irq | ||
9 | |||
10 | #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } | 10 | #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } |
11 | #define show_softirq_name(val) \ | 11 | #define show_softirq_name(val) \ |
12 | __print_symbolic(val, \ | 12 | __print_symbolic(val, \ |
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h index 845b0b4b48fd..10813fa0c8d0 100644 --- a/include/trace/events/jbd2.h +++ b/include/trace/events/jbd2.h | |||
@@ -1,12 +1,12 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM jbd2 | ||
3 | |||
1 | #if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_JBD2_H | 5 | #define _TRACE_JBD2_H |
3 | 6 | ||
4 | #include <linux/jbd2.h> | 7 | #include <linux/jbd2.h> |
5 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
6 | 9 | ||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM jbd2 | ||
9 | |||
10 | TRACE_EVENT(jbd2_checkpoint, | 10 | TRACE_EVENT(jbd2_checkpoint, |
11 | 11 | ||
12 | TP_PROTO(journal_t *journal, int result), | 12 | TP_PROTO(journal_t *journal, int result), |
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h index 9baba50d6512..1493c541f9c4 100644 --- a/include/trace/events/kmem.h +++ b/include/trace/events/kmem.h | |||
@@ -1,12 +1,12 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM kmem | ||
3 | |||
1 | #if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_KMEM_H | 5 | #define _TRACE_KMEM_H |
3 | 6 | ||
4 | #include <linux/types.h> | 7 | #include <linux/types.h> |
5 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
6 | 9 | ||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM kmem | ||
9 | |||
10 | /* | 10 | /* |
11 | * The order of these masks is important. Matching masks will be seen | 11 | * The order of these masks is important. Matching masks will be seen |
12 | * first and the left over flags will end up showing by themselves. | 12 | * first and the left over flags will end up showing by themselves. |
diff --git a/include/trace/events/lockdep.h b/include/trace/events/lockdep.h index 0e956c9dfd7e..bcf1d209a00d 100644 --- a/include/trace/events/lockdep.h +++ b/include/trace/events/lockdep.h | |||
@@ -1,12 +1,12 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM lockdep | ||
3 | |||
1 | #if !defined(_TRACE_LOCKDEP_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_LOCKDEP_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_LOCKDEP_H | 5 | #define _TRACE_LOCKDEP_H |
3 | 6 | ||
4 | #include <linux/lockdep.h> | 7 | #include <linux/lockdep.h> |
5 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
6 | 9 | ||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM lockdep | ||
9 | |||
10 | #ifdef CONFIG_LOCKDEP | 10 | #ifdef CONFIG_LOCKDEP |
11 | 11 | ||
12 | TRACE_EVENT(lock_acquire, | 12 | TRACE_EVENT(lock_acquire, |
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index 24ab5bcff7b2..8949bb7eb082 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h | |||
@@ -1,12 +1,12 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM sched | ||
3 | |||
1 | #if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_SCHED_H | 5 | #define _TRACE_SCHED_H |
3 | 6 | ||
4 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
5 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
6 | 9 | ||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM sched | ||
9 | |||
10 | /* | 10 | /* |
11 | * Tracepoint for calling kthread_stop, performed to end a kthread: | 11 | * Tracepoint for calling kthread_stop, performed to end a kthread: |
12 | */ | 12 | */ |
diff --git a/include/trace/events/skb.h b/include/trace/events/skb.h index 1e8fabb57c06..e499863b9669 100644 --- a/include/trace/events/skb.h +++ b/include/trace/events/skb.h | |||
@@ -1,12 +1,12 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM skb | ||
3 | |||
1 | #if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_SKB_H | 5 | #define _TRACE_SKB_H |
3 | 6 | ||
4 | #include <linux/skbuff.h> | 7 | #include <linux/skbuff.h> |
5 | #include <linux/tracepoint.h> | 8 | #include <linux/tracepoint.h> |
6 | 9 | ||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM skb | ||
9 | |||
10 | /* | 10 | /* |
11 | * Tracepoint for free an sk_buff: | 11 | * Tracepoint for free an sk_buff: |
12 | */ | 12 | */ |
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h index 035f1bff288e..fcfd9a1e4b96 100644 --- a/include/trace/events/workqueue.h +++ b/include/trace/events/workqueue.h | |||
@@ -1,3 +1,6 @@ | |||
1 | #undef TRACE_SYSTEM | ||
2 | #define TRACE_SYSTEM workqueue | ||
3 | |||
1 | #if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ) |
2 | #define _TRACE_WORKQUEUE_H | 5 | #define _TRACE_WORKQUEUE_H |
3 | 6 | ||
@@ -5,9 +8,6 @@ | |||
5 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
6 | #include <linux/tracepoint.h> | 9 | #include <linux/tracepoint.h> |
7 | 10 | ||
8 | #undef TRACE_SYSTEM | ||
9 | #define TRACE_SYSTEM workqueue | ||
10 | |||
11 | TRACE_EVENT(workqueue_insertion, | 11 | TRACE_EVENT(workqueue_insertion, |
12 | 12 | ||
13 | TP_PROTO(struct task_struct *wq_thread, struct work_struct *work), | 13 | TP_PROTO(struct task_struct *wq_thread, struct work_struct *work), |
diff --git a/kernel/futex.c b/kernel/futex.c index 794c862125fe..0672ff88f159 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -247,6 +247,7 @@ again: | |||
247 | if (err < 0) | 247 | if (err < 0) |
248 | return err; | 248 | return err; |
249 | 249 | ||
250 | page = compound_head(page); | ||
250 | lock_page(page); | 251 | lock_page(page); |
251 | if (!page->mapping) { | 252 | if (!page->mapping) { |
252 | unlock_page(page); | 253 | unlock_page(page); |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 9002958a96e7..49da79ab8486 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -191,6 +191,46 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, | |||
191 | } | 191 | } |
192 | } | 192 | } |
193 | 193 | ||
194 | |||
195 | /* | ||
196 | * Get the preferred target CPU for NOHZ | ||
197 | */ | ||
198 | static int hrtimer_get_target(int this_cpu, int pinned) | ||
199 | { | ||
200 | #ifdef CONFIG_NO_HZ | ||
201 | if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu)) { | ||
202 | int preferred_cpu = get_nohz_load_balancer(); | ||
203 | |||
204 | if (preferred_cpu >= 0) | ||
205 | return preferred_cpu; | ||
206 | } | ||
207 | #endif | ||
208 | return this_cpu; | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * With HIGHRES=y we do not migrate the timer when it is expiring | ||
213 | * before the next event on the target cpu because we cannot reprogram | ||
214 | * the target cpu hardware and we would cause it to fire late. | ||
215 | * | ||
216 | * Called with cpu_base->lock of target cpu held. | ||
217 | */ | ||
218 | static int | ||
219 | hrtimer_check_target(struct hrtimer *timer, struct hrtimer_clock_base *new_base) | ||
220 | { | ||
221 | #ifdef CONFIG_HIGH_RES_TIMERS | ||
222 | ktime_t expires; | ||
223 | |||
224 | if (!new_base->cpu_base->hres_active) | ||
225 | return 0; | ||
226 | |||
227 | expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); | ||
228 | return expires.tv64 <= new_base->cpu_base->expires_next.tv64; | ||
229 | #else | ||
230 | return 0; | ||
231 | #endif | ||
232 | } | ||
233 | |||
194 | /* | 234 | /* |
195 | * Switch the timer base to the current CPU when possible. | 235 | * Switch the timer base to the current CPU when possible. |
196 | */ | 236 | */ |
@@ -200,16 +240,8 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, | |||
200 | { | 240 | { |
201 | struct hrtimer_clock_base *new_base; | 241 | struct hrtimer_clock_base *new_base; |
202 | struct hrtimer_cpu_base *new_cpu_base; | 242 | struct hrtimer_cpu_base *new_cpu_base; |
203 | int cpu, preferred_cpu = -1; | 243 | int this_cpu = smp_processor_id(); |
204 | 244 | int cpu = hrtimer_get_target(this_cpu, pinned); | |
205 | cpu = smp_processor_id(); | ||
206 | #if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP) | ||
207 | if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) { | ||
208 | preferred_cpu = get_nohz_load_balancer(); | ||
209 | if (preferred_cpu >= 0) | ||
210 | cpu = preferred_cpu; | ||
211 | } | ||
212 | #endif | ||
213 | 245 | ||
214 | again: | 246 | again: |
215 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); | 247 | new_cpu_base = &per_cpu(hrtimer_bases, cpu); |
@@ -217,7 +249,7 @@ again: | |||
217 | 249 | ||
218 | if (base != new_base) { | 250 | if (base != new_base) { |
219 | /* | 251 | /* |
220 | * We are trying to schedule the timer on the local CPU. | 252 | * We are trying to move timer to new_base. |
221 | * However we can't change timer's base while it is running, | 253 | * However we can't change timer's base while it is running, |
222 | * so we keep it on the same CPU. No hassle vs. reprogramming | 254 | * so we keep it on the same CPU. No hassle vs. reprogramming |
223 | * the event source in the high resolution case. The softirq | 255 | * the event source in the high resolution case. The softirq |
@@ -233,38 +265,12 @@ again: | |||
233 | spin_unlock(&base->cpu_base->lock); | 265 | spin_unlock(&base->cpu_base->lock); |
234 | spin_lock(&new_base->cpu_base->lock); | 266 | spin_lock(&new_base->cpu_base->lock); |
235 | 267 | ||
236 | /* Optimized away for NOHZ=n SMP=n */ | 268 | if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) { |
237 | if (cpu == preferred_cpu) { | 269 | cpu = this_cpu; |
238 | /* Calculate clock monotonic expiry time */ | 270 | spin_unlock(&new_base->cpu_base->lock); |
239 | #ifdef CONFIG_HIGH_RES_TIMERS | 271 | spin_lock(&base->cpu_base->lock); |
240 | ktime_t expires = ktime_sub(hrtimer_get_expires(timer), | 272 | timer->base = base; |
241 | new_base->offset); | 273 | goto again; |
242 | #else | ||
243 | ktime_t expires = hrtimer_get_expires(timer); | ||
244 | #endif | ||
245 | |||
246 | /* | ||
247 | * Get the next event on target cpu from the | ||
248 | * clock events layer. | ||
249 | * This covers the highres=off nohz=on case as well. | ||
250 | */ | ||
251 | ktime_t next = clockevents_get_next_event(cpu); | ||
252 | |||
253 | ktime_t delta = ktime_sub(expires, next); | ||
254 | |||
255 | /* | ||
256 | * We do not migrate the timer when it is expiring | ||
257 | * before the next event on the target cpu because | ||
258 | * we cannot reprogram the target cpu hardware and | ||
259 | * we would cause it to fire late. | ||
260 | */ | ||
261 | if (delta.tv64 < 0) { | ||
262 | cpu = smp_processor_id(); | ||
263 | spin_unlock(&new_base->cpu_base->lock); | ||
264 | spin_lock(&base->cpu_base->lock); | ||
265 | timer->base = base; | ||
266 | goto again; | ||
267 | } | ||
268 | } | 274 | } |
269 | timer->base = new_base; | 275 | timer->base = new_base; |
270 | } | 276 | } |
@@ -1276,14 +1282,22 @@ void hrtimer_interrupt(struct clock_event_device *dev) | |||
1276 | 1282 | ||
1277 | expires_next.tv64 = KTIME_MAX; | 1283 | expires_next.tv64 = KTIME_MAX; |
1278 | 1284 | ||
1285 | spin_lock(&cpu_base->lock); | ||
1286 | /* | ||
1287 | * We set expires_next to KTIME_MAX here with cpu_base->lock | ||
1288 | * held to prevent that a timer is enqueued in our queue via | ||
1289 | * the migration code. This does not affect enqueueing of | ||
1290 | * timers which run their callback and need to be requeued on | ||
1291 | * this CPU. | ||
1292 | */ | ||
1293 | cpu_base->expires_next.tv64 = KTIME_MAX; | ||
1294 | |||
1279 | base = cpu_base->clock_base; | 1295 | base = cpu_base->clock_base; |
1280 | 1296 | ||
1281 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { | 1297 | for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { |
1282 | ktime_t basenow; | 1298 | ktime_t basenow; |
1283 | struct rb_node *node; | 1299 | struct rb_node *node; |
1284 | 1300 | ||
1285 | spin_lock(&cpu_base->lock); | ||
1286 | |||
1287 | basenow = ktime_add(now, base->offset); | 1301 | basenow = ktime_add(now, base->offset); |
1288 | 1302 | ||
1289 | while ((node = base->first)) { | 1303 | while ((node = base->first)) { |
@@ -1316,11 +1330,15 @@ void hrtimer_interrupt(struct clock_event_device *dev) | |||
1316 | 1330 | ||
1317 | __run_hrtimer(timer); | 1331 | __run_hrtimer(timer); |
1318 | } | 1332 | } |
1319 | spin_unlock(&cpu_base->lock); | ||
1320 | base++; | 1333 | base++; |
1321 | } | 1334 | } |
1322 | 1335 | ||
1336 | /* | ||
1337 | * Store the new expiry value so the migration code can verify | ||
1338 | * against it. | ||
1339 | */ | ||
1323 | cpu_base->expires_next = expires_next; | 1340 | cpu_base->expires_next = expires_next; |
1341 | spin_unlock(&cpu_base->lock); | ||
1324 | 1342 | ||
1325 | /* Reprogramming necessary ? */ | 1343 | /* Reprogramming necessary ? */ |
1326 | if (expires_next.tv64 != KTIME_MAX) { | 1344 | if (expires_next.tv64 != KTIME_MAX) { |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index c0fa54b276d9..16b5739c516a 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -237,13 +237,9 @@ static int __kprobes collect_garbage_slots(void) | |||
237 | { | 237 | { |
238 | struct kprobe_insn_page *kip; | 238 | struct kprobe_insn_page *kip; |
239 | struct hlist_node *pos, *next; | 239 | struct hlist_node *pos, *next; |
240 | int safety; | ||
241 | 240 | ||
242 | /* Ensure no-one is preepmted on the garbages */ | 241 | /* Ensure no-one is preepmted on the garbages */ |
243 | mutex_unlock(&kprobe_insn_mutex); | 242 | if (check_safety()) |
244 | safety = check_safety(); | ||
245 | mutex_lock(&kprobe_insn_mutex); | ||
246 | if (safety != 0) | ||
247 | return -EAGAIN; | 243 | return -EAGAIN; |
248 | 244 | ||
249 | hlist_for_each_entry_safe(kip, pos, next, &kprobe_insn_pages, hlist) { | 245 | hlist_for_each_entry_safe(kip, pos, next, &kprobe_insn_pages, hlist) { |
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index a641eb753b8c..7bc888dfd06a 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -2665,6 +2665,7 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, | |||
2665 | header.size += sizeof(cpu_entry); | 2665 | header.size += sizeof(cpu_entry); |
2666 | 2666 | ||
2667 | cpu_entry.cpu = raw_smp_processor_id(); | 2667 | cpu_entry.cpu = raw_smp_processor_id(); |
2668 | cpu_entry.reserved = 0; | ||
2668 | } | 2669 | } |
2669 | 2670 | ||
2670 | if (sample_type & PERF_SAMPLE_PERIOD) | 2671 | if (sample_type & PERF_SAMPLE_PERIOD) |
diff --git a/kernel/pid.c b/kernel/pid.c index 5fa1db48d8b7..31310b5d3f50 100644 --- a/kernel/pid.c +++ b/kernel/pid.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/pid_namespace.h> | 36 | #include <linux/pid_namespace.h> |
37 | #include <linux/init_task.h> | 37 | #include <linux/init_task.h> |
38 | #include <linux/syscalls.h> | 38 | #include <linux/syscalls.h> |
39 | #include <linux/kmemleak.h> | ||
40 | 39 | ||
41 | #define pid_hashfn(nr, ns) \ | 40 | #define pid_hashfn(nr, ns) \ |
42 | hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) | 41 | hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) |
@@ -513,12 +512,6 @@ void __init pidhash_init(void) | |||
513 | pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash))); | 512 | pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash))); |
514 | if (!pid_hash) | 513 | if (!pid_hash) |
515 | panic("Could not alloc pidhash!\n"); | 514 | panic("Could not alloc pidhash!\n"); |
516 | /* | ||
517 | * pid_hash contains references to allocated struct pid objects and it | ||
518 | * must be scanned by kmemleak to avoid false positives. | ||
519 | */ | ||
520 | kmemleak_alloc(pid_hash, pidhash_size * sizeof(*(pid_hash)), 0, | ||
521 | GFP_KERNEL); | ||
522 | for (i = 0; i < pidhash_size; i++) | 515 | for (i = 0; i < pidhash_size; i++) |
523 | INIT_HLIST_HEAD(&pid_hash[i]); | 516 | INIT_HLIST_HEAD(&pid_hash[i]); |
524 | } | 517 | } |
diff --git a/kernel/power/user.c b/kernel/power/user.c index ed97375daae9..bf0014d6a5f0 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/console.h> | 23 | #include <linux/console.h> |
24 | #include <linux/cpu.h> | 24 | #include <linux/cpu.h> |
25 | #include <linux/freezer.h> | 25 | #include <linux/freezer.h> |
26 | #include <linux/smp_lock.h> | ||
27 | #include <scsi/scsi_scan.h> | 26 | #include <scsi/scsi_scan.h> |
28 | 27 | ||
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 0dccfbba6d26..7717b95c2027 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -1533,7 +1533,7 @@ void __init __rcu_init(void) | |||
1533 | int j; | 1533 | int j; |
1534 | struct rcu_node *rnp; | 1534 | struct rcu_node *rnp; |
1535 | 1535 | ||
1536 | printk(KERN_WARNING "Experimental hierarchical RCU implementation.\n"); | 1536 | printk(KERN_INFO "Hierarchical RCU implementation.\n"); |
1537 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR | 1537 | #ifdef CONFIG_RCU_CPU_STALL_DETECTOR |
1538 | printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n"); | 1538 | printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n"); |
1539 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ | 1539 | #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ |
@@ -1546,7 +1546,6 @@ void __init __rcu_init(void) | |||
1546 | rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long)i); | 1546 | rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE, (void *)(long)i); |
1547 | /* Register notifier for non-boot CPUs */ | 1547 | /* Register notifier for non-boot CPUs */ |
1548 | register_cpu_notifier(&rcu_nb); | 1548 | register_cpu_notifier(&rcu_nb); |
1549 | printk(KERN_WARNING "Experimental hierarchical RCU init done.\n"); | ||
1550 | } | 1549 | } |
1551 | 1550 | ||
1552 | module_param(blimit, int, 0); | 1551 | module_param(blimit, int, 0); |
diff --git a/kernel/sched.c b/kernel/sched.c index 7c9098d186e6..98972d366fdc 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -493,6 +493,7 @@ struct rt_rq { | |||
493 | #endif | 493 | #endif |
494 | #ifdef CONFIG_SMP | 494 | #ifdef CONFIG_SMP |
495 | unsigned long rt_nr_migratory; | 495 | unsigned long rt_nr_migratory; |
496 | unsigned long rt_nr_total; | ||
496 | int overloaded; | 497 | int overloaded; |
497 | struct plist_head pushable_tasks; | 498 | struct plist_head pushable_tasks; |
498 | #endif | 499 | #endif |
@@ -2571,15 +2572,37 @@ static void __sched_fork(struct task_struct *p) | |||
2571 | p->se.avg_wakeup = sysctl_sched_wakeup_granularity; | 2572 | p->se.avg_wakeup = sysctl_sched_wakeup_granularity; |
2572 | 2573 | ||
2573 | #ifdef CONFIG_SCHEDSTATS | 2574 | #ifdef CONFIG_SCHEDSTATS |
2574 | p->se.wait_start = 0; | 2575 | p->se.wait_start = 0; |
2575 | p->se.sum_sleep_runtime = 0; | 2576 | p->se.wait_max = 0; |
2576 | p->se.sleep_start = 0; | 2577 | p->se.wait_count = 0; |
2577 | p->se.block_start = 0; | 2578 | p->se.wait_sum = 0; |
2578 | p->se.sleep_max = 0; | 2579 | |
2579 | p->se.block_max = 0; | 2580 | p->se.sleep_start = 0; |
2580 | p->se.exec_max = 0; | 2581 | p->se.sleep_max = 0; |
2581 | p->se.slice_max = 0; | 2582 | p->se.sum_sleep_runtime = 0; |
2582 | p->se.wait_max = 0; | 2583 | |
2584 | p->se.block_start = 0; | ||
2585 | p->se.block_max = 0; | ||
2586 | p->se.exec_max = 0; | ||
2587 | p->se.slice_max = 0; | ||
2588 | |||
2589 | p->se.nr_migrations_cold = 0; | ||
2590 | p->se.nr_failed_migrations_affine = 0; | ||
2591 | p->se.nr_failed_migrations_running = 0; | ||
2592 | p->se.nr_failed_migrations_hot = 0; | ||
2593 | p->se.nr_forced_migrations = 0; | ||
2594 | p->se.nr_forced2_migrations = 0; | ||
2595 | |||
2596 | p->se.nr_wakeups = 0; | ||
2597 | p->se.nr_wakeups_sync = 0; | ||
2598 | p->se.nr_wakeups_migrate = 0; | ||
2599 | p->se.nr_wakeups_local = 0; | ||
2600 | p->se.nr_wakeups_remote = 0; | ||
2601 | p->se.nr_wakeups_affine = 0; | ||
2602 | p->se.nr_wakeups_affine_attempts = 0; | ||
2603 | p->se.nr_wakeups_passive = 0; | ||
2604 | p->se.nr_wakeups_idle = 0; | ||
2605 | |||
2583 | #endif | 2606 | #endif |
2584 | 2607 | ||
2585 | INIT_LIST_HEAD(&p->rt.run_list); | 2608 | INIT_LIST_HEAD(&p->rt.run_list); |
@@ -6541,6 +6564,11 @@ SYSCALL_DEFINE0(sched_yield) | |||
6541 | return 0; | 6564 | return 0; |
6542 | } | 6565 | } |
6543 | 6566 | ||
6567 | static inline int should_resched(void) | ||
6568 | { | ||
6569 | return need_resched() && !(preempt_count() & PREEMPT_ACTIVE); | ||
6570 | } | ||
6571 | |||
6544 | static void __cond_resched(void) | 6572 | static void __cond_resched(void) |
6545 | { | 6573 | { |
6546 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 6574 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP |
@@ -6560,8 +6588,7 @@ static void __cond_resched(void) | |||
6560 | 6588 | ||
6561 | int __sched _cond_resched(void) | 6589 | int __sched _cond_resched(void) |
6562 | { | 6590 | { |
6563 | if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) && | 6591 | if (should_resched()) { |
6564 | system_state == SYSTEM_RUNNING) { | ||
6565 | __cond_resched(); | 6592 | __cond_resched(); |
6566 | return 1; | 6593 | return 1; |
6567 | } | 6594 | } |
@@ -6579,12 +6606,12 @@ EXPORT_SYMBOL(_cond_resched); | |||
6579 | */ | 6606 | */ |
6580 | int cond_resched_lock(spinlock_t *lock) | 6607 | int cond_resched_lock(spinlock_t *lock) |
6581 | { | 6608 | { |
6582 | int resched = need_resched() && system_state == SYSTEM_RUNNING; | 6609 | int resched = should_resched(); |
6583 | int ret = 0; | 6610 | int ret = 0; |
6584 | 6611 | ||
6585 | if (spin_needbreak(lock) || resched) { | 6612 | if (spin_needbreak(lock) || resched) { |
6586 | spin_unlock(lock); | 6613 | spin_unlock(lock); |
6587 | if (resched && need_resched()) | 6614 | if (resched) |
6588 | __cond_resched(); | 6615 | __cond_resched(); |
6589 | else | 6616 | else |
6590 | cpu_relax(); | 6617 | cpu_relax(); |
@@ -6599,7 +6626,7 @@ int __sched cond_resched_softirq(void) | |||
6599 | { | 6626 | { |
6600 | BUG_ON(!in_softirq()); | 6627 | BUG_ON(!in_softirq()); |
6601 | 6628 | ||
6602 | if (need_resched() && system_state == SYSTEM_RUNNING) { | 6629 | if (should_resched()) { |
6603 | local_bh_enable(); | 6630 | local_bh_enable(); |
6604 | __cond_resched(); | 6631 | __cond_resched(); |
6605 | local_bh_disable(); | 6632 | local_bh_disable(); |
@@ -9070,7 +9097,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) | |||
9070 | #ifdef CONFIG_SMP | 9097 | #ifdef CONFIG_SMP |
9071 | rt_rq->rt_nr_migratory = 0; | 9098 | rt_rq->rt_nr_migratory = 0; |
9072 | rt_rq->overloaded = 0; | 9099 | rt_rq->overloaded = 0; |
9073 | plist_head_init(&rq->rt.pushable_tasks, &rq->lock); | 9100 | plist_head_init(&rt_rq->pushable_tasks, &rq->lock); |
9074 | #endif | 9101 | #endif |
9075 | 9102 | ||
9076 | rt_rq->rt_time = 0; | 9103 | rt_rq->rt_time = 0; |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index ba7fd6e9556f..7c248dc30f41 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -687,7 +687,8 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) | |||
687 | * all of which have the same weight. | 687 | * all of which have the same weight. |
688 | */ | 688 | */ |
689 | if (sched_feat(NORMALIZED_SLEEPER) && | 689 | if (sched_feat(NORMALIZED_SLEEPER) && |
690 | task_of(se)->policy != SCHED_IDLE) | 690 | (!entity_is_task(se) || |
691 | task_of(se)->policy != SCHED_IDLE)) | ||
691 | thresh = calc_delta_fair(thresh, se); | 692 | thresh = calc_delta_fair(thresh, se); |
692 | 693 | ||
693 | vruntime -= thresh; | 694 | vruntime -= thresh; |
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 9bf0d2a73045..3918e01994e0 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
@@ -10,6 +10,8 @@ static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se) | |||
10 | 10 | ||
11 | #ifdef CONFIG_RT_GROUP_SCHED | 11 | #ifdef CONFIG_RT_GROUP_SCHED |
12 | 12 | ||
13 | #define rt_entity_is_task(rt_se) (!(rt_se)->my_q) | ||
14 | |||
13 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) | 15 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) |
14 | { | 16 | { |
15 | return rt_rq->rq; | 17 | return rt_rq->rq; |
@@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se) | |||
22 | 24 | ||
23 | #else /* CONFIG_RT_GROUP_SCHED */ | 25 | #else /* CONFIG_RT_GROUP_SCHED */ |
24 | 26 | ||
27 | #define rt_entity_is_task(rt_se) (1) | ||
28 | |||
25 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) | 29 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) |
26 | { | 30 | { |
27 | return container_of(rt_rq, struct rq, rt); | 31 | return container_of(rt_rq, struct rq, rt); |
@@ -73,7 +77,7 @@ static inline void rt_clear_overload(struct rq *rq) | |||
73 | 77 | ||
74 | static void update_rt_migration(struct rt_rq *rt_rq) | 78 | static void update_rt_migration(struct rt_rq *rt_rq) |
75 | { | 79 | { |
76 | if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) { | 80 | if (rt_rq->rt_nr_migratory && rt_rq->rt_nr_total > 1) { |
77 | if (!rt_rq->overloaded) { | 81 | if (!rt_rq->overloaded) { |
78 | rt_set_overload(rq_of_rt_rq(rt_rq)); | 82 | rt_set_overload(rq_of_rt_rq(rt_rq)); |
79 | rt_rq->overloaded = 1; | 83 | rt_rq->overloaded = 1; |
@@ -86,6 +90,12 @@ static void update_rt_migration(struct rt_rq *rt_rq) | |||
86 | 90 | ||
87 | static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) | 91 | static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) |
88 | { | 92 | { |
93 | if (!rt_entity_is_task(rt_se)) | ||
94 | return; | ||
95 | |||
96 | rt_rq = &rq_of_rt_rq(rt_rq)->rt; | ||
97 | |||
98 | rt_rq->rt_nr_total++; | ||
89 | if (rt_se->nr_cpus_allowed > 1) | 99 | if (rt_se->nr_cpus_allowed > 1) |
90 | rt_rq->rt_nr_migratory++; | 100 | rt_rq->rt_nr_migratory++; |
91 | 101 | ||
@@ -94,6 +104,12 @@ static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) | |||
94 | 104 | ||
95 | static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) | 105 | static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq) |
96 | { | 106 | { |
107 | if (!rt_entity_is_task(rt_se)) | ||
108 | return; | ||
109 | |||
110 | rt_rq = &rq_of_rt_rq(rt_rq)->rt; | ||
111 | |||
112 | rt_rq->rt_nr_total--; | ||
97 | if (rt_se->nr_cpus_allowed > 1) | 113 | if (rt_se->nr_cpus_allowed > 1) |
98 | rt_rq->rt_nr_migratory--; | 114 | rt_rq->rt_nr_migratory--; |
99 | 115 | ||
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 1ad6dd461119..a6dcd67b041d 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -254,15 +254,4 @@ void clockevents_notify(unsigned long reason, void *arg) | |||
254 | spin_unlock(&clockevents_lock); | 254 | spin_unlock(&clockevents_lock); |
255 | } | 255 | } |
256 | EXPORT_SYMBOL_GPL(clockevents_notify); | 256 | EXPORT_SYMBOL_GPL(clockevents_notify); |
257 | |||
258 | ktime_t clockevents_get_next_event(int cpu) | ||
259 | { | ||
260 | struct tick_device *td; | ||
261 | struct clock_event_device *dev; | ||
262 | |||
263 | td = &per_cpu(tick_cpu_device, cpu); | ||
264 | dev = td->evtdev; | ||
265 | |||
266 | return dev->next_event; | ||
267 | } | ||
268 | #endif | 257 | #endif |
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 1551f47e7669..019f380fd764 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig | |||
@@ -226,13 +226,13 @@ config BOOT_TRACER | |||
226 | the timings of the initcalls and traces key events and the identity | 226 | the timings of the initcalls and traces key events and the identity |
227 | of tasks that can cause boot delays, such as context-switches. | 227 | of tasks that can cause boot delays, such as context-switches. |
228 | 228 | ||
229 | Its aim is to be parsed by the /scripts/bootgraph.pl tool to | 229 | Its aim is to be parsed by the scripts/bootgraph.pl tool to |
230 | produce pretty graphics about boot inefficiencies, giving a visual | 230 | produce pretty graphics about boot inefficiencies, giving a visual |
231 | representation of the delays during initcalls - but the raw | 231 | representation of the delays during initcalls - but the raw |
232 | /debug/tracing/trace text output is readable too. | 232 | /debug/tracing/trace text output is readable too. |
233 | 233 | ||
234 | You must pass in ftrace=initcall to the kernel command line | 234 | You must pass in initcall_debug and ftrace=initcall to the kernel |
235 | to enable this on bootup. | 235 | command line to enable this on bootup. |
236 | 236 | ||
237 | config TRACE_BRANCH_PROFILING | 237 | config TRACE_BRANCH_PROFILING |
238 | bool | 238 | bool |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 39af8af6fc30..1090b0aed9ba 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
25 | #include <linux/smp_lock.h> | ||
25 | #include <linux/time.h> | 26 | #include <linux/time.h> |
26 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
27 | 28 | ||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index f3716bf04df6..4521c77d1a1a 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -768,7 +768,7 @@ static struct tracer_stat function_stats __initdata = { | |||
768 | .stat_show = function_stat_show | 768 | .stat_show = function_stat_show |
769 | }; | 769 | }; |
770 | 770 | ||
771 | static void ftrace_profile_debugfs(struct dentry *d_tracer) | 771 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) |
772 | { | 772 | { |
773 | struct ftrace_profile_stat *stat; | 773 | struct ftrace_profile_stat *stat; |
774 | struct dentry *entry; | 774 | struct dentry *entry; |
@@ -786,7 +786,6 @@ static void ftrace_profile_debugfs(struct dentry *d_tracer) | |||
786 | * The files created are permanent, if something happens | 786 | * The files created are permanent, if something happens |
787 | * we still do not free memory. | 787 | * we still do not free memory. |
788 | */ | 788 | */ |
789 | kfree(stat); | ||
790 | WARN(1, | 789 | WARN(1, |
791 | "Could not allocate stat file for cpu %d\n", | 790 | "Could not allocate stat file for cpu %d\n", |
792 | cpu); | 791 | cpu); |
@@ -813,7 +812,7 @@ static void ftrace_profile_debugfs(struct dentry *d_tracer) | |||
813 | } | 812 | } |
814 | 813 | ||
815 | #else /* CONFIG_FUNCTION_PROFILER */ | 814 | #else /* CONFIG_FUNCTION_PROFILER */ |
816 | static void ftrace_profile_debugfs(struct dentry *d_tracer) | 815 | static __init void ftrace_profile_debugfs(struct dentry *d_tracer) |
817 | { | 816 | { |
818 | } | 817 | } |
819 | #endif /* CONFIG_FUNCTION_PROFILER */ | 818 | #endif /* CONFIG_FUNCTION_PROFILER */ |
@@ -3160,10 +3159,10 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, | |||
3160 | 3159 | ||
3161 | ret = proc_dointvec(table, write, file, buffer, lenp, ppos); | 3160 | ret = proc_dointvec(table, write, file, buffer, lenp, ppos); |
3162 | 3161 | ||
3163 | if (ret || !write || (last_ftrace_enabled == ftrace_enabled)) | 3162 | if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) |
3164 | goto out; | 3163 | goto out; |
3165 | 3164 | ||
3166 | last_ftrace_enabled = ftrace_enabled; | 3165 | last_ftrace_enabled = !!ftrace_enabled; |
3167 | 3166 | ||
3168 | if (ftrace_enabled) { | 3167 | if (ftrace_enabled) { |
3169 | 3168 | ||
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3aa0a0dfdfa8..8bc8d8afea6a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/writeback.h> | 17 | #include <linux/writeback.h> |
18 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
20 | #include <linux/smp_lock.h> | ||
20 | #include <linux/notifier.h> | 21 | #include <linux/notifier.h> |
21 | #include <linux/irqflags.h> | 22 | #include <linux/irqflags.h> |
22 | #include <linux/debugfs.h> | 23 | #include <linux/debugfs.h> |
diff --git a/kernel/trace/trace_event_types.h b/kernel/trace/trace_event_types.h index 5e32e375134d..6db005e12487 100644 --- a/kernel/trace/trace_event_types.h +++ b/kernel/trace/trace_event_types.h | |||
@@ -26,6 +26,9 @@ TRACE_EVENT_FORMAT(funcgraph_exit, TRACE_GRAPH_RET, | |||
26 | ftrace_graph_ret_entry, ignore, | 26 | ftrace_graph_ret_entry, ignore, |
27 | TRACE_STRUCT( | 27 | TRACE_STRUCT( |
28 | TRACE_FIELD(unsigned long, ret.func, func) | 28 | TRACE_FIELD(unsigned long, ret.func, func) |
29 | TRACE_FIELD(unsigned long long, ret.calltime, calltime) | ||
30 | TRACE_FIELD(unsigned long long, ret.rettime, rettime) | ||
31 | TRACE_FIELD(unsigned long, ret.overrun, overrun) | ||
29 | TRACE_FIELD(int, ret.depth, depth) | 32 | TRACE_FIELD(int, ret.depth, depth) |
30 | ), | 33 | ), |
31 | TP_RAW_FMT("<-- %lx (%d)") | 34 | TP_RAW_FMT("<-- %lx (%d)") |
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 7402144bff21..75ef000613c3 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c | |||
@@ -363,7 +363,7 @@ ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable) | |||
363 | out_reg: | 363 | out_reg: |
364 | ret = register_ftrace_function_probe(glob, ops, count); | 364 | ret = register_ftrace_function_probe(glob, ops, count); |
365 | 365 | ||
366 | return ret; | 366 | return ret < 0 ? ret : 0; |
367 | } | 367 | } |
368 | 368 | ||
369 | static struct ftrace_func_command ftrace_traceon_cmd = { | 369 | static struct ftrace_func_command ftrace_traceon_cmd = { |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 7938f3ae93e3..e0c2545622e8 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -27,8 +27,7 @@ void trace_print_seq(struct seq_file *m, struct trace_seq *s) | |||
27 | { | 27 | { |
28 | int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; | 28 | int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len; |
29 | 29 | ||
30 | s->buffer[len] = 0; | 30 | seq_write(m, s->buffer, len); |
31 | seq_puts(m, s->buffer); | ||
32 | 31 | ||
33 | trace_seq_init(s); | 32 | trace_seq_init(s); |
34 | } | 33 | } |
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 2d7aebd71dbd..e644af910124 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
@@ -326,10 +326,10 @@ stack_trace_sysctl(struct ctl_table *table, int write, | |||
326 | ret = proc_dointvec(table, write, file, buffer, lenp, ppos); | 326 | ret = proc_dointvec(table, write, file, buffer, lenp, ppos); |
327 | 327 | ||
328 | if (ret || !write || | 328 | if (ret || !write || |
329 | (last_stack_tracer_enabled == stack_tracer_enabled)) | 329 | (last_stack_tracer_enabled == !!stack_tracer_enabled)) |
330 | goto out; | 330 | goto out; |
331 | 331 | ||
332 | last_stack_tracer_enabled = stack_tracer_enabled; | 332 | last_stack_tracer_enabled = !!stack_tracer_enabled; |
333 | 333 | ||
334 | if (stack_tracer_enabled) | 334 | if (stack_tracer_enabled) |
335 | register_ftrace_function(&trace_ops); | 335 | register_ftrace_function(&trace_ops); |
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 3b93129a968c..65b0d99b6d0a 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -716,7 +716,7 @@ void dma_debug_init(u32 num_entries) | |||
716 | 716 | ||
717 | for (i = 0; i < HASH_SIZE; ++i) { | 717 | for (i = 0; i < HASH_SIZE; ++i) { |
718 | INIT_LIST_HEAD(&dma_entry_hash[i].list); | 718 | INIT_LIST_HEAD(&dma_entry_hash[i].list); |
719 | dma_entry_hash[i].lock = SPIN_LOCK_UNLOCKED; | 719 | spin_lock_init(&dma_entry_hash[i].lock); |
720 | } | 720 | } |
721 | 721 | ||
722 | if (dma_debug_fs_init() != 0) { | 722 | if (dma_debug_fs_init() != 0) { |
@@ -856,22 +856,21 @@ static void check_for_stack(struct device *dev, void *addr) | |||
856 | "stack [addr=%p]\n", addr); | 856 | "stack [addr=%p]\n", addr); |
857 | } | 857 | } |
858 | 858 | ||
859 | static inline bool overlap(void *addr, u64 size, void *start, void *end) | 859 | static inline bool overlap(void *addr, unsigned long len, void *start, void *end) |
860 | { | 860 | { |
861 | void *addr2 = (char *)addr + size; | 861 | unsigned long a1 = (unsigned long)addr; |
862 | unsigned long b1 = a1 + len; | ||
863 | unsigned long a2 = (unsigned long)start; | ||
864 | unsigned long b2 = (unsigned long)end; | ||
862 | 865 | ||
863 | return ((addr >= start && addr < end) || | 866 | return !(b1 <= a2 || a1 >= b2); |
864 | (addr2 >= start && addr2 < end) || | ||
865 | ((addr < start) && (addr2 >= end))); | ||
866 | } | 867 | } |
867 | 868 | ||
868 | static void check_for_illegal_area(struct device *dev, void *addr, u64 size) | 869 | static void check_for_illegal_area(struct device *dev, void *addr, unsigned long len) |
869 | { | 870 | { |
870 | if (overlap(addr, size, _text, _etext) || | 871 | if (overlap(addr, len, _text, _etext) || |
871 | overlap(addr, size, __start_rodata, __end_rodata)) | 872 | overlap(addr, len, __start_rodata, __end_rodata)) |
872 | err_printk(dev, NULL, "DMA-API: device driver maps " | 873 | err_printk(dev, NULL, "DMA-API: device driver maps memory from kernel text or rodata [addr=%p] [len=%lu]\n", addr, len); |
873 | "memory from kernel text or rodata " | ||
874 | "[addr=%p] [size=%llu]\n", addr, size); | ||
875 | } | 874 | } |
876 | 875 | ||
877 | static void check_sync(struct device *dev, | 876 | static void check_sync(struct device *dev, |
@@ -969,7 +968,8 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, | |||
969 | entry->type = dma_debug_single; | 968 | entry->type = dma_debug_single; |
970 | 969 | ||
971 | if (!PageHighMem(page)) { | 970 | if (!PageHighMem(page)) { |
972 | void *addr = ((char *)page_address(page)) + offset; | 971 | void *addr = page_address(page) + offset; |
972 | |||
973 | check_for_stack(dev, addr); | 973 | check_for_stack(dev, addr); |
974 | check_for_illegal_area(dev, addr, size); | 974 | check_for_illegal_area(dev, addr, size); |
975 | } | 975 | } |
diff --git a/mm/bootmem.c b/mm/bootmem.c index d2a9ce952768..701740c9e81b 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pfn.h> | 12 | #include <linux/pfn.h> |
13 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/kmemleak.h> | ||
15 | 16 | ||
16 | #include <asm/bug.h> | 17 | #include <asm/bug.h> |
17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
@@ -335,6 +336,8 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr, | |||
335 | { | 336 | { |
336 | unsigned long start, end; | 337 | unsigned long start, end; |
337 | 338 | ||
339 | kmemleak_free_part(__va(physaddr), size); | ||
340 | |||
338 | start = PFN_UP(physaddr); | 341 | start = PFN_UP(physaddr); |
339 | end = PFN_DOWN(physaddr + size); | 342 | end = PFN_DOWN(physaddr + size); |
340 | 343 | ||
@@ -354,6 +357,8 @@ void __init free_bootmem(unsigned long addr, unsigned long size) | |||
354 | { | 357 | { |
355 | unsigned long start, end; | 358 | unsigned long start, end; |
356 | 359 | ||
360 | kmemleak_free_part(__va(addr), size); | ||
361 | |||
357 | start = PFN_UP(addr); | 362 | start = PFN_UP(addr); |
358 | end = PFN_DOWN(addr + size); | 363 | end = PFN_DOWN(addr + size); |
359 | 364 | ||
@@ -516,6 +521,7 @@ find_block: | |||
516 | region = phys_to_virt(PFN_PHYS(bdata->node_min_pfn) + | 521 | region = phys_to_virt(PFN_PHYS(bdata->node_min_pfn) + |
517 | start_off); | 522 | start_off); |
518 | memset(region, 0, size); | 523 | memset(region, 0, size); |
524 | kmemleak_alloc(region, size, 1, 0); | ||
519 | return region; | 525 | return region; |
520 | } | 526 | } |
521 | 527 | ||
diff --git a/mm/kmemleak.c b/mm/kmemleak.c index e766e1da09d2..5aabd41ffb8f 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c | |||
@@ -103,10 +103,10 @@ | |||
103 | * Kmemleak configuration and common defines. | 103 | * Kmemleak configuration and common defines. |
104 | */ | 104 | */ |
105 | #define MAX_TRACE 16 /* stack trace length */ | 105 | #define MAX_TRACE 16 /* stack trace length */ |
106 | #define REPORTS_NR 50 /* maximum number of reported leaks */ | ||
107 | #define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ | 106 | #define MSECS_MIN_AGE 5000 /* minimum object age for reporting */ |
108 | #define SECS_FIRST_SCAN 60 /* delay before the first scan */ | 107 | #define SECS_FIRST_SCAN 60 /* delay before the first scan */ |
109 | #define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ | 108 | #define SECS_SCAN_WAIT 600 /* subsequent auto scanning delay */ |
109 | #define GRAY_LIST_PASSES 25 /* maximum number of gray list scans */ | ||
110 | 110 | ||
111 | #define BYTES_PER_POINTER sizeof(void *) | 111 | #define BYTES_PER_POINTER sizeof(void *) |
112 | 112 | ||
@@ -158,6 +158,8 @@ struct kmemleak_object { | |||
158 | #define OBJECT_REPORTED (1 << 1) | 158 | #define OBJECT_REPORTED (1 << 1) |
159 | /* flag set to not scan the object */ | 159 | /* flag set to not scan the object */ |
160 | #define OBJECT_NO_SCAN (1 << 2) | 160 | #define OBJECT_NO_SCAN (1 << 2) |
161 | /* flag set on newly allocated objects */ | ||
162 | #define OBJECT_NEW (1 << 3) | ||
161 | 163 | ||
162 | /* the list of all allocated objects */ | 164 | /* the list of all allocated objects */ |
163 | static LIST_HEAD(object_list); | 165 | static LIST_HEAD(object_list); |
@@ -196,9 +198,6 @@ static int kmemleak_stack_scan = 1; | |||
196 | /* protects the memory scanning, parameters and debug/kmemleak file access */ | 198 | /* protects the memory scanning, parameters and debug/kmemleak file access */ |
197 | static DEFINE_MUTEX(scan_mutex); | 199 | static DEFINE_MUTEX(scan_mutex); |
198 | 200 | ||
199 | /* number of leaks reported (for limitation purposes) */ | ||
200 | static int reported_leaks; | ||
201 | |||
202 | /* | 201 | /* |
203 | * Early object allocation/freeing logging. Kmemleak is initialized after the | 202 | * Early object allocation/freeing logging. Kmemleak is initialized after the |
204 | * kernel allocator. However, both the kernel allocator and kmemleak may | 203 | * kernel allocator. However, both the kernel allocator and kmemleak may |
@@ -211,6 +210,7 @@ static int reported_leaks; | |||
211 | enum { | 210 | enum { |
212 | KMEMLEAK_ALLOC, | 211 | KMEMLEAK_ALLOC, |
213 | KMEMLEAK_FREE, | 212 | KMEMLEAK_FREE, |
213 | KMEMLEAK_FREE_PART, | ||
214 | KMEMLEAK_NOT_LEAK, | 214 | KMEMLEAK_NOT_LEAK, |
215 | KMEMLEAK_IGNORE, | 215 | KMEMLEAK_IGNORE, |
216 | KMEMLEAK_SCAN_AREA, | 216 | KMEMLEAK_SCAN_AREA, |
@@ -274,6 +274,11 @@ static int color_gray(const struct kmemleak_object *object) | |||
274 | return object->min_count != -1 && object->count >= object->min_count; | 274 | return object->min_count != -1 && object->count >= object->min_count; |
275 | } | 275 | } |
276 | 276 | ||
277 | static int color_black(const struct kmemleak_object *object) | ||
278 | { | ||
279 | return object->min_count == -1; | ||
280 | } | ||
281 | |||
277 | /* | 282 | /* |
278 | * Objects are considered unreferenced only if their color is white, they have | 283 | * Objects are considered unreferenced only if their color is white, they have |
279 | * not be deleted and have a minimum age to avoid false positives caused by | 284 | * not be deleted and have a minimum age to avoid false positives caused by |
@@ -451,7 +456,7 @@ static void create_object(unsigned long ptr, size_t size, int min_count, | |||
451 | INIT_HLIST_HEAD(&object->area_list); | 456 | INIT_HLIST_HEAD(&object->area_list); |
452 | spin_lock_init(&object->lock); | 457 | spin_lock_init(&object->lock); |
453 | atomic_set(&object->use_count, 1); | 458 | atomic_set(&object->use_count, 1); |
454 | object->flags = OBJECT_ALLOCATED; | 459 | object->flags = OBJECT_ALLOCATED | OBJECT_NEW; |
455 | object->pointer = ptr; | 460 | object->pointer = ptr; |
456 | object->size = size; | 461 | object->size = size; |
457 | object->min_count = min_count; | 462 | object->min_count = min_count; |
@@ -519,27 +524,17 @@ out: | |||
519 | * Remove the metadata (struct kmemleak_object) for a memory block from the | 524 | * Remove the metadata (struct kmemleak_object) for a memory block from the |
520 | * object_list and object_tree_root and decrement its use_count. | 525 | * object_list and object_tree_root and decrement its use_count. |
521 | */ | 526 | */ |
522 | static void delete_object(unsigned long ptr) | 527 | static void __delete_object(struct kmemleak_object *object) |
523 | { | 528 | { |
524 | unsigned long flags; | 529 | unsigned long flags; |
525 | struct kmemleak_object *object; | ||
526 | 530 | ||
527 | write_lock_irqsave(&kmemleak_lock, flags); | 531 | write_lock_irqsave(&kmemleak_lock, flags); |
528 | object = lookup_object(ptr, 0); | ||
529 | if (!object) { | ||
530 | #ifdef DEBUG | ||
531 | kmemleak_warn("Freeing unknown object at 0x%08lx\n", | ||
532 | ptr); | ||
533 | #endif | ||
534 | write_unlock_irqrestore(&kmemleak_lock, flags); | ||
535 | return; | ||
536 | } | ||
537 | prio_tree_remove(&object_tree_root, &object->tree_node); | 532 | prio_tree_remove(&object_tree_root, &object->tree_node); |
538 | list_del_rcu(&object->object_list); | 533 | list_del_rcu(&object->object_list); |
539 | write_unlock_irqrestore(&kmemleak_lock, flags); | 534 | write_unlock_irqrestore(&kmemleak_lock, flags); |
540 | 535 | ||
541 | WARN_ON(!(object->flags & OBJECT_ALLOCATED)); | 536 | WARN_ON(!(object->flags & OBJECT_ALLOCATED)); |
542 | WARN_ON(atomic_read(&object->use_count) < 1); | 537 | WARN_ON(atomic_read(&object->use_count) < 2); |
543 | 538 | ||
544 | /* | 539 | /* |
545 | * Locking here also ensures that the corresponding memory block | 540 | * Locking here also ensures that the corresponding memory block |
@@ -552,6 +547,64 @@ static void delete_object(unsigned long ptr) | |||
552 | } | 547 | } |
553 | 548 | ||
554 | /* | 549 | /* |
550 | * Look up the metadata (struct kmemleak_object) corresponding to ptr and | ||
551 | * delete it. | ||
552 | */ | ||
553 | static void delete_object_full(unsigned long ptr) | ||
554 | { | ||
555 | struct kmemleak_object *object; | ||
556 | |||
557 | object = find_and_get_object(ptr, 0); | ||
558 | if (!object) { | ||
559 | #ifdef DEBUG | ||
560 | kmemleak_warn("Freeing unknown object at 0x%08lx\n", | ||
561 | ptr); | ||
562 | #endif | ||
563 | return; | ||
564 | } | ||
565 | __delete_object(object); | ||
566 | put_object(object); | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * Look up the metadata (struct kmemleak_object) corresponding to ptr and | ||
571 | * delete it. If the memory block is partially freed, the function may create | ||
572 | * additional metadata for the remaining parts of the block. | ||
573 | */ | ||
574 | static void delete_object_part(unsigned long ptr, size_t size) | ||
575 | { | ||
576 | struct kmemleak_object *object; | ||
577 | unsigned long start, end; | ||
578 | |||
579 | object = find_and_get_object(ptr, 1); | ||
580 | if (!object) { | ||
581 | #ifdef DEBUG | ||
582 | kmemleak_warn("Partially freeing unknown object at 0x%08lx " | ||
583 | "(size %zu)\n", ptr, size); | ||
584 | #endif | ||
585 | return; | ||
586 | } | ||
587 | __delete_object(object); | ||
588 | |||
589 | /* | ||
590 | * Create one or two objects that may result from the memory block | ||
591 | * split. Note that partial freeing is only done by free_bootmem() and | ||
592 | * this happens before kmemleak_init() is called. The path below is | ||
593 | * only executed during early log recording in kmemleak_init(), so | ||
594 | * GFP_KERNEL is enough. | ||
595 | */ | ||
596 | start = object->pointer; | ||
597 | end = object->pointer + object->size; | ||
598 | if (ptr > start) | ||
599 | create_object(start, ptr - start, object->min_count, | ||
600 | GFP_KERNEL); | ||
601 | if (ptr + size < end) | ||
602 | create_object(ptr + size, end - ptr - size, object->min_count, | ||
603 | GFP_KERNEL); | ||
604 | |||
605 | put_object(object); | ||
606 | } | ||
607 | /* | ||
555 | * Make a object permanently as gray-colored so that it can no longer be | 608 | * Make a object permanently as gray-colored so that it can no longer be |
556 | * reported as a leak. This is used in general to mark a false positive. | 609 | * reported as a leak. This is used in general to mark a false positive. |
557 | */ | 610 | */ |
@@ -715,13 +768,28 @@ void kmemleak_free(const void *ptr) | |||
715 | pr_debug("%s(0x%p)\n", __func__, ptr); | 768 | pr_debug("%s(0x%p)\n", __func__, ptr); |
716 | 769 | ||
717 | if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) | 770 | if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) |
718 | delete_object((unsigned long)ptr); | 771 | delete_object_full((unsigned long)ptr); |
719 | else if (atomic_read(&kmemleak_early_log)) | 772 | else if (atomic_read(&kmemleak_early_log)) |
720 | log_early(KMEMLEAK_FREE, ptr, 0, 0, 0, 0); | 773 | log_early(KMEMLEAK_FREE, ptr, 0, 0, 0, 0); |
721 | } | 774 | } |
722 | EXPORT_SYMBOL_GPL(kmemleak_free); | 775 | EXPORT_SYMBOL_GPL(kmemleak_free); |
723 | 776 | ||
724 | /* | 777 | /* |
778 | * Partial memory freeing function callback. This function is usually called | ||
779 | * from bootmem allocator when (part of) a memory block is freed. | ||
780 | */ | ||
781 | void kmemleak_free_part(const void *ptr, size_t size) | ||
782 | { | ||
783 | pr_debug("%s(0x%p)\n", __func__, ptr); | ||
784 | |||
785 | if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr)) | ||
786 | delete_object_part((unsigned long)ptr, size); | ||
787 | else if (atomic_read(&kmemleak_early_log)) | ||
788 | log_early(KMEMLEAK_FREE_PART, ptr, size, 0, 0, 0); | ||
789 | } | ||
790 | EXPORT_SYMBOL_GPL(kmemleak_free_part); | ||
791 | |||
792 | /* | ||
725 | * Mark an already allocated memory block as a false positive. This will cause | 793 | * Mark an already allocated memory block as a false positive. This will cause |
726 | * the block to no longer be reported as leak and always be scanned. | 794 | * the block to no longer be reported as leak and always be scanned. |
727 | */ | 795 | */ |
@@ -807,7 +875,7 @@ static int scan_should_stop(void) | |||
807 | * found to the gray list. | 875 | * found to the gray list. |
808 | */ | 876 | */ |
809 | static void scan_block(void *_start, void *_end, | 877 | static void scan_block(void *_start, void *_end, |
810 | struct kmemleak_object *scanned) | 878 | struct kmemleak_object *scanned, int allow_resched) |
811 | { | 879 | { |
812 | unsigned long *ptr; | 880 | unsigned long *ptr; |
813 | unsigned long *start = PTR_ALIGN(_start, BYTES_PER_POINTER); | 881 | unsigned long *start = PTR_ALIGN(_start, BYTES_PER_POINTER); |
@@ -818,6 +886,8 @@ static void scan_block(void *_start, void *_end, | |||
818 | unsigned long pointer = *ptr; | 886 | unsigned long pointer = *ptr; |
819 | struct kmemleak_object *object; | 887 | struct kmemleak_object *object; |
820 | 888 | ||
889 | if (allow_resched) | ||
890 | cond_resched(); | ||
821 | if (scan_should_stop()) | 891 | if (scan_should_stop()) |
822 | break; | 892 | break; |
823 | 893 | ||
@@ -881,12 +951,12 @@ static void scan_object(struct kmemleak_object *object) | |||
881 | goto out; | 951 | goto out; |
882 | if (hlist_empty(&object->area_list)) | 952 | if (hlist_empty(&object->area_list)) |
883 | scan_block((void *)object->pointer, | 953 | scan_block((void *)object->pointer, |
884 | (void *)(object->pointer + object->size), object); | 954 | (void *)(object->pointer + object->size), object, 0); |
885 | else | 955 | else |
886 | hlist_for_each_entry(area, elem, &object->area_list, node) | 956 | hlist_for_each_entry(area, elem, &object->area_list, node) |
887 | scan_block((void *)(object->pointer + area->offset), | 957 | scan_block((void *)(object->pointer + area->offset), |
888 | (void *)(object->pointer + area->offset | 958 | (void *)(object->pointer + area->offset |
889 | + area->length), object); | 959 | + area->length), object, 0); |
890 | out: | 960 | out: |
891 | spin_unlock_irqrestore(&object->lock, flags); | 961 | spin_unlock_irqrestore(&object->lock, flags); |
892 | } | 962 | } |
@@ -903,6 +973,7 @@ static void kmemleak_scan(void) | |||
903 | struct task_struct *task; | 973 | struct task_struct *task; |
904 | int i; | 974 | int i; |
905 | int new_leaks = 0; | 975 | int new_leaks = 0; |
976 | int gray_list_pass = 0; | ||
906 | 977 | ||
907 | jiffies_last_scan = jiffies; | 978 | jiffies_last_scan = jiffies; |
908 | 979 | ||
@@ -923,6 +994,7 @@ static void kmemleak_scan(void) | |||
923 | #endif | 994 | #endif |
924 | /* reset the reference count (whiten the object) */ | 995 | /* reset the reference count (whiten the object) */ |
925 | object->count = 0; | 996 | object->count = 0; |
997 | object->flags &= ~OBJECT_NEW; | ||
926 | if (color_gray(object) && get_object(object)) | 998 | if (color_gray(object) && get_object(object)) |
927 | list_add_tail(&object->gray_list, &gray_list); | 999 | list_add_tail(&object->gray_list, &gray_list); |
928 | 1000 | ||
@@ -931,14 +1003,14 @@ static void kmemleak_scan(void) | |||
931 | rcu_read_unlock(); | 1003 | rcu_read_unlock(); |
932 | 1004 | ||
933 | /* data/bss scanning */ | 1005 | /* data/bss scanning */ |
934 | scan_block(_sdata, _edata, NULL); | 1006 | scan_block(_sdata, _edata, NULL, 1); |
935 | scan_block(__bss_start, __bss_stop, NULL); | 1007 | scan_block(__bss_start, __bss_stop, NULL, 1); |
936 | 1008 | ||
937 | #ifdef CONFIG_SMP | 1009 | #ifdef CONFIG_SMP |
938 | /* per-cpu sections scanning */ | 1010 | /* per-cpu sections scanning */ |
939 | for_each_possible_cpu(i) | 1011 | for_each_possible_cpu(i) |
940 | scan_block(__per_cpu_start + per_cpu_offset(i), | 1012 | scan_block(__per_cpu_start + per_cpu_offset(i), |
941 | __per_cpu_end + per_cpu_offset(i), NULL); | 1013 | __per_cpu_end + per_cpu_offset(i), NULL, 1); |
942 | #endif | 1014 | #endif |
943 | 1015 | ||
944 | /* | 1016 | /* |
@@ -960,7 +1032,7 @@ static void kmemleak_scan(void) | |||
960 | /* only scan if page is in use */ | 1032 | /* only scan if page is in use */ |
961 | if (page_count(page) == 0) | 1033 | if (page_count(page) == 0) |
962 | continue; | 1034 | continue; |
963 | scan_block(page, page + 1, NULL); | 1035 | scan_block(page, page + 1, NULL, 1); |
964 | } | 1036 | } |
965 | } | 1037 | } |
966 | 1038 | ||
@@ -972,7 +1044,8 @@ static void kmemleak_scan(void) | |||
972 | read_lock(&tasklist_lock); | 1044 | read_lock(&tasklist_lock); |
973 | for_each_process(task) | 1045 | for_each_process(task) |
974 | scan_block(task_stack_page(task), | 1046 | scan_block(task_stack_page(task), |
975 | task_stack_page(task) + THREAD_SIZE, NULL); | 1047 | task_stack_page(task) + THREAD_SIZE, |
1048 | NULL, 0); | ||
976 | read_unlock(&tasklist_lock); | 1049 | read_unlock(&tasklist_lock); |
977 | } | 1050 | } |
978 | 1051 | ||
@@ -984,6 +1057,7 @@ static void kmemleak_scan(void) | |||
984 | * kmemleak objects cannot be freed from outside the loop because their | 1057 | * kmemleak objects cannot be freed from outside the loop because their |
985 | * use_count was increased. | 1058 | * use_count was increased. |
986 | */ | 1059 | */ |
1060 | repeat: | ||
987 | object = list_entry(gray_list.next, typeof(*object), gray_list); | 1061 | object = list_entry(gray_list.next, typeof(*object), gray_list); |
988 | while (&object->gray_list != &gray_list) { | 1062 | while (&object->gray_list != &gray_list) { |
989 | cond_resched(); | 1063 | cond_resched(); |
@@ -1001,12 +1075,38 @@ static void kmemleak_scan(void) | |||
1001 | 1075 | ||
1002 | object = tmp; | 1076 | object = tmp; |
1003 | } | 1077 | } |
1078 | |||
1079 | if (scan_should_stop() || ++gray_list_pass >= GRAY_LIST_PASSES) | ||
1080 | goto scan_end; | ||
1081 | |||
1082 | /* | ||
1083 | * Check for new objects allocated during this scanning and add them | ||
1084 | * to the gray list. | ||
1085 | */ | ||
1086 | rcu_read_lock(); | ||
1087 | list_for_each_entry_rcu(object, &object_list, object_list) { | ||
1088 | spin_lock_irqsave(&object->lock, flags); | ||
1089 | if ((object->flags & OBJECT_NEW) && !color_black(object) && | ||
1090 | get_object(object)) { | ||
1091 | object->flags &= ~OBJECT_NEW; | ||
1092 | list_add_tail(&object->gray_list, &gray_list); | ||
1093 | } | ||
1094 | spin_unlock_irqrestore(&object->lock, flags); | ||
1095 | } | ||
1096 | rcu_read_unlock(); | ||
1097 | |||
1098 | if (!list_empty(&gray_list)) | ||
1099 | goto repeat; | ||
1100 | |||
1101 | scan_end: | ||
1004 | WARN_ON(!list_empty(&gray_list)); | 1102 | WARN_ON(!list_empty(&gray_list)); |
1005 | 1103 | ||
1006 | /* | 1104 | /* |
1007 | * If scanning was stopped do not report any new unreferenced objects. | 1105 | * If scanning was stopped or new objects were being allocated at a |
1106 | * higher rate than gray list scanning, do not report any new | ||
1107 | * unreferenced objects. | ||
1008 | */ | 1108 | */ |
1009 | if (scan_should_stop()) | 1109 | if (scan_should_stop() || gray_list_pass >= GRAY_LIST_PASSES) |
1010 | return; | 1110 | return; |
1011 | 1111 | ||
1012 | /* | 1112 | /* |
@@ -1039,6 +1139,7 @@ static int kmemleak_scan_thread(void *arg) | |||
1039 | static int first_run = 1; | 1139 | static int first_run = 1; |
1040 | 1140 | ||
1041 | pr_info("Automatic memory scanning thread started\n"); | 1141 | pr_info("Automatic memory scanning thread started\n"); |
1142 | set_user_nice(current, 10); | ||
1042 | 1143 | ||
1043 | /* | 1144 | /* |
1044 | * Wait before the first scan to allow the system to fully initialize. | 1145 | * Wait before the first scan to allow the system to fully initialize. |
@@ -1101,11 +1202,11 @@ static void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos) | |||
1101 | { | 1202 | { |
1102 | struct kmemleak_object *object; | 1203 | struct kmemleak_object *object; |
1103 | loff_t n = *pos; | 1204 | loff_t n = *pos; |
1205 | int err; | ||
1104 | 1206 | ||
1105 | if (!n) | 1207 | err = mutex_lock_interruptible(&scan_mutex); |
1106 | reported_leaks = 0; | 1208 | if (err < 0) |
1107 | if (reported_leaks >= REPORTS_NR) | 1209 | return ERR_PTR(err); |
1108 | return NULL; | ||
1109 | 1210 | ||
1110 | rcu_read_lock(); | 1211 | rcu_read_lock(); |
1111 | list_for_each_entry_rcu(object, &object_list, object_list) { | 1212 | list_for_each_entry_rcu(object, &object_list, object_list) { |
@@ -1131,8 +1232,6 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1131 | struct list_head *n = &prev_obj->object_list; | 1232 | struct list_head *n = &prev_obj->object_list; |
1132 | 1233 | ||
1133 | ++(*pos); | 1234 | ++(*pos); |
1134 | if (reported_leaks >= REPORTS_NR) | ||
1135 | goto out; | ||
1136 | 1235 | ||
1137 | rcu_read_lock(); | 1236 | rcu_read_lock(); |
1138 | list_for_each_continue_rcu(n, &object_list) { | 1237 | list_for_each_continue_rcu(n, &object_list) { |
@@ -1141,7 +1240,7 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1141 | break; | 1240 | break; |
1142 | } | 1241 | } |
1143 | rcu_read_unlock(); | 1242 | rcu_read_unlock(); |
1144 | out: | 1243 | |
1145 | put_object(prev_obj); | 1244 | put_object(prev_obj); |
1146 | return next_obj; | 1245 | return next_obj; |
1147 | } | 1246 | } |
@@ -1151,8 +1250,15 @@ out: | |||
1151 | */ | 1250 | */ |
1152 | static void kmemleak_seq_stop(struct seq_file *seq, void *v) | 1251 | static void kmemleak_seq_stop(struct seq_file *seq, void *v) |
1153 | { | 1252 | { |
1154 | if (v) | 1253 | if (!IS_ERR(v)) { |
1155 | put_object(v); | 1254 | /* |
1255 | * kmemleak_seq_start may return ERR_PTR if the scan_mutex | ||
1256 | * waiting was interrupted, so only release it if !IS_ERR. | ||
1257 | */ | ||
1258 | mutex_unlock(&scan_mutex); | ||
1259 | if (v) | ||
1260 | put_object(v); | ||
1261 | } | ||
1156 | } | 1262 | } |
1157 | 1263 | ||
1158 | /* | 1264 | /* |
@@ -1164,10 +1270,8 @@ static int kmemleak_seq_show(struct seq_file *seq, void *v) | |||
1164 | unsigned long flags; | 1270 | unsigned long flags; |
1165 | 1271 | ||
1166 | spin_lock_irqsave(&object->lock, flags); | 1272 | spin_lock_irqsave(&object->lock, flags); |
1167 | if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) { | 1273 | if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) |
1168 | print_unreferenced(seq, object); | 1274 | print_unreferenced(seq, object); |
1169 | reported_leaks++; | ||
1170 | } | ||
1171 | spin_unlock_irqrestore(&object->lock, flags); | 1275 | spin_unlock_irqrestore(&object->lock, flags); |
1172 | return 0; | 1276 | return 0; |
1173 | } | 1277 | } |
@@ -1181,36 +1285,15 @@ static const struct seq_operations kmemleak_seq_ops = { | |||
1181 | 1285 | ||
1182 | static int kmemleak_open(struct inode *inode, struct file *file) | 1286 | static int kmemleak_open(struct inode *inode, struct file *file) |
1183 | { | 1287 | { |
1184 | int ret = 0; | ||
1185 | |||
1186 | if (!atomic_read(&kmemleak_enabled)) | 1288 | if (!atomic_read(&kmemleak_enabled)) |
1187 | return -EBUSY; | 1289 | return -EBUSY; |
1188 | 1290 | ||
1189 | ret = mutex_lock_interruptible(&scan_mutex); | 1291 | return seq_open(file, &kmemleak_seq_ops); |
1190 | if (ret < 0) | ||
1191 | goto out; | ||
1192 | if (file->f_mode & FMODE_READ) { | ||
1193 | ret = seq_open(file, &kmemleak_seq_ops); | ||
1194 | if (ret < 0) | ||
1195 | goto scan_unlock; | ||
1196 | } | ||
1197 | return ret; | ||
1198 | |||
1199 | scan_unlock: | ||
1200 | mutex_unlock(&scan_mutex); | ||
1201 | out: | ||
1202 | return ret; | ||
1203 | } | 1292 | } |
1204 | 1293 | ||
1205 | static int kmemleak_release(struct inode *inode, struct file *file) | 1294 | static int kmemleak_release(struct inode *inode, struct file *file) |
1206 | { | 1295 | { |
1207 | int ret = 0; | 1296 | return seq_release(inode, file); |
1208 | |||
1209 | if (file->f_mode & FMODE_READ) | ||
1210 | seq_release(inode, file); | ||
1211 | mutex_unlock(&scan_mutex); | ||
1212 | |||
1213 | return ret; | ||
1214 | } | 1297 | } |
1215 | 1298 | ||
1216 | /* | 1299 | /* |
@@ -1230,15 +1313,17 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, | |||
1230 | { | 1313 | { |
1231 | char buf[64]; | 1314 | char buf[64]; |
1232 | int buf_size; | 1315 | int buf_size; |
1233 | 1316 | int ret; | |
1234 | if (!atomic_read(&kmemleak_enabled)) | ||
1235 | return -EBUSY; | ||
1236 | 1317 | ||
1237 | buf_size = min(size, (sizeof(buf) - 1)); | 1318 | buf_size = min(size, (sizeof(buf) - 1)); |
1238 | if (strncpy_from_user(buf, user_buf, buf_size) < 0) | 1319 | if (strncpy_from_user(buf, user_buf, buf_size) < 0) |
1239 | return -EFAULT; | 1320 | return -EFAULT; |
1240 | buf[buf_size] = 0; | 1321 | buf[buf_size] = 0; |
1241 | 1322 | ||
1323 | ret = mutex_lock_interruptible(&scan_mutex); | ||
1324 | if (ret < 0) | ||
1325 | return ret; | ||
1326 | |||
1242 | if (strncmp(buf, "off", 3) == 0) | 1327 | if (strncmp(buf, "off", 3) == 0) |
1243 | kmemleak_disable(); | 1328 | kmemleak_disable(); |
1244 | else if (strncmp(buf, "stack=on", 8) == 0) | 1329 | else if (strncmp(buf, "stack=on", 8) == 0) |
@@ -1251,11 +1336,10 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, | |||
1251 | stop_scan_thread(); | 1336 | stop_scan_thread(); |
1252 | else if (strncmp(buf, "scan=", 5) == 0) { | 1337 | else if (strncmp(buf, "scan=", 5) == 0) { |
1253 | unsigned long secs; | 1338 | unsigned long secs; |
1254 | int err; | ||
1255 | 1339 | ||
1256 | err = strict_strtoul(buf + 5, 0, &secs); | 1340 | ret = strict_strtoul(buf + 5, 0, &secs); |
1257 | if (err < 0) | 1341 | if (ret < 0) |
1258 | return err; | 1342 | goto out; |
1259 | stop_scan_thread(); | 1343 | stop_scan_thread(); |
1260 | if (secs) { | 1344 | if (secs) { |
1261 | jiffies_scan_wait = msecs_to_jiffies(secs * 1000); | 1345 | jiffies_scan_wait = msecs_to_jiffies(secs * 1000); |
@@ -1264,7 +1348,12 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, | |||
1264 | } else if (strncmp(buf, "scan", 4) == 0) | 1348 | } else if (strncmp(buf, "scan", 4) == 0) |
1265 | kmemleak_scan(); | 1349 | kmemleak_scan(); |
1266 | else | 1350 | else |
1267 | return -EINVAL; | 1351 | ret = -EINVAL; |
1352 | |||
1353 | out: | ||
1354 | mutex_unlock(&scan_mutex); | ||
1355 | if (ret < 0) | ||
1356 | return ret; | ||
1268 | 1357 | ||
1269 | /* ignore the rest of the buffer, only one command at a time */ | 1358 | /* ignore the rest of the buffer, only one command at a time */ |
1270 | *ppos += size; | 1359 | *ppos += size; |
@@ -1293,7 +1382,7 @@ static int kmemleak_cleanup_thread(void *arg) | |||
1293 | 1382 | ||
1294 | rcu_read_lock(); | 1383 | rcu_read_lock(); |
1295 | list_for_each_entry_rcu(object, &object_list, object_list) | 1384 | list_for_each_entry_rcu(object, &object_list, object_list) |
1296 | delete_object(object->pointer); | 1385 | delete_object_full(object->pointer); |
1297 | rcu_read_unlock(); | 1386 | rcu_read_unlock(); |
1298 | mutex_unlock(&scan_mutex); | 1387 | mutex_unlock(&scan_mutex); |
1299 | 1388 | ||
@@ -1388,6 +1477,9 @@ void __init kmemleak_init(void) | |||
1388 | case KMEMLEAK_FREE: | 1477 | case KMEMLEAK_FREE: |
1389 | kmemleak_free(log->ptr); | 1478 | kmemleak_free(log->ptr); |
1390 | break; | 1479 | break; |
1480 | case KMEMLEAK_FREE_PART: | ||
1481 | kmemleak_free_part(log->ptr, log->size); | ||
1482 | break; | ||
1391 | case KMEMLEAK_NOT_LEAK: | 1483 | case KMEMLEAK_NOT_LEAK: |
1392 | kmemleak_not_leak(log->ptr); | 1484 | kmemleak_not_leak(log->ptr); |
1393 | break; | 1485 | break; |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index a35eeab2724c..caa92689aac9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -4745,8 +4745,10 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
4745 | * some pages at the end of hash table which | 4745 | * some pages at the end of hash table which |
4746 | * alloc_pages_exact() automatically does | 4746 | * alloc_pages_exact() automatically does |
4747 | */ | 4747 | */ |
4748 | if (get_order(size) < MAX_ORDER) | 4748 | if (get_order(size) < MAX_ORDER) { |
4749 | table = alloc_pages_exact(size, GFP_ATOMIC); | 4749 | table = alloc_pages_exact(size, GFP_ATOMIC); |
4750 | kmemleak_alloc(table, size, 1, GFP_ATOMIC); | ||
4751 | } | ||
4750 | } | 4752 | } |
4751 | } while (!table && size > PAGE_SIZE && --log2qty); | 4753 | } while (!table && size > PAGE_SIZE && --log2qty); |
4752 | 4754 | ||
@@ -4764,16 +4766,6 @@ void *__init alloc_large_system_hash(const char *tablename, | |||
4764 | if (_hash_mask) | 4766 | if (_hash_mask) |
4765 | *_hash_mask = (1 << log2qty) - 1; | 4767 | *_hash_mask = (1 << log2qty) - 1; |
4766 | 4768 | ||
4767 | /* | ||
4768 | * If hashdist is set, the table allocation is done with __vmalloc() | ||
4769 | * which invokes the kmemleak_alloc() callback. This function may also | ||
4770 | * be called before the slab and kmemleak are initialised when | ||
4771 | * kmemleak simply buffers the request to be executed later | ||
4772 | * (GFP_ATOMIC flag ignored in this case). | ||
4773 | */ | ||
4774 | if (!hashdist) | ||
4775 | kmemleak_alloc(table, size, 1, GFP_ATOMIC); | ||
4776 | |||
4777 | return table; | 4769 | return table; |
4778 | } | 4770 | } |
4779 | 4771 | ||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/kmemcheck.h> | 21 | #include <linux/kmemcheck.h> |
22 | #include <linux/cpu.h> | 22 | #include <linux/cpu.h> |
23 | #include <linux/cpuset.h> | 23 | #include <linux/cpuset.h> |
24 | #include <linux/kmemleak.h> | ||
25 | #include <linux/mempolicy.h> | 24 | #include <linux/mempolicy.h> |
26 | #include <linux/ctype.h> | 25 | #include <linux/ctype.h> |
27 | #include <linux/debugobjects.h> | 26 | #include <linux/debugobjects.h> |
@@ -2835,13 +2834,15 @@ EXPORT_SYMBOL(__kmalloc); | |||
2835 | static void *kmalloc_large_node(size_t size, gfp_t flags, int node) | 2834 | static void *kmalloc_large_node(size_t size, gfp_t flags, int node) |
2836 | { | 2835 | { |
2837 | struct page *page; | 2836 | struct page *page; |
2837 | void *ptr = NULL; | ||
2838 | 2838 | ||
2839 | flags |= __GFP_COMP | __GFP_NOTRACK; | 2839 | flags |= __GFP_COMP | __GFP_NOTRACK; |
2840 | page = alloc_pages_node(node, flags, get_order(size)); | 2840 | page = alloc_pages_node(node, flags, get_order(size)); |
2841 | if (page) | 2841 | if (page) |
2842 | return page_address(page); | 2842 | ptr = page_address(page); |
2843 | else | 2843 | |
2844 | return NULL; | 2844 | kmemleak_alloc(ptr, size, 1, flags); |
2845 | return ptr; | ||
2845 | } | 2846 | } |
2846 | 2847 | ||
2847 | #ifdef CONFIG_NUMA | 2848 | #ifdef CONFIG_NUMA |
@@ -2926,6 +2927,7 @@ void kfree(const void *x) | |||
2926 | page = virt_to_head_page(x); | 2927 | page = virt_to_head_page(x); |
2927 | if (unlikely(!PageSlab(page))) { | 2928 | if (unlikely(!PageSlab(page))) { |
2928 | BUG_ON(!PageCompound(page)); | 2929 | BUG_ON(!PageCompound(page)); |
2930 | kmemleak_free(x); | ||
2929 | put_page(page); | 2931 | put_page(page); |
2930 | return; | 2932 | return; |
2931 | } | 2933 | } |
diff --git a/net/9p/client.c b/net/9p/client.c index dd43a8289b0d..787ccddb85ea 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -117,9 +117,6 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
117 | } | 117 | } |
118 | } | 118 | } |
119 | 119 | ||
120 | if (!clnt->trans_mod) | ||
121 | clnt->trans_mod = v9fs_get_default_trans(); | ||
122 | |||
123 | kfree(options); | 120 | kfree(options); |
124 | return ret; | 121 | return ret; |
125 | } | 122 | } |
@@ -689,6 +686,9 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | |||
689 | if (err < 0) | 686 | if (err < 0) |
690 | goto error; | 687 | goto error; |
691 | 688 | ||
689 | if (!clnt->trans_mod) | ||
690 | clnt->trans_mod = v9fs_get_default_trans(); | ||
691 | |||
692 | if (clnt->trans_mod == NULL) { | 692 | if (clnt->trans_mod == NULL) { |
693 | err = -EPROTONOSUPPORT; | 693 | err = -EPROTONOSUPPORT; |
694 | P9_DPRINTK(P9_DEBUG_ERROR, | 694 | P9_DPRINTK(P9_DEBUG_ERROR, |
@@ -1098,7 +1098,6 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, | |||
1098 | 1098 | ||
1099 | if (data) { | 1099 | if (data) { |
1100 | memmove(data, dataptr, count); | 1100 | memmove(data, dataptr, count); |
1101 | data += count; | ||
1102 | } | 1101 | } |
1103 | 1102 | ||
1104 | if (udata) { | 1103 | if (udata) { |
@@ -1192,9 +1191,9 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | |||
1192 | 1191 | ||
1193 | err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret); | 1192 | err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret); |
1194 | if (err) { | 1193 | if (err) { |
1195 | ret = ERR_PTR(err); | ||
1196 | p9pdu_dump(1, req->rc); | 1194 | p9pdu_dump(1, req->rc); |
1197 | goto free_and_error; | 1195 | p9_free_req(clnt, req); |
1196 | goto error; | ||
1198 | } | 1197 | } |
1199 | 1198 | ||
1200 | P9_DPRINTK(P9_DEBUG_9P, | 1199 | P9_DPRINTK(P9_DEBUG_9P, |
@@ -1211,8 +1210,6 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | |||
1211 | p9_free_req(clnt, req); | 1210 | p9_free_req(clnt, req); |
1212 | return ret; | 1211 | return ret; |
1213 | 1212 | ||
1214 | free_and_error: | ||
1215 | p9_free_req(clnt, req); | ||
1216 | error: | 1213 | error: |
1217 | kfree(ret); | 1214 | kfree(ret); |
1218 | return ERR_PTR(err); | 1215 | return ERR_PTR(err); |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 590b83963622..bfbe13786bb4 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/capability.h> | 54 | #include <linux/capability.h> |
55 | #include <linux/module.h> | 55 | #include <linux/module.h> |
56 | #include <linux/if_arp.h> | 56 | #include <linux/if_arp.h> |
57 | #include <linux/smp_lock.h> | ||
57 | #include <linux/termios.h> /* For TIOCOUTQ/INQ */ | 58 | #include <linux/termios.h> /* For TIOCOUTQ/INQ */ |
58 | #include <net/datalink.h> | 59 | #include <net/datalink.h> |
59 | #include <net/psnap.h> | 60 | #include <net/psnap.h> |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 95d7f32643ae..72720c710351 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -75,6 +75,7 @@ static __initdata const char banner[] = KERN_INFO | |||
75 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); | 75 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); |
76 | MODULE_LICENSE("Dual BSD/GPL"); | 76 | MODULE_LICENSE("Dual BSD/GPL"); |
77 | MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); | 77 | MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); |
78 | MODULE_ALIAS("can-proto-2"); | ||
78 | 79 | ||
79 | /* easy access to can_frame payload */ | 80 | /* easy access to can_frame payload */ |
80 | static inline u64 GET_U64(const struct can_frame *cp) | 81 | static inline u64 GET_U64(const struct can_frame *cp) |
@@ -1469,6 +1470,9 @@ static int bcm_release(struct socket *sock) | |||
1469 | bo->ifindex = 0; | 1470 | bo->ifindex = 0; |
1470 | } | 1471 | } |
1471 | 1472 | ||
1473 | sock_orphan(sk); | ||
1474 | sock->sk = NULL; | ||
1475 | |||
1472 | release_sock(sk); | 1476 | release_sock(sk); |
1473 | sock_put(sk); | 1477 | sock_put(sk); |
1474 | 1478 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index 6aa154e806ae..f4cc44548bda 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -62,6 +62,7 @@ static __initdata const char banner[] = | |||
62 | MODULE_DESCRIPTION("PF_CAN raw protocol"); | 62 | MODULE_DESCRIPTION("PF_CAN raw protocol"); |
63 | MODULE_LICENSE("Dual BSD/GPL"); | 63 | MODULE_LICENSE("Dual BSD/GPL"); |
64 | MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>"); | 64 | MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>"); |
65 | MODULE_ALIAS("can-proto-1"); | ||
65 | 66 | ||
66 | #define MASK_ALL 0 | 67 | #define MASK_ALL 0 |
67 | 68 | ||
@@ -306,6 +307,9 @@ static int raw_release(struct socket *sock) | |||
306 | ro->bound = 0; | 307 | ro->bound = 0; |
307 | ro->count = 0; | 308 | ro->count = 0; |
308 | 309 | ||
310 | sock_orphan(sk); | ||
311 | sock->sk = NULL; | ||
312 | |||
309 | release_sock(sk); | 313 | release_sock(sk); |
310 | sock_put(sk); | 314 | sock_put(sk); |
311 | 315 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 6354863b1c68..bbb25be7ddfe 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -631,7 +631,7 @@ set_rcvbuf: | |||
631 | 631 | ||
632 | case SO_TIMESTAMPING: | 632 | case SO_TIMESTAMPING: |
633 | if (val & ~SOF_TIMESTAMPING_MASK) { | 633 | if (val & ~SOF_TIMESTAMPING_MASK) { |
634 | ret = EINVAL; | 634 | ret = -EINVAL; |
635 | break; | 635 | break; |
636 | } | 636 | } |
637 | sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE, | 637 | sock_valbool_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE, |
@@ -919,13 +919,19 @@ static inline void sock_lock_init(struct sock *sk) | |||
919 | af_family_keys + sk->sk_family); | 919 | af_family_keys + sk->sk_family); |
920 | } | 920 | } |
921 | 921 | ||
922 | /* | ||
923 | * Copy all fields from osk to nsk but nsk->sk_refcnt must not change yet, | ||
924 | * even temporarly, because of RCU lookups. sk_node should also be left as is. | ||
925 | */ | ||
922 | static void sock_copy(struct sock *nsk, const struct sock *osk) | 926 | static void sock_copy(struct sock *nsk, const struct sock *osk) |
923 | { | 927 | { |
924 | #ifdef CONFIG_SECURITY_NETWORK | 928 | #ifdef CONFIG_SECURITY_NETWORK |
925 | void *sptr = nsk->sk_security; | 929 | void *sptr = nsk->sk_security; |
926 | #endif | 930 | #endif |
927 | 931 | BUILD_BUG_ON(offsetof(struct sock, sk_copy_start) != | |
928 | memcpy(nsk, osk, osk->sk_prot->obj_size); | 932 | sizeof(osk->sk_node) + sizeof(osk->sk_refcnt)); |
933 | memcpy(&nsk->sk_copy_start, &osk->sk_copy_start, | ||
934 | osk->sk_prot->obj_size - offsetof(struct sock, sk_copy_start)); | ||
929 | #ifdef CONFIG_SECURITY_NETWORK | 935 | #ifdef CONFIG_SECURITY_NETWORK |
930 | nsk->sk_security = sptr; | 936 | nsk->sk_security = sptr; |
931 | security_sk_clone(osk, nsk); | 937 | security_sk_clone(osk, nsk); |
@@ -939,8 +945,23 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | |||
939 | struct kmem_cache *slab; | 945 | struct kmem_cache *slab; |
940 | 946 | ||
941 | slab = prot->slab; | 947 | slab = prot->slab; |
942 | if (slab != NULL) | 948 | if (slab != NULL) { |
943 | sk = kmem_cache_alloc(slab, priority); | 949 | sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO); |
950 | if (!sk) | ||
951 | return sk; | ||
952 | if (priority & __GFP_ZERO) { | ||
953 | /* | ||
954 | * caches using SLAB_DESTROY_BY_RCU should let | ||
955 | * sk_node.next un-modified. Special care is taken | ||
956 | * when initializing object to zero. | ||
957 | */ | ||
958 | if (offsetof(struct sock, sk_node.next) != 0) | ||
959 | memset(sk, 0, offsetof(struct sock, sk_node.next)); | ||
960 | memset(&sk->sk_node.pprev, 0, | ||
961 | prot->obj_size - offsetof(struct sock, | ||
962 | sk_node.pprev)); | ||
963 | } | ||
964 | } | ||
944 | else | 965 | else |
945 | sk = kmalloc(prot->obj_size, priority); | 966 | sk = kmalloc(prot->obj_size, priority); |
946 | 967 | ||
@@ -1125,6 +1146,11 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
1125 | 1146 | ||
1126 | newsk->sk_err = 0; | 1147 | newsk->sk_err = 0; |
1127 | newsk->sk_priority = 0; | 1148 | newsk->sk_priority = 0; |
1149 | /* | ||
1150 | * Before updating sk_refcnt, we must commit prior changes to memory | ||
1151 | * (Documentation/RCU/rculist_nulls.txt for details) | ||
1152 | */ | ||
1153 | smp_wmb(); | ||
1128 | atomic_set(&newsk->sk_refcnt, 2); | 1154 | atomic_set(&newsk->sk_refcnt, 2); |
1129 | 1155 | ||
1130 | /* | 1156 | /* |
@@ -1840,6 +1866,11 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1840 | 1866 | ||
1841 | sk->sk_stamp = ktime_set(-1L, 0); | 1867 | sk->sk_stamp = ktime_set(-1L, 0); |
1842 | 1868 | ||
1869 | /* | ||
1870 | * Before updating sk_refcnt, we must commit prior changes to memory | ||
1871 | * (Documentation/RCU/rculist_nulls.txt for details) | ||
1872 | */ | ||
1873 | smp_wmb(); | ||
1843 | atomic_set(&sk->sk_refcnt, 1); | 1874 | atomic_set(&sk->sk_refcnt, 1); |
1844 | atomic_set(&sk->sk_wmem_alloc, 1); | 1875 | atomic_set(&sk->sk_wmem_alloc, 1); |
1845 | atomic_set(&sk->sk_drops, 0); | 1876 | atomic_set(&sk->sk_drops, 0); |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 44e2a3d2359a..cb4a0f4bd5e5 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -735,10 +735,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
735 | } | 735 | } |
736 | 736 | ||
737 | tos = tiph->tos; | 737 | tos = tiph->tos; |
738 | if (tos&1) { | 738 | if (tos == 1) { |
739 | tos = 0; | ||
739 | if (skb->protocol == htons(ETH_P_IP)) | 740 | if (skb->protocol == htons(ETH_P_IP)) |
740 | tos = old_iph->tos; | 741 | tos = old_iph->tos; |
741 | tos &= ~1; | ||
742 | } | 742 | } |
743 | 743 | ||
744 | { | 744 | { |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 247026282669..7d0821054729 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -1243,7 +1243,6 @@ int ip_push_pending_frames(struct sock *sk) | |||
1243 | skb->len += tmp_skb->len; | 1243 | skb->len += tmp_skb->len; |
1244 | skb->data_len += tmp_skb->len; | 1244 | skb->data_len += tmp_skb->len; |
1245 | skb->truesize += tmp_skb->truesize; | 1245 | skb->truesize += tmp_skb->truesize; |
1246 | __sock_put(tmp_skb->sk); | ||
1247 | tmp_skb->destructor = NULL; | 1246 | tmp_skb->destructor = NULL; |
1248 | tmp_skb->sk = NULL; | 1247 | tmp_skb->sk = NULL; |
1249 | } | 1248 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5a1ca2698c88..6d88219c5e22 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1160,6 +1160,7 @@ struct request_sock_ops tcp_request_sock_ops __read_mostly = { | |||
1160 | #ifdef CONFIG_TCP_MD5SIG | 1160 | #ifdef CONFIG_TCP_MD5SIG |
1161 | static struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { | 1161 | static struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { |
1162 | .md5_lookup = tcp_v4_reqsk_md5_lookup, | 1162 | .md5_lookup = tcp_v4_reqsk_md5_lookup, |
1163 | .calc_md5_hash = tcp_v4_md5_hash_skb, | ||
1163 | }; | 1164 | }; |
1164 | #endif | 1165 | #endif |
1165 | 1166 | ||
@@ -1373,7 +1374,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1373 | */ | 1374 | */ |
1374 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); | 1375 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); |
1375 | if (newkey != NULL) | 1376 | if (newkey != NULL) |
1376 | tcp_v4_md5_do_add(newsk, inet_sk(sk)->daddr, | 1377 | tcp_v4_md5_do_add(newsk, newinet->daddr, |
1377 | newkey, key->keylen); | 1378 | newkey, key->keylen); |
1378 | newsk->sk_route_caps &= ~NETIF_F_GSO_MASK; | 1379 | newsk->sk_route_caps &= ~NETIF_F_GSO_MASK; |
1379 | } | 1380 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5bdf08d312d9..bd62712848fa 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2261,7 +2261,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2261 | #ifdef CONFIG_TCP_MD5SIG | 2261 | #ifdef CONFIG_TCP_MD5SIG |
2262 | /* Okay, we have all we need - do the md5 hash if needed */ | 2262 | /* Okay, we have all we need - do the md5 hash if needed */ |
2263 | if (md5) { | 2263 | if (md5) { |
2264 | tp->af_specific->calc_md5_hash(md5_hash_location, | 2264 | tcp_rsk(req)->af_specific->calc_md5_hash(md5_hash_location, |
2265 | md5, NULL, req, skb); | 2265 | md5, NULL, req, skb); |
2266 | } | 2266 | } |
2267 | #endif | 2267 | #endif |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 7c76e3d18215..87f8419a68fd 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1484,7 +1484,6 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1484 | skb->len += tmp_skb->len; | 1484 | skb->len += tmp_skb->len; |
1485 | skb->data_len += tmp_skb->len; | 1485 | skb->data_len += tmp_skb->len; |
1486 | skb->truesize += tmp_skb->truesize; | 1486 | skb->truesize += tmp_skb->truesize; |
1487 | __sock_put(tmp_skb->sk); | ||
1488 | tmp_skb->destructor = NULL; | 1487 | tmp_skb->destructor = NULL; |
1489 | tmp_skb->sk = NULL; | 1488 | tmp_skb->sk = NULL; |
1490 | } | 1489 | } |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 68e52308e552..98b7327d0949 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -1018,6 +1018,7 @@ static void ipip6_tunnel_setup(struct net_device *dev) | |||
1018 | dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); | 1018 | dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); |
1019 | dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr); | 1019 | dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr); |
1020 | dev->flags = IFF_NOARP; | 1020 | dev->flags = IFF_NOARP; |
1021 | dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; | ||
1021 | dev->iflink = 0; | 1022 | dev->iflink = 0; |
1022 | dev->addr_len = 4; | 1023 | dev->addr_len = 4; |
1023 | dev->features |= NETIF_F_NETNS_LOCAL; | 1024 | dev->features |= NETIF_F_NETNS_LOCAL; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 58810c65b635..d849dd53b788 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -896,6 +896,7 @@ struct request_sock_ops tcp6_request_sock_ops __read_mostly = { | |||
896 | #ifdef CONFIG_TCP_MD5SIG | 896 | #ifdef CONFIG_TCP_MD5SIG |
897 | static struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { | 897 | static struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { |
898 | .md5_lookup = tcp_v6_reqsk_md5_lookup, | 898 | .md5_lookup = tcp_v6_reqsk_md5_lookup, |
899 | .calc_md5_hash = tcp_v6_md5_hash_skb, | ||
899 | }; | 900 | }; |
900 | #endif | 901 | #endif |
901 | 902 | ||
@@ -1441,7 +1442,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1441 | */ | 1442 | */ |
1442 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); | 1443 | char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC); |
1443 | if (newkey != NULL) | 1444 | if (newkey != NULL) |
1444 | tcp_v6_md5_do_add(newsk, &inet6_sk(sk)->daddr, | 1445 | tcp_v6_md5_do_add(newsk, &newnp->daddr, |
1445 | newkey, key->keylen); | 1446 | newkey, key->keylen); |
1446 | } | 1447 | } |
1447 | #endif | 1448 | #endif |
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 417b0e309495..f1118d92a191 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/netdevice.h> | 41 | #include <linux/netdevice.h> |
42 | #include <linux/uio.h> | 42 | #include <linux/uio.h> |
43 | #include <linux/skbuff.h> | 43 | #include <linux/skbuff.h> |
44 | #include <linux/smp_lock.h> | ||
44 | #include <linux/socket.h> | 45 | #include <linux/socket.h> |
45 | #include <linux/sockios.h> | 46 | #include <linux/sockios.h> |
46 | #include <linux/string.h> | 47 | #include <linux/string.h> |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index cb762c8723ea..80cf29aae096 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/capability.h> | 45 | #include <linux/capability.h> |
46 | #include <linux/module.h> | 46 | #include <linux/module.h> |
47 | #include <linux/types.h> | 47 | #include <linux/types.h> |
48 | #include <linux/smp_lock.h> | ||
48 | #include <linux/socket.h> | 49 | #include <linux/socket.h> |
49 | #include <linux/sockios.h> | 50 | #include <linux/sockios.h> |
50 | #include <linux/init.h> | 51 | #include <linux/init.h> |
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index bccf4d0059f0..b001c361ad30 100644 --- a/net/irda/irnet/irnet.h +++ b/net/irda/irnet/irnet.h | |||
@@ -241,7 +241,6 @@ | |||
241 | #include <linux/module.h> | 241 | #include <linux/module.h> |
242 | 242 | ||
243 | #include <linux/kernel.h> | 243 | #include <linux/kernel.h> |
244 | #include <linux/smp_lock.h> | ||
245 | #include <linux/skbuff.h> | 244 | #include <linux/skbuff.h> |
246 | #include <linux/tty.h> | 245 | #include <linux/tty.h> |
247 | #include <linux/proc_fs.h> | 246 | #include <linux/proc_fs.h> |
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index 6d8ae03c14f5..68cbcb19cbd8 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * 2) as a control channel (write commands, read events) | 13 | * 2) as a control channel (write commands, read events) |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/smp_lock.h> | ||
16 | #include "irnet_ppp.h" /* Private header */ | 17 | #include "irnet_ppp.h" /* Private header */ |
17 | /* Please put other headers in irnet.h - Thanks */ | 18 | /* Please put other headers in irnet.h - Thanks */ |
18 | 19 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 7508f11c5b39..b5869b9574b0 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -561,23 +561,38 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, | |||
561 | } | 561 | } |
562 | } | 562 | } |
563 | 563 | ||
564 | ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp); | 564 | /* |
565 | * Do not use kmem_cache_zalloc(), as this cache uses | ||
566 | * SLAB_DESTROY_BY_RCU. | ||
567 | */ | ||
568 | ct = kmem_cache_alloc(nf_conntrack_cachep, gfp); | ||
565 | if (ct == NULL) { | 569 | if (ct == NULL) { |
566 | pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n"); | 570 | pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n"); |
567 | atomic_dec(&net->ct.count); | 571 | atomic_dec(&net->ct.count); |
568 | return ERR_PTR(-ENOMEM); | 572 | return ERR_PTR(-ENOMEM); |
569 | } | 573 | } |
570 | 574 | /* | |
575 | * Let ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.next | ||
576 | * and ct->tuplehash[IP_CT_DIR_REPLY].hnnode.next unchanged. | ||
577 | */ | ||
578 | memset(&ct->tuplehash[IP_CT_DIR_MAX], 0, | ||
579 | sizeof(*ct) - offsetof(struct nf_conn, tuplehash[IP_CT_DIR_MAX])); | ||
571 | spin_lock_init(&ct->lock); | 580 | spin_lock_init(&ct->lock); |
572 | atomic_set(&ct->ct_general.use, 1); | ||
573 | ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; | 581 | ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; |
582 | ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL; | ||
574 | ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; | 583 | ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; |
584 | ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev = NULL; | ||
575 | /* Don't set timer yet: wait for confirmation */ | 585 | /* Don't set timer yet: wait for confirmation */ |
576 | setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); | 586 | setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); |
577 | #ifdef CONFIG_NET_NS | 587 | #ifdef CONFIG_NET_NS |
578 | ct->ct_net = net; | 588 | ct->ct_net = net; |
579 | #endif | 589 | #endif |
580 | 590 | ||
591 | /* | ||
592 | * changes to lookup keys must be done before setting refcnt to 1 | ||
593 | */ | ||
594 | smp_wmb(); | ||
595 | atomic_set(&ct->ct_general.use, 1); | ||
581 | return ct; | 596 | return ct; |
582 | } | 597 | } |
583 | EXPORT_SYMBOL_GPL(nf_conntrack_alloc); | 598 | EXPORT_SYMBOL_GPL(nf_conntrack_alloc); |
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 863e40977a4d..0f482e2440b4 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c | |||
@@ -330,7 +330,8 @@ static bool xt_osf_match_packet(const struct sk_buff *skb, | |||
330 | fcount++; | 330 | fcount++; |
331 | 331 | ||
332 | if (info->flags & XT_OSF_LOG) | 332 | if (info->flags & XT_OSF_LOG) |
333 | nf_log_packet(p->hooknum, 0, skb, p->in, p->out, NULL, | 333 | nf_log_packet(p->family, p->hooknum, skb, |
334 | p->in, p->out, NULL, | ||
334 | "%s [%s:%s] : %pi4:%d -> %pi4:%d hops=%d\n", | 335 | "%s [%s:%s] : %pi4:%d -> %pi4:%d hops=%d\n", |
335 | f->genre, f->version, f->subtype, | 336 | f->genre, f->version, f->subtype, |
336 | &ip->saddr, ntohs(tcp->source), | 337 | &ip->saddr, ntohs(tcp->source), |
@@ -345,7 +346,7 @@ static bool xt_osf_match_packet(const struct sk_buff *skb, | |||
345 | rcu_read_unlock(); | 346 | rcu_read_unlock(); |
346 | 347 | ||
347 | if (!fcount && (info->flags & XT_OSF_LOG)) | 348 | if (!fcount && (info->flags & XT_OSF_LOG)) |
348 | nf_log_packet(p->hooknum, 0, skb, p->in, p->out, NULL, | 349 | nf_log_packet(p->family, p->hooknum, skb, p->in, p->out, NULL, |
349 | "Remote OS is not known: %pi4:%u -> %pi4:%u\n", | 350 | "Remote OS is not known: %pi4:%u -> %pi4:%u\n", |
350 | &ip->saddr, ntohs(tcp->source), | 351 | &ip->saddr, ntohs(tcp->source), |
351 | &ip->daddr, ntohs(tcp->dest)); | 352 | &ip->daddr, ntohs(tcp->dest)); |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 5bc2f45bddf0..ebfcf9b89909 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/kallsyms.h> | 28 | #include <linux/kallsyms.h> |
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
32 | #include <linux/utsname.h> | 31 | #include <linux/utsname.h> |
33 | #include <linux/workqueue.h> | 32 | #include <linux/workqueue.h> |
34 | #include <linux/in6.h> | 33 | #include <linux/in6.h> |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 1102ce1251f7..8f459abe97cf 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/mempool.h> | 17 | #include <linux/mempool.h> |
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/smp_lock.h> | ||
20 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
21 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
22 | 21 | ||
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 6f33d33cc064..27d44332f017 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/smp_lock.h> | ||
8 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
9 | #include <linux/freezer.h> | 10 | #include <linux/freezer.h> |
10 | #include <linux/kthread.h> | 11 | #include <linux/kthread.h> |
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index 466e2d22d256..258daa80ad92 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/kernel.h> | 48 | #include <linux/kernel.h> |
49 | #include <linux/module.h> /* support for loadable modules */ | 49 | #include <linux/module.h> /* support for loadable modules */ |
50 | #include <linux/slab.h> /* kmalloc(), kfree() */ | 50 | #include <linux/slab.h> /* kmalloc(), kfree() */ |
51 | #include <linux/smp_lock.h> | ||
51 | #include <linux/mm.h> | 52 | #include <linux/mm.h> |
52 | #include <linux/string.h> /* inline mem*, str* functions */ | 53 | #include <linux/string.h> /* inline mem*, str* functions */ |
53 | 54 | ||
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 21cdc872004e..5e6c072c64d3 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
41 | #include <linux/kernel.h> | 41 | #include <linux/kernel.h> |
42 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
43 | #include <linux/smp_lock.h> | ||
43 | #include <linux/timer.h> | 44 | #include <linux/timer.h> |
44 | #include <linux/string.h> | 45 | #include <linux/string.h> |
45 | #include <linux/net.h> | 46 | #include <linux/net.h> |
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h index 9977a756fb32..f24ae370e514 100644 --- a/samples/trace_events/trace-events-sample.h +++ b/samples/trace_events/trace-events-sample.h | |||
@@ -1,21 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Notice that this file is not protected like a normal header. | ||
3 | * We also must allow for rereading of this file. The | ||
4 | * | ||
5 | * || defined(TRACE_HEADER_MULTI_READ) | ||
6 | * | ||
7 | * serves this purpose. | ||
8 | */ | ||
9 | #if !defined(_TRACE_EVENT_SAMPLE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
10 | #define _TRACE_EVENT_SAMPLE_H | ||
11 | |||
12 | /* | ||
13 | * All trace headers should include tracepoint.h, until we finally | ||
14 | * make it into a standard header. | ||
15 | */ | ||
16 | #include <linux/tracepoint.h> | ||
17 | |||
18 | /* | ||
19 | * If TRACE_SYSTEM is defined, that will be the directory created | 2 | * If TRACE_SYSTEM is defined, that will be the directory created |
20 | * in the ftrace directory under /debugfs/tracing/events/<system> | 3 | * in the ftrace directory under /debugfs/tracing/events/<system> |
21 | * | 4 | * |
@@ -34,11 +17,31 @@ | |||
34 | * #define TRACE_INCLUDE_FILE trace-events-sample | 17 | * #define TRACE_INCLUDE_FILE trace-events-sample |
35 | * | 18 | * |
36 | * As we do an the bottom of this file. | 19 | * As we do an the bottom of this file. |
20 | * | ||
21 | * Notice that TRACE_SYSTEM should be defined outside of #if | ||
22 | * protection, just like TRACE_INCLUDE_FILE. | ||
37 | */ | 23 | */ |
38 | #undef TRACE_SYSTEM | 24 | #undef TRACE_SYSTEM |
39 | #define TRACE_SYSTEM sample | 25 | #define TRACE_SYSTEM sample |
40 | 26 | ||
41 | /* | 27 | /* |
28 | * Notice that this file is not protected like a normal header. | ||
29 | * We also must allow for rereading of this file. The | ||
30 | * | ||
31 | * || defined(TRACE_HEADER_MULTI_READ) | ||
32 | * | ||
33 | * serves this purpose. | ||
34 | */ | ||
35 | #if !defined(_TRACE_EVENT_SAMPLE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
36 | #define _TRACE_EVENT_SAMPLE_H | ||
37 | |||
38 | /* | ||
39 | * All trace headers should include tracepoint.h, until we finally | ||
40 | * make it into a standard header. | ||
41 | */ | ||
42 | #include <linux/tracepoint.h> | ||
43 | |||
44 | /* | ||
42 | * The TRACE_EVENT macro is broken up into 5 parts. | 45 | * The TRACE_EVENT macro is broken up into 5 parts. |
43 | * | 46 | * |
44 | * name: name of the trace point. This is also how to enable the tracepoint. | 47 | * name: name of the trace point. This is also how to enable the tracepoint. |
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c index 86d95cca46a7..f2375ad7ebc9 100644 --- a/scripts/kconfig/lxdialog/util.c +++ b/scripts/kconfig/lxdialog/util.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <stdarg.h> | ||
23 | |||
22 | #include "dialog.h" | 24 | #include "dialog.h" |
23 | 25 | ||
24 | struct dialog_info dlg; | 26 | struct dialog_info dlg; |
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 3bcacb4bfd3a..25b60bc117f7 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
@@ -888,6 +888,8 @@ int main(int ac, char **av) | |||
888 | single_menu_mode = 1; | 888 | single_menu_mode = 1; |
889 | } | 889 | } |
890 | 890 | ||
891 | initscr(); | ||
892 | |||
891 | getyx(stdscr, saved_y, saved_x); | 893 | getyx(stdscr, saved_y, saved_x); |
892 | if (init_dialog(NULL)) { | 894 | if (init_dialog(NULL)) { |
893 | fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); | 895 | fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); |
diff --git a/scripts/package/builddeb b/scripts/package/builddeb index b19f1f4962e3..8b357b0bd250 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb | |||
@@ -89,7 +89,7 @@ for script in postinst postrm preinst prerm ; do | |||
89 | set -e | 89 | set -e |
90 | 90 | ||
91 | # Pass maintainer script parameters to hook scripts | 91 | # Pass maintainer script parameters to hook scripts |
92 | export DEB_MAINT_PARAMS="\$@" | 92 | export DEB_MAINT_PARAMS="\$*" |
93 | 93 | ||
94 | test -d $debhookdir/$script.d && run-parts --arg="$version" $debhookdir/$script.d | 94 | test -d $debhookdir/$script.d && run-parts --arg="$version" $debhookdir/$script.d |
95 | exit 0 | 95 | exit 0 |
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c index 108b643229ba..6205f37d547c 100644 --- a/sound/arm/pxa2xx-pcm-lib.c +++ b/sound/arm/pxa2xx-pcm-lib.c | |||
@@ -75,7 +75,7 @@ int __pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
75 | { | 75 | { |
76 | struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; | 76 | struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; |
77 | 77 | ||
78 | if (rtd && rtd->params) | 78 | if (rtd && rtd->params && rtd->params->drcmr) |
79 | *rtd->params->drcmr = 0; | 79 | *rtd->params->drcmr = 0; |
80 | 80 | ||
81 | snd_pcm_set_runtime_buffer(substream, NULL); | 81 | snd_pcm_set_runtime_buffer(substream, NULL); |
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index 1bcb360330e5..941f64a853eb 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile | |||
@@ -3,10 +3,6 @@ | |||
3 | # Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz> | 3 | # Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz> |
4 | # | 4 | # |
5 | 5 | ||
6 | ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) | ||
7 | obj-$(CONFIG_SND_SEQUENCER) += oss/ | ||
8 | endif | ||
9 | |||
10 | snd-seq-device-objs := seq_device.o | 6 | snd-seq-device-objs := seq_device.o |
11 | snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ | 7 | snd-seq-objs := seq.o seq_lock.o seq_clientmgr.o seq_memory.o seq_queue.o \ |
12 | seq_fifo.o seq_prioq.o seq_timer.o \ | 8 | seq_fifo.o seq_prioq.o seq_timer.o \ |
@@ -19,7 +15,8 @@ snd-seq-virmidi-objs := seq_virmidi.o | |||
19 | 15 | ||
20 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o | 16 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq.o snd-seq-device.o |
21 | ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) | 17 | ifeq ($(CONFIG_SND_SEQUENCER_OSS),y) |
22 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o | 18 | obj-$(CONFIG_SND_SEQUENCER) += snd-seq-midi-event.o |
19 | obj-$(CONFIG_SND_SEQUENCER) += oss/ | ||
23 | endif | 20 | endif |
24 | obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o | 21 | obj-$(CONFIG_SND_SEQ_DUMMY) += snd-seq-dummy.o |
25 | 22 | ||
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index edb11eefdfe3..2dcf45bf7293 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c | |||
@@ -795,13 +795,13 @@ static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
795 | if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE)) | 795 | if (!(pcmp->flags & SNDRV_GF1_PCM_PFLG_ACTIVE)) |
796 | continue; | 796 | continue; |
797 | /* load real volume - better precision */ | 797 | /* load real volume - better precision */ |
798 | spin_lock_irqsave(&gus->reg_lock, flags); | 798 | spin_lock(&gus->reg_lock); |
799 | snd_gf1_select_voice(gus, pvoice->number); | 799 | snd_gf1_select_voice(gus, pvoice->number); |
800 | snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); | 800 | snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); |
801 | vol = pvoice == pcmp->pvoices[0] ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right; | 801 | vol = pvoice == pcmp->pvoices[0] ? gus->gf1.pcm_volume_level_left : gus->gf1.pcm_volume_level_right; |
802 | snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol); | 802 | snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, vol); |
803 | pcmp->final_volume = 1; | 803 | pcmp->final_volume = 1; |
804 | spin_unlock_irqrestore(&gus->reg_lock, flags); | 804 | spin_unlock(&gus->reg_lock); |
805 | } | 805 | } |
806 | spin_unlock_irqrestore(&gus->voice_alloc, flags); | 806 | spin_unlock_irqrestore(&gus->voice_alloc, flags); |
807 | return change; | 807 | return change; |
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index f24bf1ecb36d..15e4138bce17 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -325,9 +325,9 @@ static struct snd_pcm_hardware snd_ca0106_capture_hw = { | |||
325 | .rate_max = 192000, | 325 | .rate_max = 192000, |
326 | .channels_min = 2, | 326 | .channels_min = 2, |
327 | .channels_max = 2, | 327 | .channels_max = 2, |
328 | .buffer_bytes_max = ((65536 - 64) * 8), | 328 | .buffer_bytes_max = 65536 - 128, |
329 | .period_bytes_min = 64, | 329 | .period_bytes_min = 64, |
330 | .period_bytes_max = (65536 - 64), | 330 | .period_bytes_max = 32768 - 64, |
331 | .periods_min = 2, | 331 | .periods_min = 2, |
332 | .periods_max = 2, | 332 | .periods_max = 2, |
333 | .fifo_size = 0, | 333 | .fifo_size = 0, |
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index 082e35c08c02..deb6cfa73600 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c | |||
@@ -57,9 +57,9 @@ struct daio_rsc_idx idx_20k1[NUM_DAIOTYP] = { | |||
57 | 57 | ||
58 | struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = { | 58 | struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = { |
59 | [LINEO1] = {.left = 0x40, .right = 0x41}, | 59 | [LINEO1] = {.left = 0x40, .right = 0x41}, |
60 | [LINEO2] = {.left = 0x70, .right = 0x71}, | 60 | [LINEO2] = {.left = 0x60, .right = 0x61}, |
61 | [LINEO3] = {.left = 0x50, .right = 0x51}, | 61 | [LINEO3] = {.left = 0x50, .right = 0x51}, |
62 | [LINEO4] = {.left = 0x60, .right = 0x61}, | 62 | [LINEO4] = {.left = 0x70, .right = 0x71}, |
63 | [LINEIM] = {.left = 0x45, .right = 0xc5}, | 63 | [LINEIM] = {.left = 0x45, .right = 0xc5}, |
64 | [SPDIFOO] = {.left = 0x00, .right = 0x01}, | 64 | [SPDIFOO] = {.left = 0x00, .right = 0x01}, |
65 | [SPDIFIO] = {.left = 0x05, .right = 0x85}, | 65 | [SPDIFIO] = {.left = 0x05, .right = 0x85}, |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 29272f2e95a0..b0275a050870 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -50,19 +50,22 @@ static void snd_hda_generate_beep(struct work_struct *work) | |||
50 | * The tone frequency of beep generator on IDT/STAC codecs is | 50 | * The tone frequency of beep generator on IDT/STAC codecs is |
51 | * defined from the 8bit tone parameter, in Hz, | 51 | * defined from the 8bit tone parameter, in Hz, |
52 | * freq = 48000 * (257 - tone) / 1024 | 52 | * freq = 48000 * (257 - tone) / 1024 |
53 | * that is from 12kHz to 93.75kHz in step of 46.875 hz | 53 | * that is from 12kHz to 93.75Hz in steps of 46.875 Hz |
54 | */ | 54 | */ |
55 | static int beep_linear_tone(struct hda_beep *beep, int hz) | 55 | static int beep_linear_tone(struct hda_beep *beep, int hz) |
56 | { | 56 | { |
57 | if (hz <= 0) | ||
58 | return 0; | ||
57 | hz *= 1000; /* fixed point */ | 59 | hz *= 1000; /* fixed point */ |
58 | hz = hz - DIGBEEP_HZ_MIN; | 60 | hz = hz - DIGBEEP_HZ_MIN |
61 | + DIGBEEP_HZ_STEP / 2; /* round to nearest step */ | ||
59 | if (hz < 0) | 62 | if (hz < 0) |
60 | hz = 0; /* turn off PC beep*/ | 63 | hz = 0; /* turn off PC beep*/ |
61 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) | 64 | else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) |
62 | hz = 0xff; | 65 | hz = 1; /* max frequency */ |
63 | else { | 66 | else { |
64 | hz /= DIGBEEP_HZ_STEP; | 67 | hz /= DIGBEEP_HZ_STEP; |
65 | hz++; | 68 | hz = 255 - hz; |
66 | } | 69 | } |
67 | return hz; | 70 | return hz; |
68 | } | 71 | } |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 26d255de6beb..88480c0c58a0 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -332,6 +332,12 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
332 | AC_VERB_GET_CONNECT_LIST, i); | 332 | AC_VERB_GET_CONNECT_LIST, i); |
333 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ | 333 | range_val = !!(parm & (1 << (shift-1))); /* ranges */ |
334 | val = parm & mask; | 334 | val = parm & mask; |
335 | if (val == 0) { | ||
336 | snd_printk(KERN_WARNING "hda_codec: " | ||
337 | "invalid CONNECT_LIST verb %x[%i]:%x\n", | ||
338 | nid, i, parm); | ||
339 | return 0; | ||
340 | } | ||
335 | parm >>= shift; | 341 | parm >>= shift; |
336 | if (range_val) { | 342 | if (range_val) { |
337 | /* ranges between the previous and this one */ | 343 | /* ranges between the previous and this one */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1877d95d4aa6..77c1b840ca8b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1455,6 +1455,17 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1455 | return err; | 1455 | return err; |
1456 | } | 1456 | } |
1457 | snd_pcm_limit_hw_rates(runtime); | 1457 | snd_pcm_limit_hw_rates(runtime); |
1458 | /* sanity check */ | ||
1459 | if (snd_BUG_ON(!runtime->hw.channels_min) || | ||
1460 | snd_BUG_ON(!runtime->hw.channels_max) || | ||
1461 | snd_BUG_ON(!runtime->hw.formats) || | ||
1462 | snd_BUG_ON(!runtime->hw.rates)) { | ||
1463 | azx_release_device(azx_dev); | ||
1464 | hinfo->ops.close(hinfo, apcm->codec, substream); | ||
1465 | snd_hda_power_down(apcm->codec); | ||
1466 | mutex_unlock(&chip->open_mutex); | ||
1467 | return -EINVAL; | ||
1468 | } | ||
1458 | spin_lock_irqsave(&chip->reg_lock, flags); | 1469 | spin_lock_irqsave(&chip->reg_lock, flags); |
1459 | azx_dev->substream = substream; | 1470 | azx_dev->substream = substream; |
1460 | azx_dev->running = 0; | 1471 | azx_dev->running = 0; |
@@ -1463,13 +1474,6 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1463 | runtime->private_data = azx_dev; | 1474 | runtime->private_data = azx_dev; |
1464 | snd_pcm_set_sync(substream); | 1475 | snd_pcm_set_sync(substream); |
1465 | mutex_unlock(&chip->open_mutex); | 1476 | mutex_unlock(&chip->open_mutex); |
1466 | |||
1467 | if (snd_BUG_ON(!runtime->hw.channels_min || !runtime->hw.channels_max)) | ||
1468 | return -EINVAL; | ||
1469 | if (snd_BUG_ON(!runtime->hw.formats)) | ||
1470 | return -EINVAL; | ||
1471 | if (snd_BUG_ON(!runtime->hw.rates)) | ||
1472 | return -EINVAL; | ||
1473 | return 0; | 1477 | return 0; |
1474 | } | 1478 | } |
1475 | 1479 | ||
@@ -2329,9 +2333,19 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2329 | gcap = azx_readw(chip, GCAP); | 2333 | gcap = azx_readw(chip, GCAP); |
2330 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); | 2334 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); |
2331 | 2335 | ||
2332 | /* ATI chips seems buggy about 64bit DMA addresses */ | 2336 | /* disable SB600 64bit support for safety */ |
2333 | if (chip->driver_type == AZX_DRIVER_ATI) | 2337 | if ((chip->driver_type == AZX_DRIVER_ATI) || |
2334 | gcap &= ~ICH6_GCAP_64OK; | 2338 | (chip->driver_type == AZX_DRIVER_ATIHDMI)) { |
2339 | struct pci_dev *p_smbus; | ||
2340 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, | ||
2341 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, | ||
2342 | NULL); | ||
2343 | if (p_smbus) { | ||
2344 | if (p_smbus->revision < 0x30) | ||
2345 | gcap &= ~ICH6_GCAP_64OK; | ||
2346 | pci_dev_put(p_smbus); | ||
2347 | } | ||
2348 | } | ||
2335 | 2349 | ||
2336 | /* allow 64bit DMA address if supported by H/W */ | 2350 | /* allow 64bit DMA address if supported by H/W */ |
2337 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2351 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e661b21354be..7e99763ca527 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4505,6 +4505,12 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4505 | &dig_nid, 1); | 4505 | &dig_nid, 1); |
4506 | if (err < 0) | 4506 | if (err < 0) |
4507 | continue; | 4507 | continue; |
4508 | if (dig_nid > 0x7f) { | ||
4509 | printk(KERN_ERR "alc880_auto: invalid dig_nid " | ||
4510 | "connection 0x%x for NID 0x%x\n", dig_nid, | ||
4511 | spec->autocfg.dig_out_pins[i]); | ||
4512 | continue; | ||
4513 | } | ||
4508 | if (!i) | 4514 | if (!i) |
4509 | spec->multiout.dig_out_nid = dig_nid; | 4515 | spec->multiout.dig_out_nid = dig_nid; |
4510 | else { | 4516 | else { |
@@ -6919,9 +6925,6 @@ static struct hda_verb alc882_targa_verbs[] = { | |||
6919 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 6925 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
6920 | 6926 | ||
6921 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 6927 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
6922 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | ||
6923 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | ||
6924 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | ||
6925 | { } /* end */ | 6928 | { } /* end */ |
6926 | }; | 6929 | }; |
6927 | 6930 | ||
@@ -7241,7 +7244,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
7241 | }, | 7244 | }, |
7242 | [ALC882_TARGA] = { | 7245 | [ALC882_TARGA] = { |
7243 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, | 7246 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, |
7244 | .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, | 7247 | .init_verbs = { alc882_init_verbs, alc880_gpio3_init_verbs, |
7248 | alc882_targa_verbs}, | ||
7245 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | 7249 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), |
7246 | .dac_nids = alc882_dac_nids, | 7250 | .dac_nids = alc882_dac_nids, |
7247 | .dig_out_nid = ALC882_DIGOUT_NID, | 7251 | .dig_out_nid = ALC882_DIGOUT_NID, |
@@ -9238,7 +9242,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9238 | }, | 9242 | }, |
9239 | [ALC883_TARGA_DIG] = { | 9243 | [ALC883_TARGA_DIG] = { |
9240 | .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, | 9244 | .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, |
9241 | .init_verbs = { alc883_init_verbs, alc883_targa_verbs}, | 9245 | .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, |
9246 | alc883_targa_verbs}, | ||
9242 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | 9247 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), |
9243 | .dac_nids = alc883_dac_nids, | 9248 | .dac_nids = alc883_dac_nids, |
9244 | .dig_out_nid = ALC883_DIGOUT_NID, | 9249 | .dig_out_nid = ALC883_DIGOUT_NID, |
@@ -9251,7 +9256,8 @@ static struct alc_config_preset alc883_presets[] = { | |||
9251 | }, | 9256 | }, |
9252 | [ALC883_TARGA_2ch_DIG] = { | 9257 | [ALC883_TARGA_2ch_DIG] = { |
9253 | .mixers = { alc883_targa_2ch_mixer}, | 9258 | .mixers = { alc883_targa_2ch_mixer}, |
9254 | .init_verbs = { alc883_init_verbs, alc883_targa_verbs}, | 9259 | .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, |
9260 | alc883_targa_verbs}, | ||
9255 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | 9261 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), |
9256 | .dac_nids = alc883_dac_nids, | 9262 | .dac_nids = alc883_dac_nids, |
9257 | .adc_nids = alc883_adc_nids_alt, | 9263 | .adc_nids = alc883_adc_nids_alt, |
@@ -12878,9 +12884,9 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { | |||
12878 | 12884 | ||
12879 | static struct snd_kcontrol_new alc269_eeepc_mixer[] = { | 12885 | static struct snd_kcontrol_new alc269_eeepc_mixer[] = { |
12880 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 12886 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
12881 | HDA_CODEC_MUTE("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 12887 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
12882 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 12888 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
12883 | HDA_CODEC_MUTE("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 12889 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
12884 | { } /* end */ | 12890 | { } /* end */ |
12885 | }; | 12891 | }; |
12886 | 12892 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 14f3c3e0f62d..da7f9f65c047 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1590,8 +1590,6 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1590 | /* SigmaTel reference board */ | 1590 | /* SigmaTel reference board */ |
1591 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1591 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1592 | "DFI LanParty", STAC_REF), | 1592 | "DFI LanParty", STAC_REF), |
1593 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30, | ||
1594 | "SigmaTel",STAC_9205_REF), | ||
1595 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | 1593 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1596 | "DFI LanParty", STAC_REF), | 1594 | "DFI LanParty", STAC_REF), |
1597 | /* Dell laptops have BIOS problem */ | 1595 | /* Dell laptops have BIOS problem */ |
@@ -2344,6 +2342,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2344 | /* SigmaTel reference board */ | 2342 | /* SigmaTel reference board */ |
2345 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2343 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2346 | "DFI LanParty", STAC_9205_REF), | 2344 | "DFI LanParty", STAC_9205_REF), |
2345 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xfb30, | ||
2346 | "SigmaTel", STAC_9205_REF), | ||
2347 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | 2347 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
2348 | "DFI LanParty", STAC_9205_REF), | 2348 | "DFI LanParty", STAC_9205_REF), |
2349 | /* Dell */ | 2349 | /* Dell */ |
@@ -2378,6 +2378,7 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2378 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, | 2378 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, |
2379 | "Dell Vostro 1500", STAC_9205_DELL_M42), | 2379 | "Dell Vostro 1500", STAC_9205_DELL_M42), |
2380 | /* Gateway */ | 2380 | /* Gateway */ |
2381 | SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD), | ||
2381 | SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), | 2382 | SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), |
2382 | {} /* terminator */ | 2383 | {} /* terminator */ |
2383 | }; | 2384 | }; |
@@ -5854,6 +5855,8 @@ static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { | |||
5854 | }; | 5855 | }; |
5855 | 5856 | ||
5856 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { | 5857 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { |
5858 | SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, | ||
5859 | "Sony VAIO F/S", STAC_9872_VAIO), | ||
5857 | {} /* terminator */ | 5860 | {} /* terminator */ |
5858 | }; | 5861 | }; |
5859 | 5862 | ||
@@ -5866,6 +5869,8 @@ static int patch_stac9872(struct hda_codec *codec) | |||
5866 | if (spec == NULL) | 5869 | if (spec == NULL) |
5867 | return -ENOMEM; | 5870 | return -ENOMEM; |
5868 | codec->spec = spec; | 5871 | codec->spec = spec; |
5872 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | ||
5873 | spec->pin_nids = stac9872_pin_nids; | ||
5869 | 5874 | ||
5870 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | 5875 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, |
5871 | stac9872_models, | 5876 | stac9872_models, |
@@ -5877,8 +5882,6 @@ static int patch_stac9872(struct hda_codec *codec) | |||
5877 | stac92xx_set_config_regs(codec, | 5882 | stac92xx_set_config_regs(codec, |
5878 | stac9872_brd_tbl[spec->board_config]); | 5883 | stac9872_brd_tbl[spec->board_config]); |
5879 | 5884 | ||
5880 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | ||
5881 | spec->pin_nids = stac9872_pin_nids; | ||
5882 | spec->multiout.dac_nids = spec->dac_nids; | 5885 | spec->multiout.dac_nids = spec->dac_nids; |
5883 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); | 5886 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); |
5884 | spec->adc_nids = stac9872_adc_nids; | 5887 | spec->adc_nids = stac9872_adc_nids; |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 8e004fb6961a..9008b4b013aa 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -210,7 +210,9 @@ struct via_spec { | |||
210 | /* capture */ | 210 | /* capture */ |
211 | unsigned int num_adc_nids; | 211 | unsigned int num_adc_nids; |
212 | hda_nid_t *adc_nids; | 212 | hda_nid_t *adc_nids; |
213 | hda_nid_t mux_nids[3]; | ||
213 | hda_nid_t dig_in_nid; | 214 | hda_nid_t dig_in_nid; |
215 | hda_nid_t dig_in_pin; | ||
214 | 216 | ||
215 | /* capture source */ | 217 | /* capture source */ |
216 | const struct hda_input_mux *input_mux; | 218 | const struct hda_input_mux *input_mux; |
@@ -319,6 +321,9 @@ static void via_auto_set_output_and_unmute(struct hda_codec *codec, | |||
319 | pin_type); | 321 | pin_type); |
320 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 322 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
321 | AMP_OUT_UNMUTE); | 323 | AMP_OUT_UNMUTE); |
324 | if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) | ||
325 | snd_hda_codec_write(codec, nid, 0, | ||
326 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
322 | } | 327 | } |
323 | 328 | ||
324 | 329 | ||
@@ -387,27 +392,12 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
387 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 392 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
388 | struct via_spec *spec = codec->spec; | 393 | struct via_spec *spec = codec->spec; |
389 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 394 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
390 | unsigned int vendor_id = codec->vendor_id; | 395 | |
391 | 396 | if (!spec->mux_nids[adc_idx]) | |
392 | /* AIW0 lydia 060801 add for correct sw0 input select */ | 397 | return -EINVAL; |
393 | if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0)) | 398 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, |
394 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | 399 | spec->mux_nids[adc_idx], |
395 | 0x18, &spec->cur_mux[adc_idx]); | 400 | &spec->cur_mux[adc_idx]); |
396 | else if ((IS_VT1709_10CH_VENDORID(vendor_id) || | ||
397 | IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0)) | ||
398 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
399 | 0x19, &spec->cur_mux[adc_idx]); | ||
400 | else if ((IS_VT1708B_8CH_VENDORID(vendor_id) || | ||
401 | IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0)) | ||
402 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
403 | 0x17, &spec->cur_mux[adc_idx]); | ||
404 | else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0)) | ||
405 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
406 | 0x13, &spec->cur_mux[adc_idx]); | ||
407 | else | ||
408 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, | ||
409 | spec->adc_nids[adc_idx], | ||
410 | &spec->cur_mux[adc_idx]); | ||
411 | } | 401 | } |
412 | 402 | ||
413 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, | 403 | static int via_independent_hp_info(struct snd_kcontrol *kcontrol, |
@@ -998,25 +988,11 @@ static int via_init(struct hda_codec *codec) | |||
998 | 988 | ||
999 | /* Lydia Add for EAPD enable */ | 989 | /* Lydia Add for EAPD enable */ |
1000 | if (!spec->dig_in_nid) { /* No Digital In connection */ | 990 | if (!spec->dig_in_nid) { /* No Digital In connection */ |
1001 | if (IS_VT1708_VENDORID(codec->vendor_id)) { | 991 | if (spec->dig_in_pin) { |
1002 | snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, | 992 | snd_hda_codec_write(codec, spec->dig_in_pin, 0, |
1003 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1004 | PIN_OUT); | ||
1005 | snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0, | ||
1006 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
1007 | } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) || | ||
1008 | IS_VT1709_6CH_VENDORID(codec->vendor_id)) { | ||
1009 | snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, | ||
1010 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 993 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
1011 | PIN_OUT); | 994 | PIN_OUT); |
1012 | snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0, | 995 | snd_hda_codec_write(codec, spec->dig_in_pin, 0, |
1013 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | ||
1014 | } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) || | ||
1015 | IS_VT1708B_4CH_VENDORID(codec->vendor_id)) { | ||
1016 | snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, | ||
1017 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1018 | PIN_OUT); | ||
1019 | snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0, | ||
1020 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | 996 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); |
1021 | } | 997 | } |
1022 | } else /* enable SPDIF-input pin */ | 998 | } else /* enable SPDIF-input pin */ |
@@ -1326,6 +1302,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) | |||
1326 | 1302 | ||
1327 | if (spec->autocfg.dig_outs) | 1303 | if (spec->autocfg.dig_outs) |
1328 | spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; | 1304 | spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; |
1305 | spec->dig_in_pin = VT1708_DIGIN_PIN; | ||
1329 | if (spec->autocfg.dig_in_pin) | 1306 | if (spec->autocfg.dig_in_pin) |
1330 | spec->dig_in_nid = VT1708_DIGIN_NID; | 1307 | spec->dig_in_nid = VT1708_DIGIN_NID; |
1331 | 1308 | ||
@@ -1352,6 +1329,34 @@ static int via_auto_init(struct hda_codec *codec) | |||
1352 | return 0; | 1329 | return 0; |
1353 | } | 1330 | } |
1354 | 1331 | ||
1332 | static int get_mux_nids(struct hda_codec *codec) | ||
1333 | { | ||
1334 | struct via_spec *spec = codec->spec; | ||
1335 | hda_nid_t nid, conn[8]; | ||
1336 | unsigned int type; | ||
1337 | int i, n; | ||
1338 | |||
1339 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
1340 | nid = spec->adc_nids[i]; | ||
1341 | while (nid) { | ||
1342 | type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) | ||
1343 | >> AC_WCAP_TYPE_SHIFT; | ||
1344 | if (type == AC_WID_PIN) | ||
1345 | break; | ||
1346 | n = snd_hda_get_connections(codec, nid, conn, | ||
1347 | ARRAY_SIZE(conn)); | ||
1348 | if (n <= 0) | ||
1349 | break; | ||
1350 | if (n > 1) { | ||
1351 | spec->mux_nids[i] = nid; | ||
1352 | break; | ||
1353 | } | ||
1354 | nid = conn[0]; | ||
1355 | } | ||
1356 | } | ||
1357 | return 0; | ||
1358 | } | ||
1359 | |||
1355 | static int patch_vt1708(struct hda_codec *codec) | 1360 | static int patch_vt1708(struct hda_codec *codec) |
1356 | { | 1361 | { |
1357 | struct via_spec *spec; | 1362 | struct via_spec *spec; |
@@ -1799,6 +1804,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
1799 | 1804 | ||
1800 | if (spec->autocfg.dig_outs) | 1805 | if (spec->autocfg.dig_outs) |
1801 | spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; | 1806 | spec->multiout.dig_out_nid = VT1709_DIGOUT_NID; |
1807 | spec->dig_in_pin = VT1709_DIGIN_PIN; | ||
1802 | if (spec->autocfg.dig_in_pin) | 1808 | if (spec->autocfg.dig_in_pin) |
1803 | spec->dig_in_nid = VT1709_DIGIN_NID; | 1809 | spec->dig_in_nid = VT1709_DIGIN_NID; |
1804 | 1810 | ||
@@ -1859,6 +1865,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec) | |||
1859 | if (!spec->adc_nids && spec->input_mux) { | 1865 | if (!spec->adc_nids && spec->input_mux) { |
1860 | spec->adc_nids = vt1709_adc_nids; | 1866 | spec->adc_nids = vt1709_adc_nids; |
1861 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); | 1867 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); |
1868 | get_mux_nids(codec); | ||
1862 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; | 1869 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; |
1863 | spec->num_mixers++; | 1870 | spec->num_mixers++; |
1864 | } | 1871 | } |
@@ -1952,6 +1959,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec) | |||
1952 | if (!spec->adc_nids && spec->input_mux) { | 1959 | if (!spec->adc_nids && spec->input_mux) { |
1953 | spec->adc_nids = vt1709_adc_nids; | 1960 | spec->adc_nids = vt1709_adc_nids; |
1954 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); | 1961 | spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids); |
1962 | get_mux_nids(codec); | ||
1955 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; | 1963 | spec->mixers[spec->num_mixers] = vt1709_capture_mixer; |
1956 | spec->num_mixers++; | 1964 | spec->num_mixers++; |
1957 | } | 1965 | } |
@@ -2344,6 +2352,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
2344 | 2352 | ||
2345 | if (spec->autocfg.dig_outs) | 2353 | if (spec->autocfg.dig_outs) |
2346 | spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID; | 2354 | spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID; |
2355 | spec->dig_in_pin = VT1708B_DIGIN_PIN; | ||
2347 | if (spec->autocfg.dig_in_pin) | 2356 | if (spec->autocfg.dig_in_pin) |
2348 | spec->dig_in_nid = VT1708B_DIGIN_NID; | 2357 | spec->dig_in_nid = VT1708B_DIGIN_NID; |
2349 | 2358 | ||
@@ -2404,6 +2413,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) | |||
2404 | if (!spec->adc_nids && spec->input_mux) { | 2413 | if (!spec->adc_nids && spec->input_mux) { |
2405 | spec->adc_nids = vt1708B_adc_nids; | 2414 | spec->adc_nids = vt1708B_adc_nids; |
2406 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); | 2415 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); |
2416 | get_mux_nids(codec); | ||
2407 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; | 2417 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; |
2408 | spec->num_mixers++; | 2418 | spec->num_mixers++; |
2409 | } | 2419 | } |
@@ -2455,6 +2465,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) | |||
2455 | if (!spec->adc_nids && spec->input_mux) { | 2465 | if (!spec->adc_nids && spec->input_mux) { |
2456 | spec->adc_nids = vt1708B_adc_nids; | 2466 | spec->adc_nids = vt1708B_adc_nids; |
2457 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); | 2467 | spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids); |
2468 | get_mux_nids(codec); | ||
2458 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; | 2469 | spec->mixers[spec->num_mixers] = vt1708B_capture_mixer; |
2459 | spec->num_mixers++; | 2470 | spec->num_mixers++; |
2460 | } | 2471 | } |
@@ -2889,6 +2900,7 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
2889 | if (!spec->adc_nids && spec->input_mux) { | 2900 | if (!spec->adc_nids && spec->input_mux) { |
2890 | spec->adc_nids = vt1708S_adc_nids; | 2901 | spec->adc_nids = vt1708S_adc_nids; |
2891 | spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); | 2902 | spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); |
2903 | get_mux_nids(codec); | ||
2892 | spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; | 2904 | spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; |
2893 | spec->num_mixers++; | 2905 | spec->num_mixers++; |
2894 | } | 2906 | } |
@@ -3206,6 +3218,7 @@ static int patch_vt1702(struct hda_codec *codec) | |||
3206 | if (!spec->adc_nids && spec->input_mux) { | 3218 | if (!spec->adc_nids && spec->input_mux) { |
3207 | spec->adc_nids = vt1702_adc_nids; | 3219 | spec->adc_nids = vt1702_adc_nids; |
3208 | spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); | 3220 | spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); |
3221 | get_mux_nids(codec); | ||
3209 | spec->mixers[spec->num_mixers] = vt1702_capture_mixer; | 3222 | spec->mixers[spec->num_mixers] = vt1702_capture_mixer; |
3210 | spec->num_mixers++; | 3223 | spec->num_mixers++; |
3211 | } | 3224 | } |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 235a71e5ac8d..b5ca02e2038c 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
@@ -2197,9 +2197,12 @@ static int __init alsa_card_riptide_init(void) | |||
2197 | if (err < 0) | 2197 | if (err < 0) |
2198 | return err; | 2198 | return err; |
2199 | #if defined(SUPPORT_JOYSTICK) | 2199 | #if defined(SUPPORT_JOYSTICK) |
2200 | pci_register_driver(&joystick_driver); | 2200 | err = pci_register_driver(&joystick_driver); |
2201 | /* On failure unregister formerly registered audio driver */ | ||
2202 | if (err < 0) | ||
2203 | pci_unregister_driver(&driver); | ||
2201 | #endif | 2204 | #endif |
2202 | return 0; | 2205 | return err; |
2203 | } | 2206 | } |
2204 | 2207 | ||
2205 | static void __exit alsa_card_riptide_exit(void) | 2208 | static void __exit alsa_card_riptide_exit(void) |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index d28eeaceb857..49c4b2898aff 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -79,7 +79,7 @@ static const u16 wm8753_reg[] = { | |||
79 | 0x0097, 0x0097, 0x0000, 0x0004, | 79 | 0x0097, 0x0097, 0x0000, 0x0004, |
80 | 0x0000, 0x0083, 0x0024, 0x01ba, | 80 | 0x0000, 0x0083, 0x0024, 0x01ba, |
81 | 0x0000, 0x0083, 0x0024, 0x01ba, | 81 | 0x0000, 0x0083, 0x0024, 0x01ba, |
82 | 0x0000, 0x0000 | 82 | 0x0000, 0x0000, 0x0000 |
83 | }; | 83 | }; |
84 | 84 | ||
85 | /* codec private data */ | 85 | /* codec private data */ |
@@ -1660,11 +1660,11 @@ static int wm8753_register(struct wm8753_priv *wm8753) | |||
1660 | codec->set_bias_level = wm8753_set_bias_level; | 1660 | codec->set_bias_level = wm8753_set_bias_level; |
1661 | codec->dai = wm8753_dai; | 1661 | codec->dai = wm8753_dai; |
1662 | codec->num_dai = 2; | 1662 | codec->num_dai = 2; |
1663 | codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache); | 1663 | codec->reg_cache_size = ARRAY_SIZE(wm8753->reg_cache) + 1; |
1664 | codec->reg_cache = &wm8753->reg_cache; | 1664 | codec->reg_cache = &wm8753->reg_cache; |
1665 | codec->private_data = wm8753; | 1665 | codec->private_data = wm8753; |
1666 | 1666 | ||
1667 | memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache)); | 1667 | memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache)); |
1668 | INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); | 1668 | INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); |
1669 | 1669 | ||
1670 | ret = wm8753_reset(codec); | 1670 | ret = wm8753_reset(codec); |
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index c05f71803aa8..8c0fdf84aac3 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -1037,14 +1037,14 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) | |||
1037 | codec->control_data = spi; | 1037 | codec->control_data = spi; |
1038 | codec->dev = &spi->dev; | 1038 | codec->dev = &spi->dev; |
1039 | 1039 | ||
1040 | spi->dev.driver_data = wm8988; | 1040 | dev_set_drvdata(&spi->dev, wm8988); |
1041 | 1041 | ||
1042 | return wm8988_register(wm8988); | 1042 | return wm8988_register(wm8988); |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | static int __devexit wm8988_spi_remove(struct spi_device *spi) | 1045 | static int __devexit wm8988_spi_remove(struct spi_device *spi) |
1046 | { | 1046 | { |
1047 | struct wm8988_priv *wm8988 = spi->dev.driver_data; | 1047 | struct wm8988_priv *wm8988 = dev_get_drvdata(&spi->dev); |
1048 | 1048 | ||
1049 | wm8988_unregister(wm8988); | 1049 | wm8988_unregister(wm8988); |
1050 | 1050 | ||
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index efec33a1c5bd..f0a2d4071998 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c | |||
@@ -456,6 +456,7 @@ int mpc5200_audio_dma_create(struct of_device *op) | |||
456 | return -ENODEV; | 456 | return -ENODEV; |
457 | 457 | ||
458 | spin_lock_init(&psc_dma->lock); | 458 | spin_lock_init(&psc_dma->lock); |
459 | mutex_init(&psc_dma->mutex); | ||
459 | psc_dma->id = be32_to_cpu(*prop); | 460 | psc_dma->id = be32_to_cpu(*prop); |
460 | psc_dma->irq = irq; | 461 | psc_dma->irq = irq; |
461 | psc_dma->psc_regs = regs; | 462 | psc_dma->psc_regs = regs; |
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 2000803f06a7..8d396bb9d9fe 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h | |||
@@ -55,6 +55,7 @@ struct psc_dma { | |||
55 | unsigned int irq; | 55 | unsigned int irq; |
56 | struct device *dev; | 56 | struct device *dev; |
57 | spinlock_t lock; | 57 | spinlock_t lock; |
58 | struct mutex mutex; | ||
58 | u32 sicr; | 59 | u32 sicr; |
59 | uint sysclk; | 60 | uint sysclk; |
60 | int imr; | 61 | int imr; |
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index 794a247b3eb5..7eb549985d49 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c | |||
@@ -34,13 +34,20 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
34 | int status; | 34 | int status; |
35 | unsigned int val; | 35 | unsigned int val; |
36 | 36 | ||
37 | mutex_lock(&psc_dma->mutex); | ||
38 | |||
37 | /* Wait for command send status zero = ready */ | 39 | /* Wait for command send status zero = ready */ |
38 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & | 40 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & |
39 | MPC52xx_PSC_SR_CMDSEND), 100, 0); | 41 | MPC52xx_PSC_SR_CMDSEND), 100, 0); |
40 | if (status == 0) { | 42 | if (status == 0) { |
41 | pr_err("timeout on ac97 bus (rdy)\n"); | 43 | pr_err("timeout on ac97 bus (rdy)\n"); |
44 | mutex_unlock(&psc_dma->mutex); | ||
42 | return -ENODEV; | 45 | return -ENODEV; |
43 | } | 46 | } |
47 | |||
48 | /* Force clear the data valid bit */ | ||
49 | in_be32(&psc_dma->psc_regs->ac97_data); | ||
50 | |||
44 | /* Send the read */ | 51 | /* Send the read */ |
45 | out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24)); | 52 | out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24)); |
46 | 53 | ||
@@ -50,16 +57,19 @@ static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
50 | if (status == 0) { | 57 | if (status == 0) { |
51 | pr_err("timeout on ac97 read (val) %x\n", | 58 | pr_err("timeout on ac97 read (val) %x\n", |
52 | in_be16(&psc_dma->psc_regs->sr_csr.status)); | 59 | in_be16(&psc_dma->psc_regs->sr_csr.status)); |
60 | mutex_unlock(&psc_dma->mutex); | ||
53 | return -ENODEV; | 61 | return -ENODEV; |
54 | } | 62 | } |
55 | /* Get the data */ | 63 | /* Get the data */ |
56 | val = in_be32(&psc_dma->psc_regs->ac97_data); | 64 | val = in_be32(&psc_dma->psc_regs->ac97_data); |
57 | if (((val >> 24) & 0x7f) != reg) { | 65 | if (((val >> 24) & 0x7f) != reg) { |
58 | pr_err("reg echo error on ac97 read\n"); | 66 | pr_err("reg echo error on ac97 read\n"); |
67 | mutex_unlock(&psc_dma->mutex); | ||
59 | return -ENODEV; | 68 | return -ENODEV; |
60 | } | 69 | } |
61 | val = (val >> 8) & 0xffff; | 70 | val = (val >> 8) & 0xffff; |
62 | 71 | ||
72 | mutex_unlock(&psc_dma->mutex); | ||
63 | return (unsigned short) val; | 73 | return (unsigned short) val; |
64 | } | 74 | } |
65 | 75 | ||
@@ -68,16 +78,21 @@ static void psc_ac97_write(struct snd_ac97 *ac97, | |||
68 | { | 78 | { |
69 | int status; | 79 | int status; |
70 | 80 | ||
81 | mutex_lock(&psc_dma->mutex); | ||
82 | |||
71 | /* Wait for command status zero = ready */ | 83 | /* Wait for command status zero = ready */ |
72 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & | 84 | status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & |
73 | MPC52xx_PSC_SR_CMDSEND), 100, 0); | 85 | MPC52xx_PSC_SR_CMDSEND), 100, 0); |
74 | if (status == 0) { | 86 | if (status == 0) { |
75 | pr_err("timeout on ac97 bus (write)\n"); | 87 | pr_err("timeout on ac97 bus (write)\n"); |
76 | return; | 88 | goto out; |
77 | } | 89 | } |
78 | /* Write data */ | 90 | /* Write data */ |
79 | out_be32(&psc_dma->psc_regs->ac97_cmd, | 91 | out_be32(&psc_dma->psc_regs->ac97_cmd, |
80 | ((reg & 0x7f) << 24) | (val << 8)); | 92 | ((reg & 0x7f) << 24) | (val << 8)); |
93 | |||
94 | out: | ||
95 | mutex_unlock(&psc_dma->mutex); | ||
81 | } | 96 | } |
82 | 97 | ||
83 | static void psc_ac97_warm_reset(struct snd_ac97 *ac97) | 98 | static void psc_ac97_warm_reset(struct snd_ac97 *ac97) |
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index c7b902358b7b..44b9cdc8a83b 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -2661,7 +2661,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2661 | struct usb_interface_descriptor *altsd; | 2661 | struct usb_interface_descriptor *altsd; |
2662 | int i, altno, err, stream; | 2662 | int i, altno, err, stream; |
2663 | int format; | 2663 | int format; |
2664 | struct audioformat *fp; | 2664 | struct audioformat *fp = NULL; |
2665 | unsigned char *fmt, *csep; | 2665 | unsigned char *fmt, *csep; |
2666 | int num; | 2666 | int num; |
2667 | 2667 | ||
@@ -2734,6 +2734,18 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | |||
2734 | continue; | 2734 | continue; |
2735 | } | 2735 | } |
2736 | 2736 | ||
2737 | /* | ||
2738 | * Blue Microphones workaround: The last altsetting is identical | ||
2739 | * with the previous one, except for a larger packet size, but | ||
2740 | * is actually a mislabeled two-channel setting; ignore it. | ||
2741 | */ | ||
2742 | if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 && | ||
2743 | fp && fp->altsetting == 1 && fp->channels == 1 && | ||
2744 | fp->format == SNDRV_PCM_FORMAT_S16_LE && | ||
2745 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
2746 | fp->maxpacksize * 2) | ||
2747 | continue; | ||
2748 | |||
2737 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | 2749 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); |
2738 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | 2750 | /* Creamware Noah has this descriptor after the 2nd endpoint */ |
2739 | if (!csep && altsd->bNumEndpoints >= 2) | 2751 | if (!csep && altsd->bNumEndpoints >= 2) |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 9c6d0ae3708e..7822b3d6baca 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -164,7 +164,7 @@ endif | |||
164 | 164 | ||
165 | # CFLAGS and LDFLAGS are for the users to override from the command line. | 165 | # CFLAGS and LDFLAGS are for the users to override from the command line. |
166 | 166 | ||
167 | CFLAGS = $(M64) -ggdb3 -Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -Werror -O6 | 167 | CFLAGS = $(M64) -ggdb3 -Wall -Wextra -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -Werror -O6 |
168 | LDFLAGS = -lpthread -lrt -lelf -lm | 168 | LDFLAGS = -lpthread -lrt -lelf -lm |
169 | ALL_CFLAGS = $(CFLAGS) | 169 | ALL_CFLAGS = $(CFLAGS) |
170 | ALL_LDFLAGS = $(LDFLAGS) | 170 | ALL_LDFLAGS = $(LDFLAGS) |
@@ -223,7 +223,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ | |||
223 | # Those must not be GNU-specific; they are shared with perl/ which may | 223 | # Those must not be GNU-specific; they are shared with perl/ which may |
224 | # be built by a different compiler. (Note that this is an artifact now | 224 | # be built by a different compiler. (Note that this is an artifact now |
225 | # but it still might be nice to keep that distinction.) | 225 | # but it still might be nice to keep that distinction.) |
226 | BASIC_CFLAGS = | 226 | BASIC_CFLAGS = -Iutil/include |
227 | BASIC_LDFLAGS = | 227 | BASIC_LDFLAGS = |
228 | 228 | ||
229 | # Guard against environment variables | 229 | # Guard against environment variables |
@@ -289,10 +289,11 @@ export PERL_PATH | |||
289 | LIB_FILE=libperf.a | 289 | LIB_FILE=libperf.a |
290 | 290 | ||
291 | LIB_H += ../../include/linux/perf_counter.h | 291 | LIB_H += ../../include/linux/perf_counter.h |
292 | LIB_H += ../../include/linux/rbtree.h | ||
293 | LIB_H += ../../include/linux/list.h | ||
294 | LIB_H += util/include/linux/list.h | ||
292 | LIB_H += perf.h | 295 | LIB_H += perf.h |
293 | LIB_H += util/types.h | 296 | LIB_H += util/types.h |
294 | LIB_H += util/list.h | ||
295 | LIB_H += util/rbtree.h | ||
296 | LIB_H += util/levenshtein.h | 297 | LIB_H += util/levenshtein.h |
297 | LIB_H += util/parse-options.h | 298 | LIB_H += util/parse-options.h |
298 | LIB_H += util/parse-events.h | 299 | LIB_H += util/parse-events.h |
@@ -305,6 +306,7 @@ LIB_H += util/strlist.h | |||
305 | LIB_H += util/run-command.h | 306 | LIB_H += util/run-command.h |
306 | LIB_H += util/sigchain.h | 307 | LIB_H += util/sigchain.h |
307 | LIB_H += util/symbol.h | 308 | LIB_H += util/symbol.h |
309 | LIB_H += util/module.h | ||
308 | LIB_H += util/color.h | 310 | LIB_H += util/color.h |
309 | 311 | ||
310 | LIB_OBJS += util/abspath.o | 312 | LIB_OBJS += util/abspath.o |
@@ -328,6 +330,7 @@ LIB_OBJS += util/usage.o | |||
328 | LIB_OBJS += util/wrapper.o | 330 | LIB_OBJS += util/wrapper.o |
329 | LIB_OBJS += util/sigchain.o | 331 | LIB_OBJS += util/sigchain.o |
330 | LIB_OBJS += util/symbol.o | 332 | LIB_OBJS += util/symbol.o |
333 | LIB_OBJS += util/module.o | ||
331 | LIB_OBJS += util/color.o | 334 | LIB_OBJS += util/color.o |
332 | LIB_OBJS += util/pager.o | 335 | LIB_OBJS += util/pager.o |
333 | LIB_OBJS += util/header.o | 336 | LIB_OBJS += util/header.o |
@@ -381,12 +384,6 @@ ifndef CC_LD_DYNPATH | |||
381 | endif | 384 | endif |
382 | endif | 385 | endif |
383 | 386 | ||
384 | ifdef ZLIB_PATH | ||
385 | BASIC_CFLAGS += -I$(ZLIB_PATH)/include | ||
386 | EXTLIBS += -L$(ZLIB_PATH)/$(lib) $(CC_LD_DYNPATH)$(ZLIB_PATH)/$(lib) | ||
387 | endif | ||
388 | EXTLIBS += -lz | ||
389 | |||
390 | ifdef NEEDS_SOCKET | 387 | ifdef NEEDS_SOCKET |
391 | EXTLIBS += -lsocket | 388 | EXTLIBS += -lsocket |
392 | endif | 389 | endif |
@@ -697,6 +694,9 @@ builtin-init-db.o: builtin-init-db.c PERF-CFLAGS | |||
697 | util/config.o: util/config.c PERF-CFLAGS | 694 | util/config.o: util/config.c PERF-CFLAGS |
698 | $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | 695 | $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< |
699 | 696 | ||
697 | util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS | ||
698 | $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< | ||
699 | |||
700 | perf-%$X: %.o $(PERFLIBS) | 700 | perf-%$X: %.o $(PERFLIBS) |
701 | $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) | 701 | $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) |
702 | 702 | ||
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 722c0f54e549..5f9eefecc574 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -10,9 +10,9 @@ | |||
10 | #include "util/util.h" | 10 | #include "util/util.h" |
11 | 11 | ||
12 | #include "util/color.h" | 12 | #include "util/color.h" |
13 | #include "util/list.h" | 13 | #include <linux/list.h> |
14 | #include "util/cache.h" | 14 | #include "util/cache.h" |
15 | #include "util/rbtree.h" | 15 | #include <linux/rbtree.h> |
16 | #include "util/symbol.h" | 16 | #include "util/symbol.h" |
17 | #include "util/string.h" | 17 | #include "util/string.h" |
18 | 18 | ||
@@ -25,10 +25,6 @@ | |||
25 | #define SHOW_USER 2 | 25 | #define SHOW_USER 2 |
26 | #define SHOW_HV 4 | 26 | #define SHOW_HV 4 |
27 | 27 | ||
28 | #define MIN_GREEN 0.5 | ||
29 | #define MIN_RED 5.0 | ||
30 | |||
31 | |||
32 | static char const *input_name = "perf.data"; | 28 | static char const *input_name = "perf.data"; |
33 | static char *vmlinux = "vmlinux"; | 29 | static char *vmlinux = "vmlinux"; |
34 | 30 | ||
@@ -43,6 +39,10 @@ static int dump_trace = 0; | |||
43 | 39 | ||
44 | static int verbose; | 40 | static int verbose; |
45 | 41 | ||
42 | static int modules; | ||
43 | |||
44 | static int full_paths; | ||
45 | |||
46 | static int print_line; | 46 | static int print_line; |
47 | 47 | ||
48 | static unsigned long page_size; | 48 | static unsigned long page_size; |
@@ -160,7 +160,7 @@ static void dsos__fprintf(FILE *fp) | |||
160 | 160 | ||
161 | static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) | 161 | static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) |
162 | { | 162 | { |
163 | return dso__find_symbol(kernel_dso, ip); | 163 | return dso__find_symbol(dso, ip); |
164 | } | 164 | } |
165 | 165 | ||
166 | static int load_kernel(void) | 166 | static int load_kernel(void) |
@@ -171,8 +171,8 @@ static int load_kernel(void) | |||
171 | if (!kernel_dso) | 171 | if (!kernel_dso) |
172 | return -1; | 172 | return -1; |
173 | 173 | ||
174 | err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); | 174 | err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules); |
175 | if (err) { | 175 | if (err <= 0) { |
176 | dso__delete(kernel_dso); | 176 | dso__delete(kernel_dso); |
177 | kernel_dso = NULL; | 177 | kernel_dso = NULL; |
178 | } else | 178 | } else |
@@ -203,7 +203,7 @@ static u64 map__map_ip(struct map *map, u64 ip) | |||
203 | return ip - map->start + map->pgoff; | 203 | return ip - map->start + map->pgoff; |
204 | } | 204 | } |
205 | 205 | ||
206 | static u64 vdso__map_ip(struct map *map, u64 ip) | 206 | static u64 vdso__map_ip(struct map *map __used, u64 ip) |
207 | { | 207 | { |
208 | return ip; | 208 | return ip; |
209 | } | 209 | } |
@@ -600,7 +600,7 @@ static LIST_HEAD(hist_entry__sort_list); | |||
600 | 600 | ||
601 | static int sort_dimension__add(char *tok) | 601 | static int sort_dimension__add(char *tok) |
602 | { | 602 | { |
603 | int i; | 603 | unsigned int i; |
604 | 604 | ||
605 | for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { | 605 | for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { |
606 | struct sort_dimension *sd = &sort_dimensions[i]; | 606 | struct sort_dimension *sd = &sort_dimensions[i]; |
@@ -1043,24 +1043,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head) | |||
1043 | return 0; | 1043 | return 0; |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | static char *get_color(double percent) | ||
1047 | { | ||
1048 | char *color = PERF_COLOR_NORMAL; | ||
1049 | |||
1050 | /* | ||
1051 | * We color high-overhead entries in red, mid-overhead | ||
1052 | * entries in green - and keep the low overhead places | ||
1053 | * normal: | ||
1054 | */ | ||
1055 | if (percent >= MIN_RED) | ||
1056 | color = PERF_COLOR_RED; | ||
1057 | else { | ||
1058 | if (percent > MIN_GREEN) | ||
1059 | color = PERF_COLOR_GREEN; | ||
1060 | } | ||
1061 | return color; | ||
1062 | } | ||
1063 | |||
1064 | static int | 1046 | static int |
1065 | parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) | 1047 | parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) |
1066 | { | 1048 | { |
@@ -1069,7 +1051,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) | |||
1069 | static const char *prev_color; | 1051 | static const char *prev_color; |
1070 | unsigned int offset; | 1052 | unsigned int offset; |
1071 | size_t line_len; | 1053 | size_t line_len; |
1072 | u64 line_ip; | 1054 | s64 line_ip; |
1073 | int ret; | 1055 | int ret; |
1074 | char *c; | 1056 | char *c; |
1075 | 1057 | ||
@@ -1122,7 +1104,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) | |||
1122 | } else if (sym->hist_sum) | 1104 | } else if (sym->hist_sum) |
1123 | percent = 100.0 * hits / sym->hist_sum; | 1105 | percent = 100.0 * hits / sym->hist_sum; |
1124 | 1106 | ||
1125 | color = get_color(percent); | 1107 | color = get_percent_color(percent); |
1126 | 1108 | ||
1127 | /* | 1109 | /* |
1128 | * Also color the filename and line if needed, with | 1110 | * Also color the filename and line if needed, with |
@@ -1258,7 +1240,7 @@ static void print_summary(char *filename) | |||
1258 | 1240 | ||
1259 | sym_ext = rb_entry(node, struct sym_ext, node); | 1241 | sym_ext = rb_entry(node, struct sym_ext, node); |
1260 | percent = sym_ext->percent; | 1242 | percent = sym_ext->percent; |
1261 | color = get_color(percent); | 1243 | color = get_percent_color(percent); |
1262 | path = sym_ext->path; | 1244 | path = sym_ext->path; |
1263 | 1245 | ||
1264 | color_fprintf(stdout, color, " %7.2f %s", percent, path); | 1246 | color_fprintf(stdout, color, " %7.2f %s", percent, path); |
@@ -1268,19 +1250,25 @@ static void print_summary(char *filename) | |||
1268 | 1250 | ||
1269 | static void annotate_sym(struct dso *dso, struct symbol *sym) | 1251 | static void annotate_sym(struct dso *dso, struct symbol *sym) |
1270 | { | 1252 | { |
1271 | char *filename = dso->name; | 1253 | char *filename = dso->name, *d_filename; |
1272 | u64 start, end, len; | 1254 | u64 start, end, len; |
1273 | char command[PATH_MAX*2]; | 1255 | char command[PATH_MAX*2]; |
1274 | FILE *file; | 1256 | FILE *file; |
1275 | 1257 | ||
1276 | if (!filename) | 1258 | if (!filename) |
1277 | return; | 1259 | return; |
1278 | if (dso == kernel_dso) | 1260 | if (sym->module) |
1261 | filename = sym->module->path; | ||
1262 | else if (dso == kernel_dso) | ||
1279 | filename = vmlinux; | 1263 | filename = vmlinux; |
1280 | 1264 | ||
1281 | start = sym->obj_start; | 1265 | start = sym->obj_start; |
1282 | if (!start) | 1266 | if (!start) |
1283 | start = sym->start; | 1267 | start = sym->start; |
1268 | if (full_paths) | ||
1269 | d_filename = filename; | ||
1270 | else | ||
1271 | d_filename = basename(filename); | ||
1284 | 1272 | ||
1285 | end = start + sym->end - sym->start + 1; | 1273 | end = start + sym->end - sym->start + 1; |
1286 | len = sym->end - sym->start; | 1274 | len = sym->end - sym->start; |
@@ -1291,13 +1279,14 @@ static void annotate_sym(struct dso *dso, struct symbol *sym) | |||
1291 | } | 1279 | } |
1292 | 1280 | ||
1293 | printf("\n\n------------------------------------------------\n"); | 1281 | printf("\n\n------------------------------------------------\n"); |
1294 | printf(" Percent | Source code & Disassembly of %s\n", filename); | 1282 | printf(" Percent | Source code & Disassembly of %s\n", d_filename); |
1295 | printf("------------------------------------------------\n"); | 1283 | printf("------------------------------------------------\n"); |
1296 | 1284 | ||
1297 | if (verbose >= 2) | 1285 | if (verbose >= 2) |
1298 | printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name); | 1286 | printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name); |
1299 | 1287 | ||
1300 | sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (u64)start, (u64)end, filename); | 1288 | sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s", |
1289 | (u64)start, (u64)end, filename, filename); | ||
1301 | 1290 | ||
1302 | if (verbose >= 3) | 1291 | if (verbose >= 3) |
1303 | printf("doing: %s\n", command); | 1292 | printf("doing: %s\n", command); |
@@ -1428,7 +1417,7 @@ more: | |||
1428 | 1417 | ||
1429 | head += size; | 1418 | head += size; |
1430 | 1419 | ||
1431 | if (offset + head < stat.st_size) | 1420 | if (offset + head < (unsigned long)stat.st_size) |
1432 | goto more; | 1421 | goto more; |
1433 | 1422 | ||
1434 | rc = EXIT_SUCCESS; | 1423 | rc = EXIT_SUCCESS; |
@@ -1472,8 +1461,12 @@ static const struct option options[] = { | |||
1472 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 1461 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, |
1473 | "dump raw trace in ASCII"), | 1462 | "dump raw trace in ASCII"), |
1474 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), | 1463 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), |
1464 | OPT_BOOLEAN('m', "modules", &modules, | ||
1465 | "load module symbols - WARNING: use only with -k and LIVE kernel"), | ||
1475 | OPT_BOOLEAN('l', "print-line", &print_line, | 1466 | OPT_BOOLEAN('l', "print-line", &print_line, |
1476 | "print matching source lines (may be slow)"), | 1467 | "print matching source lines (may be slow)"), |
1468 | OPT_BOOLEAN('P', "full-paths", &full_paths, | ||
1469 | "Don't shorten the displayed pathnames"), | ||
1477 | OPT_END() | 1470 | OPT_END() |
1478 | }; | 1471 | }; |
1479 | 1472 | ||
@@ -1492,7 +1485,7 @@ static void setup_sorting(void) | |||
1492 | free(str); | 1485 | free(str); |
1493 | } | 1486 | } |
1494 | 1487 | ||
1495 | int cmd_annotate(int argc, const char **argv, const char *prefix) | 1488 | int cmd_annotate(int argc, const char **argv, const char *prefix __used) |
1496 | { | 1489 | { |
1497 | symbol__init(); | 1490 | symbol__init(); |
1498 | 1491 | ||
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 0f32dc3f3c4c..2599d86a733b 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Builtin help command | 4 | * Builtin help command |
5 | */ | 5 | */ |
6 | #include "perf.h" | ||
6 | #include "util/cache.h" | 7 | #include "util/cache.h" |
7 | #include "builtin.h" | 8 | #include "builtin.h" |
8 | #include "util/exec_cmd.h" | 9 | #include "util/exec_cmd.h" |
@@ -277,7 +278,7 @@ static struct cmdnames main_cmds, other_cmds; | |||
277 | 278 | ||
278 | void list_common_cmds_help(void) | 279 | void list_common_cmds_help(void) |
279 | { | 280 | { |
280 | int i, longest = 0; | 281 | unsigned int i, longest = 0; |
281 | 282 | ||
282 | for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { | 283 | for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { |
283 | if (longest < strlen(common_cmds[i].name)) | 284 | if (longest < strlen(common_cmds[i].name)) |
@@ -415,9 +416,10 @@ static void show_html_page(const char *perf_cmd) | |||
415 | open_html(page_path.buf); | 416 | open_html(page_path.buf); |
416 | } | 417 | } |
417 | 418 | ||
418 | int cmd_help(int argc, const char **argv, const char *prefix) | 419 | int cmd_help(int argc, const char **argv, const char *prefix __used) |
419 | { | 420 | { |
420 | const char *alias; | 421 | const char *alias; |
422 | |||
421 | load_command_list("perf-", &main_cmds, &other_cmds); | 423 | load_command_list("perf-", &main_cmds, &other_cmds); |
422 | 424 | ||
423 | perf_config(perf_help_config, NULL); | 425 | perf_config(perf_help_config, NULL); |
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index fe60e37c96ef..f990fa8a35c9 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "util/parse-options.h" | 13 | #include "util/parse-options.h" |
14 | #include "util/parse-events.h" | 14 | #include "util/parse-events.h" |
15 | 15 | ||
16 | int cmd_list(int argc, const char **argv, const char *prefix) | 16 | int cmd_list(int argc __used, const char **argv __used, const char *prefix __used) |
17 | { | 17 | { |
18 | print_events(); | 18 | print_events(); |
19 | return 0; | 19 | return 0; |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d18546f37d7c..4ef78a5e6f32 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -294,7 +294,7 @@ static void pid_synthesize_mmap_samples(pid_t pid) | |||
294 | while (1) { | 294 | while (1) { |
295 | char bf[BUFSIZ], *pbf = bf; | 295 | char bf[BUFSIZ], *pbf = bf; |
296 | struct mmap_event mmap_ev = { | 296 | struct mmap_event mmap_ev = { |
297 | .header.type = PERF_EVENT_MMAP, | 297 | .header = { .type = PERF_EVENT_MMAP }, |
298 | }; | 298 | }; |
299 | int n; | 299 | int n; |
300 | size_t size; | 300 | size_t size; |
@@ -650,7 +650,7 @@ static const struct option options[] = { | |||
650 | OPT_END() | 650 | OPT_END() |
651 | }; | 651 | }; |
652 | 652 | ||
653 | int cmd_record(int argc, const char **argv, const char *prefix) | 653 | int cmd_record(int argc, const char **argv, const char *prefix __used) |
654 | { | 654 | { |
655 | int counter; | 655 | int counter; |
656 | 656 | ||
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 135b7837e6bf..4e5cc266311e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -10,9 +10,9 @@ | |||
10 | #include "util/util.h" | 10 | #include "util/util.h" |
11 | 11 | ||
12 | #include "util/color.h" | 12 | #include "util/color.h" |
13 | #include "util/list.h" | 13 | #include <linux/list.h> |
14 | #include "util/cache.h" | 14 | #include "util/cache.h" |
15 | #include "util/rbtree.h" | 15 | #include <linux/rbtree.h> |
16 | #include "util/symbol.h" | 16 | #include "util/symbol.h" |
17 | #include "util/string.h" | 17 | #include "util/string.h" |
18 | #include "util/callchain.h" | 18 | #include "util/callchain.h" |
@@ -46,6 +46,8 @@ static int dump_trace = 0; | |||
46 | static int verbose; | 46 | static int verbose; |
47 | #define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0) | 47 | #define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0) |
48 | 48 | ||
49 | static int modules; | ||
50 | |||
49 | static int full_paths; | 51 | static int full_paths; |
50 | 52 | ||
51 | static unsigned long page_size; | 53 | static unsigned long page_size; |
@@ -56,8 +58,17 @@ static char *parent_pattern = default_parent_pattern; | |||
56 | static regex_t parent_regex; | 58 | static regex_t parent_regex; |
57 | 59 | ||
58 | static int exclude_other = 1; | 60 | static int exclude_other = 1; |
61 | |||
62 | static char callchain_default_opt[] = "fractal,0.5"; | ||
63 | |||
59 | static int callchain; | 64 | static int callchain; |
60 | 65 | ||
66 | static | ||
67 | struct callchain_param callchain_param = { | ||
68 | .mode = CHAIN_GRAPH_ABS, | ||
69 | .min_percent = 0.5 | ||
70 | }; | ||
71 | |||
61 | static u64 sample_type; | 72 | static u64 sample_type; |
62 | 73 | ||
63 | struct ip_event { | 74 | struct ip_event { |
@@ -121,6 +132,7 @@ typedef union event_union { | |||
121 | static LIST_HEAD(dsos); | 132 | static LIST_HEAD(dsos); |
122 | static struct dso *kernel_dso; | 133 | static struct dso *kernel_dso; |
123 | static struct dso *vdso; | 134 | static struct dso *vdso; |
135 | static struct dso *hypervisor_dso; | ||
124 | 136 | ||
125 | static void dsos__add(struct dso *dso) | 137 | static void dsos__add(struct dso *dso) |
126 | { | 138 | { |
@@ -176,7 +188,7 @@ static void dsos__fprintf(FILE *fp) | |||
176 | 188 | ||
177 | static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) | 189 | static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) |
178 | { | 190 | { |
179 | return dso__find_symbol(kernel_dso, ip); | 191 | return dso__find_symbol(dso, ip); |
180 | } | 192 | } |
181 | 193 | ||
182 | static int load_kernel(void) | 194 | static int load_kernel(void) |
@@ -187,8 +199,8 @@ static int load_kernel(void) | |||
187 | if (!kernel_dso) | 199 | if (!kernel_dso) |
188 | return -1; | 200 | return -1; |
189 | 201 | ||
190 | err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); | 202 | err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules); |
191 | if (err) { | 203 | if (err <= 0) { |
192 | dso__delete(kernel_dso); | 204 | dso__delete(kernel_dso); |
193 | kernel_dso = NULL; | 205 | kernel_dso = NULL; |
194 | } else | 206 | } else |
@@ -202,6 +214,11 @@ static int load_kernel(void) | |||
202 | 214 | ||
203 | dsos__add(vdso); | 215 | dsos__add(vdso); |
204 | 216 | ||
217 | hypervisor_dso = dso__new("[hypervisor]", 0); | ||
218 | if (!hypervisor_dso) | ||
219 | return -1; | ||
220 | dsos__add(hypervisor_dso); | ||
221 | |||
205 | return err; | 222 | return err; |
206 | } | 223 | } |
207 | 224 | ||
@@ -233,7 +250,7 @@ static u64 map__map_ip(struct map *map, u64 ip) | |||
233 | return ip - map->start + map->pgoff; | 250 | return ip - map->start + map->pgoff; |
234 | } | 251 | } |
235 | 252 | ||
236 | static u64 vdso__map_ip(struct map *map, u64 ip) | 253 | static u64 vdso__map_ip(struct map *map __used, u64 ip) |
237 | { | 254 | { |
238 | return ip; | 255 | return ip; |
239 | } | 256 | } |
@@ -640,7 +657,11 @@ sort__sym_print(FILE *fp, struct hist_entry *self) | |||
640 | 657 | ||
641 | if (self->sym) { | 658 | if (self->sym) { |
642 | ret += fprintf(fp, "[%c] %s", | 659 | ret += fprintf(fp, "[%c] %s", |
643 | self->dso == kernel_dso ? 'k' : '.', self->sym->name); | 660 | self->dso == kernel_dso ? 'k' : |
661 | self->dso == hypervisor_dso ? 'h' : '.', self->sym->name); | ||
662 | |||
663 | if (self->sym->module) | ||
664 | ret += fprintf(fp, "\t[%s]", self->sym->module->name); | ||
644 | } else { | 665 | } else { |
645 | ret += fprintf(fp, "%#016llx", (u64)self->ip); | 666 | ret += fprintf(fp, "%#016llx", (u64)self->ip); |
646 | } | 667 | } |
@@ -705,7 +726,7 @@ static LIST_HEAD(hist_entry__sort_list); | |||
705 | 726 | ||
706 | static int sort_dimension__add(char *tok) | 727 | static int sort_dimension__add(char *tok) |
707 | { | 728 | { |
708 | int i; | 729 | unsigned int i; |
709 | 730 | ||
710 | for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { | 731 | for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { |
711 | struct sort_dimension *sd = &sort_dimensions[i]; | 732 | struct sort_dimension *sd = &sort_dimensions[i]; |
@@ -775,8 +796,109 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right) | |||
775 | return cmp; | 796 | return cmp; |
776 | } | 797 | } |
777 | 798 | ||
799 | static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask) | ||
800 | { | ||
801 | int i; | ||
802 | size_t ret = 0; | ||
803 | |||
804 | ret += fprintf(fp, "%s", " "); | ||
805 | |||
806 | for (i = 0; i < depth; i++) | ||
807 | if (depth_mask & (1 << i)) | ||
808 | ret += fprintf(fp, "| "); | ||
809 | else | ||
810 | ret += fprintf(fp, " "); | ||
811 | |||
812 | ret += fprintf(fp, "\n"); | ||
813 | |||
814 | return ret; | ||
815 | } | ||
816 | static size_t | ||
817 | ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth, | ||
818 | int depth_mask, int count, u64 total_samples, | ||
819 | int hits) | ||
820 | { | ||
821 | int i; | ||
822 | size_t ret = 0; | ||
823 | |||
824 | ret += fprintf(fp, "%s", " "); | ||
825 | for (i = 0; i < depth; i++) { | ||
826 | if (depth_mask & (1 << i)) | ||
827 | ret += fprintf(fp, "|"); | ||
828 | else | ||
829 | ret += fprintf(fp, " "); | ||
830 | if (!count && i == depth - 1) { | ||
831 | double percent; | ||
832 | |||
833 | percent = hits * 100.0 / total_samples; | ||
834 | ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent); | ||
835 | } else | ||
836 | ret += fprintf(fp, "%s", " "); | ||
837 | } | ||
838 | if (chain->sym) | ||
839 | ret += fprintf(fp, "%s\n", chain->sym->name); | ||
840 | else | ||
841 | ret += fprintf(fp, "%p\n", (void *)(long)chain->ip); | ||
842 | |||
843 | return ret; | ||
844 | } | ||
845 | |||
846 | static size_t | ||
847 | callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | ||
848 | u64 total_samples, int depth, int depth_mask) | ||
849 | { | ||
850 | struct rb_node *node, *next; | ||
851 | struct callchain_node *child; | ||
852 | struct callchain_list *chain; | ||
853 | int new_depth_mask = depth_mask; | ||
854 | u64 new_total; | ||
855 | size_t ret = 0; | ||
856 | int i; | ||
857 | |||
858 | if (callchain_param.mode == CHAIN_GRAPH_REL) | ||
859 | new_total = self->cumul_hit; | ||
860 | else | ||
861 | new_total = total_samples; | ||
862 | |||
863 | node = rb_first(&self->rb_root); | ||
864 | while (node) { | ||
865 | child = rb_entry(node, struct callchain_node, rb_node); | ||
866 | |||
867 | /* | ||
868 | * The depth mask manages the output of pipes that show | ||
869 | * the depth. We don't want to keep the pipes of the current | ||
870 | * level for the last child of this depth | ||
871 | */ | ||
872 | next = rb_next(node); | ||
873 | if (!next) | ||
874 | new_depth_mask &= ~(1 << (depth - 1)); | ||
875 | |||
876 | /* | ||
877 | * But we keep the older depth mask for the line seperator | ||
878 | * to keep the level link until we reach the last child | ||
879 | */ | ||
880 | ret += ipchain__fprintf_graph_line(fp, depth, depth_mask); | ||
881 | i = 0; | ||
882 | list_for_each_entry(chain, &child->val, list) { | ||
883 | if (chain->ip >= PERF_CONTEXT_MAX) | ||
884 | continue; | ||
885 | ret += ipchain__fprintf_graph(fp, chain, depth, | ||
886 | new_depth_mask, i++, | ||
887 | new_total, | ||
888 | child->cumul_hit); | ||
889 | } | ||
890 | ret += callchain__fprintf_graph(fp, child, new_total, | ||
891 | depth + 1, | ||
892 | new_depth_mask | (1 << depth)); | ||
893 | node = next; | ||
894 | } | ||
895 | |||
896 | return ret; | ||
897 | } | ||
898 | |||
778 | static size_t | 899 | static size_t |
779 | callchain__fprintf(FILE *fp, struct callchain_node *self, u64 total_samples) | 900 | callchain__fprintf_flat(FILE *fp, struct callchain_node *self, |
901 | u64 total_samples) | ||
780 | { | 902 | { |
781 | struct callchain_list *chain; | 903 | struct callchain_list *chain; |
782 | size_t ret = 0; | 904 | size_t ret = 0; |
@@ -784,11 +906,18 @@ callchain__fprintf(FILE *fp, struct callchain_node *self, u64 total_samples) | |||
784 | if (!self) | 906 | if (!self) |
785 | return 0; | 907 | return 0; |
786 | 908 | ||
787 | ret += callchain__fprintf(fp, self->parent, total_samples); | 909 | ret += callchain__fprintf_flat(fp, self->parent, total_samples); |
788 | 910 | ||
789 | 911 | ||
790 | list_for_each_entry(chain, &self->val, list) | 912 | list_for_each_entry(chain, &self->val, list) { |
791 | ret += fprintf(fp, " %p\n", (void *)chain->ip); | 913 | if (chain->ip >= PERF_CONTEXT_MAX) |
914 | continue; | ||
915 | if (chain->sym) | ||
916 | ret += fprintf(fp, " %s\n", chain->sym->name); | ||
917 | else | ||
918 | ret += fprintf(fp, " %p\n", | ||
919 | (void *)(long)chain->ip); | ||
920 | } | ||
792 | 921 | ||
793 | return ret; | 922 | return ret; |
794 | } | 923 | } |
@@ -807,8 +936,19 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
807 | 936 | ||
808 | chain = rb_entry(rb_node, struct callchain_node, rb_node); | 937 | chain = rb_entry(rb_node, struct callchain_node, rb_node); |
809 | percent = chain->hit * 100.0 / total_samples; | 938 | percent = chain->hit * 100.0 / total_samples; |
810 | ret += fprintf(fp, " %6.2f%%\n", percent); | 939 | switch (callchain_param.mode) { |
811 | ret += callchain__fprintf(fp, chain, total_samples); | 940 | case CHAIN_FLAT: |
941 | ret += percent_color_fprintf(fp, " %6.2f%%\n", | ||
942 | percent); | ||
943 | ret += callchain__fprintf_flat(fp, chain, total_samples); | ||
944 | break; | ||
945 | case CHAIN_GRAPH_ABS: /* Falldown */ | ||
946 | case CHAIN_GRAPH_REL: | ||
947 | ret += callchain__fprintf_graph(fp, chain, | ||
948 | total_samples, 1, 1); | ||
949 | default: | ||
950 | break; | ||
951 | } | ||
812 | ret += fprintf(fp, "\n"); | 952 | ret += fprintf(fp, "\n"); |
813 | rb_node = rb_next(rb_node); | 953 | rb_node = rb_next(rb_node); |
814 | } | 954 | } |
@@ -826,25 +966,10 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) | |||
826 | if (exclude_other && !self->parent) | 966 | if (exclude_other && !self->parent) |
827 | return 0; | 967 | return 0; |
828 | 968 | ||
829 | if (total_samples) { | 969 | if (total_samples) |
830 | double percent = self->count * 100.0 / total_samples; | 970 | ret = percent_color_fprintf(fp, " %6.2f%%", |
831 | char *color = PERF_COLOR_NORMAL; | ||
832 | |||
833 | /* | ||
834 | * We color high-overhead entries in red, mid-overhead | ||
835 | * entries in green - and keep the low overhead places | ||
836 | * normal: | ||
837 | */ | ||
838 | if (percent >= 5.0) { | ||
839 | color = PERF_COLOR_RED; | ||
840 | } else { | ||
841 | if (percent >= 0.5) | ||
842 | color = PERF_COLOR_GREEN; | ||
843 | } | ||
844 | |||
845 | ret = color_fprintf(fp, color, " %6.2f%%", | ||
846 | (self->count * 100.0) / total_samples); | 971 | (self->count * 100.0) / total_samples); |
847 | } else | 972 | else |
848 | ret = fprintf(fp, "%12Ld ", self->count); | 973 | ret = fprintf(fp, "%12Ld ", self->count); |
849 | 974 | ||
850 | list_for_each_entry(se, &hist_entry__sort_list, list) { | 975 | list_for_each_entry(se, &hist_entry__sort_list, list) { |
@@ -923,6 +1048,58 @@ static int call__match(struct symbol *sym) | |||
923 | return 0; | 1048 | return 0; |
924 | } | 1049 | } |
925 | 1050 | ||
1051 | static struct symbol ** | ||
1052 | resolve_callchain(struct thread *thread, struct map *map __used, | ||
1053 | struct ip_callchain *chain, struct hist_entry *entry) | ||
1054 | { | ||
1055 | u64 context = PERF_CONTEXT_MAX; | ||
1056 | struct symbol **syms = NULL; | ||
1057 | unsigned int i; | ||
1058 | |||
1059 | if (callchain) { | ||
1060 | syms = calloc(chain->nr, sizeof(*syms)); | ||
1061 | if (!syms) { | ||
1062 | fprintf(stderr, "Can't allocate memory for symbols\n"); | ||
1063 | exit(-1); | ||
1064 | } | ||
1065 | } | ||
1066 | |||
1067 | for (i = 0; i < chain->nr; i++) { | ||
1068 | u64 ip = chain->ips[i]; | ||
1069 | struct dso *dso = NULL; | ||
1070 | struct symbol *sym; | ||
1071 | |||
1072 | if (ip >= PERF_CONTEXT_MAX) { | ||
1073 | context = ip; | ||
1074 | continue; | ||
1075 | } | ||
1076 | |||
1077 | switch (context) { | ||
1078 | case PERF_CONTEXT_HV: | ||
1079 | dso = hypervisor_dso; | ||
1080 | break; | ||
1081 | case PERF_CONTEXT_KERNEL: | ||
1082 | dso = kernel_dso; | ||
1083 | break; | ||
1084 | default: | ||
1085 | break; | ||
1086 | } | ||
1087 | |||
1088 | sym = resolve_symbol(thread, NULL, &dso, &ip); | ||
1089 | |||
1090 | if (sym) { | ||
1091 | if (sort__has_parent && call__match(sym) && | ||
1092 | !entry->parent) | ||
1093 | entry->parent = sym; | ||
1094 | if (!callchain) | ||
1095 | break; | ||
1096 | syms[i] = sym; | ||
1097 | } | ||
1098 | } | ||
1099 | |||
1100 | return syms; | ||
1101 | } | ||
1102 | |||
926 | /* | 1103 | /* |
927 | * collect histogram counts | 1104 | * collect histogram counts |
928 | */ | 1105 | */ |
@@ -935,6 +1112,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
935 | struct rb_node **p = &hist.rb_node; | 1112 | struct rb_node **p = &hist.rb_node; |
936 | struct rb_node *parent = NULL; | 1113 | struct rb_node *parent = NULL; |
937 | struct hist_entry *he; | 1114 | struct hist_entry *he; |
1115 | struct symbol **syms = NULL; | ||
938 | struct hist_entry entry = { | 1116 | struct hist_entry entry = { |
939 | .thread = thread, | 1117 | .thread = thread, |
940 | .map = map, | 1118 | .map = map, |
@@ -948,36 +1126,8 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
948 | }; | 1126 | }; |
949 | int cmp; | 1127 | int cmp; |
950 | 1128 | ||
951 | if (sort__has_parent && chain) { | 1129 | if ((sort__has_parent || callchain) && chain) |
952 | u64 context = PERF_CONTEXT_MAX; | 1130 | syms = resolve_callchain(thread, map, chain, &entry); |
953 | int i; | ||
954 | |||
955 | for (i = 0; i < chain->nr; i++) { | ||
956 | u64 ip = chain->ips[i]; | ||
957 | struct dso *dso = NULL; | ||
958 | struct symbol *sym; | ||
959 | |||
960 | if (ip >= PERF_CONTEXT_MAX) { | ||
961 | context = ip; | ||
962 | continue; | ||
963 | } | ||
964 | |||
965 | switch (context) { | ||
966 | case PERF_CONTEXT_KERNEL: | ||
967 | dso = kernel_dso; | ||
968 | break; | ||
969 | default: | ||
970 | break; | ||
971 | } | ||
972 | |||
973 | sym = resolve_symbol(thread, NULL, &dso, &ip); | ||
974 | |||
975 | if (sym && call__match(sym)) { | ||
976 | entry.parent = sym; | ||
977 | break; | ||
978 | } | ||
979 | } | ||
980 | } | ||
981 | 1131 | ||
982 | while (*p != NULL) { | 1132 | while (*p != NULL) { |
983 | parent = *p; | 1133 | parent = *p; |
@@ -987,8 +1137,10 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
987 | 1137 | ||
988 | if (!cmp) { | 1138 | if (!cmp) { |
989 | he->count += count; | 1139 | he->count += count; |
990 | if (callchain) | 1140 | if (callchain) { |
991 | append_chain(&he->callchain, chain); | 1141 | append_chain(&he->callchain, chain, syms); |
1142 | free(syms); | ||
1143 | } | ||
992 | return 0; | 1144 | return 0; |
993 | } | 1145 | } |
994 | 1146 | ||
@@ -1004,7 +1156,8 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
1004 | *he = entry; | 1156 | *he = entry; |
1005 | if (callchain) { | 1157 | if (callchain) { |
1006 | callchain_init(&he->callchain); | 1158 | callchain_init(&he->callchain); |
1007 | append_chain(&he->callchain, chain); | 1159 | append_chain(&he->callchain, chain, syms); |
1160 | free(syms); | ||
1008 | } | 1161 | } |
1009 | rb_link_node(&he->rb_node, parent, p); | 1162 | rb_link_node(&he->rb_node, parent, p); |
1010 | rb_insert_color(&he->rb_node, &hist); | 1163 | rb_insert_color(&he->rb_node, &hist); |
@@ -1076,14 +1229,15 @@ static void collapse__resort(void) | |||
1076 | 1229 | ||
1077 | static struct rb_root output_hists; | 1230 | static struct rb_root output_hists; |
1078 | 1231 | ||
1079 | static void output__insert_entry(struct hist_entry *he) | 1232 | static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits) |
1080 | { | 1233 | { |
1081 | struct rb_node **p = &output_hists.rb_node; | 1234 | struct rb_node **p = &output_hists.rb_node; |
1082 | struct rb_node *parent = NULL; | 1235 | struct rb_node *parent = NULL; |
1083 | struct hist_entry *iter; | 1236 | struct hist_entry *iter; |
1084 | 1237 | ||
1085 | if (callchain) | 1238 | if (callchain) |
1086 | sort_chain_to_rbtree(&he->sorted_chain, &he->callchain); | 1239 | callchain_param.sort(&he->sorted_chain, &he->callchain, |
1240 | min_callchain_hits, &callchain_param); | ||
1087 | 1241 | ||
1088 | while (*p != NULL) { | 1242 | while (*p != NULL) { |
1089 | parent = *p; | 1243 | parent = *p; |
@@ -1099,11 +1253,14 @@ static void output__insert_entry(struct hist_entry *he) | |||
1099 | rb_insert_color(&he->rb_node, &output_hists); | 1253 | rb_insert_color(&he->rb_node, &output_hists); |
1100 | } | 1254 | } |
1101 | 1255 | ||
1102 | static void output__resort(void) | 1256 | static void output__resort(u64 total_samples) |
1103 | { | 1257 | { |
1104 | struct rb_node *next; | 1258 | struct rb_node *next; |
1105 | struct hist_entry *n; | 1259 | struct hist_entry *n; |
1106 | struct rb_root *tree = &hist; | 1260 | struct rb_root *tree = &hist; |
1261 | u64 min_callchain_hits; | ||
1262 | |||
1263 | min_callchain_hits = total_samples * (callchain_param.min_percent / 100); | ||
1107 | 1264 | ||
1108 | if (sort__need_collapse) | 1265 | if (sort__need_collapse) |
1109 | tree = &collapse_hists; | 1266 | tree = &collapse_hists; |
@@ -1115,7 +1272,7 @@ static void output__resort(void) | |||
1115 | next = rb_next(&n->rb_node); | 1272 | next = rb_next(&n->rb_node); |
1116 | 1273 | ||
1117 | rb_erase(&n->rb_node, tree); | 1274 | rb_erase(&n->rb_node, tree); |
1118 | output__insert_entry(n); | 1275 | output__insert_entry(n, min_callchain_hits); |
1119 | } | 1276 | } |
1120 | } | 1277 | } |
1121 | 1278 | ||
@@ -1141,7 +1298,7 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) | |||
1141 | 1298 | ||
1142 | fprintf(fp, "# ........"); | 1299 | fprintf(fp, "# ........"); |
1143 | list_for_each_entry(se, &hist_entry__sort_list, list) { | 1300 | list_for_each_entry(se, &hist_entry__sort_list, list) { |
1144 | int i; | 1301 | unsigned int i; |
1145 | 1302 | ||
1146 | if (exclude_other && (se == &sort_parent)) | 1303 | if (exclude_other && (se == &sort_parent)) |
1147 | continue; | 1304 | continue; |
@@ -1213,6 +1370,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
1213 | struct map *map = NULL; | 1370 | struct map *map = NULL; |
1214 | void *more_data = event->ip.__more_data; | 1371 | void *more_data = event->ip.__more_data; |
1215 | struct ip_callchain *chain = NULL; | 1372 | struct ip_callchain *chain = NULL; |
1373 | int cpumode; | ||
1216 | 1374 | ||
1217 | if (sample_type & PERF_SAMPLE_PERIOD) { | 1375 | if (sample_type & PERF_SAMPLE_PERIOD) { |
1218 | period = *(u64 *)more_data; | 1376 | period = *(u64 *)more_data; |
@@ -1228,7 +1386,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
1228 | (long long)period); | 1386 | (long long)period); |
1229 | 1387 | ||
1230 | if (sample_type & PERF_SAMPLE_CALLCHAIN) { | 1388 | if (sample_type & PERF_SAMPLE_CALLCHAIN) { |
1231 | int i; | 1389 | unsigned int i; |
1232 | 1390 | ||
1233 | chain = (void *)more_data; | 1391 | chain = (void *)more_data; |
1234 | 1392 | ||
@@ -1256,7 +1414,9 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
1256 | if (comm_list && !strlist__has_entry(comm_list, thread->comm)) | 1414 | if (comm_list && !strlist__has_entry(comm_list, thread->comm)) |
1257 | return 0; | 1415 | return 0; |
1258 | 1416 | ||
1259 | if (event->header.misc & PERF_EVENT_MISC_KERNEL) { | 1417 | cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK; |
1418 | |||
1419 | if (cpumode == PERF_EVENT_MISC_KERNEL) { | ||
1260 | show = SHOW_KERNEL; | 1420 | show = SHOW_KERNEL; |
1261 | level = 'k'; | 1421 | level = 'k'; |
1262 | 1422 | ||
@@ -1264,7 +1424,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
1264 | 1424 | ||
1265 | dprintf(" ...... dso: %s\n", dso->name); | 1425 | dprintf(" ...... dso: %s\n", dso->name); |
1266 | 1426 | ||
1267 | } else if (event->header.misc & PERF_EVENT_MISC_USER) { | 1427 | } else if (cpumode == PERF_EVENT_MISC_USER) { |
1268 | 1428 | ||
1269 | show = SHOW_USER; | 1429 | show = SHOW_USER; |
1270 | level = '.'; | 1430 | level = '.'; |
@@ -1272,6 +1432,9 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) | |||
1272 | } else { | 1432 | } else { |
1273 | show = SHOW_HV; | 1433 | show = SHOW_HV; |
1274 | level = 'H'; | 1434 | level = 'H'; |
1435 | |||
1436 | dso = hypervisor_dso; | ||
1437 | |||
1275 | dprintf(" ...... dso: [hypervisor]\n"); | 1438 | dprintf(" ...... dso: [hypervisor]\n"); |
1276 | } | 1439 | } |
1277 | 1440 | ||
@@ -1534,9 +1697,19 @@ static int __cmd_report(void) | |||
1534 | 1697 | ||
1535 | sample_type = perf_header__sample_type(); | 1698 | sample_type = perf_header__sample_type(); |
1536 | 1699 | ||
1537 | if (sort__has_parent && !(sample_type & PERF_SAMPLE_CALLCHAIN)) { | 1700 | if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) { |
1538 | fprintf(stderr, "selected --sort parent, but no callchain data\n"); | 1701 | if (sort__has_parent) { |
1539 | exit(-1); | 1702 | fprintf(stderr, "selected --sort parent, but no" |
1703 | " callchain data. Did you call" | ||
1704 | " perf record without -g?\n"); | ||
1705 | exit(-1); | ||
1706 | } | ||
1707 | if (callchain) { | ||
1708 | fprintf(stderr, "selected -c but no callchain data." | ||
1709 | " Did you call perf record without" | ||
1710 | " -g?\n"); | ||
1711 | exit(-1); | ||
1712 | } | ||
1540 | } | 1713 | } |
1541 | 1714 | ||
1542 | if (load_kernel() < 0) { | 1715 | if (load_kernel() < 0) { |
@@ -1619,7 +1792,7 @@ more: | |||
1619 | if (offset + head >= header->data_offset + header->data_size) | 1792 | if (offset + head >= header->data_offset + header->data_size) |
1620 | goto done; | 1793 | goto done; |
1621 | 1794 | ||
1622 | if (offset + head < stat.st_size) | 1795 | if (offset + head < (unsigned long)stat.st_size) |
1623 | goto more; | 1796 | goto more; |
1624 | 1797 | ||
1625 | done: | 1798 | done: |
@@ -1643,12 +1816,58 @@ done: | |||
1643 | dsos__fprintf(stdout); | 1816 | dsos__fprintf(stdout); |
1644 | 1817 | ||
1645 | collapse__resort(); | 1818 | collapse__resort(); |
1646 | output__resort(); | 1819 | output__resort(total); |
1647 | output__fprintf(stdout, total); | 1820 | output__fprintf(stdout, total); |
1648 | 1821 | ||
1649 | return rc; | 1822 | return rc; |
1650 | } | 1823 | } |
1651 | 1824 | ||
1825 | static int | ||
1826 | parse_callchain_opt(const struct option *opt __used, const char *arg, | ||
1827 | int unset __used) | ||
1828 | { | ||
1829 | char *tok; | ||
1830 | char *endptr; | ||
1831 | |||
1832 | callchain = 1; | ||
1833 | |||
1834 | if (!arg) | ||
1835 | return 0; | ||
1836 | |||
1837 | tok = strtok((char *)arg, ","); | ||
1838 | if (!tok) | ||
1839 | return -1; | ||
1840 | |||
1841 | /* get the output mode */ | ||
1842 | if (!strncmp(tok, "graph", strlen(arg))) | ||
1843 | callchain_param.mode = CHAIN_GRAPH_ABS; | ||
1844 | |||
1845 | else if (!strncmp(tok, "flat", strlen(arg))) | ||
1846 | callchain_param.mode = CHAIN_FLAT; | ||
1847 | |||
1848 | else if (!strncmp(tok, "fractal", strlen(arg))) | ||
1849 | callchain_param.mode = CHAIN_GRAPH_REL; | ||
1850 | |||
1851 | else | ||
1852 | return -1; | ||
1853 | |||
1854 | /* get the min percentage */ | ||
1855 | tok = strtok(NULL, ","); | ||
1856 | if (!tok) | ||
1857 | goto setup; | ||
1858 | |||
1859 | callchain_param.min_percent = strtod(tok, &endptr); | ||
1860 | if (tok == endptr) | ||
1861 | return -1; | ||
1862 | |||
1863 | setup: | ||
1864 | if (register_callchain_param(&callchain_param) < 0) { | ||
1865 | fprintf(stderr, "Can't register callchain params\n"); | ||
1866 | return -1; | ||
1867 | } | ||
1868 | return 0; | ||
1869 | } | ||
1870 | |||
1652 | static const char * const report_usage[] = { | 1871 | static const char * const report_usage[] = { |
1653 | "perf report [<options>] <command>", | 1872 | "perf report [<options>] <command>", |
1654 | NULL | 1873 | NULL |
@@ -1662,6 +1881,8 @@ static const struct option options[] = { | |||
1662 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, | 1881 | OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, |
1663 | "dump raw trace in ASCII"), | 1882 | "dump raw trace in ASCII"), |
1664 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), | 1883 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), |
1884 | OPT_BOOLEAN('m', "modules", &modules, | ||
1885 | "load module symbols - WARNING: use only with -k and LIVE kernel"), | ||
1665 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", | 1886 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", |
1666 | "sort by key(s): pid, comm, dso, symbol, parent"), | 1887 | "sort by key(s): pid, comm, dso, symbol, parent"), |
1667 | OPT_BOOLEAN('P', "full-paths", &full_paths, | 1888 | OPT_BOOLEAN('P', "full-paths", &full_paths, |
@@ -1670,7 +1891,9 @@ static const struct option options[] = { | |||
1670 | "regex filter to identify parent, see: '--sort parent'"), | 1891 | "regex filter to identify parent, see: '--sort parent'"), |
1671 | OPT_BOOLEAN('x', "exclude-other", &exclude_other, | 1892 | OPT_BOOLEAN('x', "exclude-other", &exclude_other, |
1672 | "Only display entries with parent-match"), | 1893 | "Only display entries with parent-match"), |
1673 | OPT_BOOLEAN('c', "callchain", &callchain, "Display callchains"), | 1894 | OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type,min_percent", |
1895 | "Display callchains using output_type and min percent threshold. " | ||
1896 | "Default: flat,0", &parse_callchain_opt, callchain_default_opt), | ||
1674 | OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]", | 1897 | OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]", |
1675 | "only consider symbols in these dsos"), | 1898 | "only consider symbols in these dsos"), |
1676 | OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]", | 1899 | OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]", |
@@ -1708,7 +1931,7 @@ static void setup_list(struct strlist **list, const char *list_str, | |||
1708 | } | 1931 | } |
1709 | } | 1932 | } |
1710 | 1933 | ||
1711 | int cmd_report(int argc, const char **argv, const char *prefix) | 1934 | int cmd_report(int argc, const char **argv, const char *prefix __used) |
1712 | { | 1935 | { |
1713 | symbol__init(); | 1936 | symbol__init(); |
1714 | 1937 | ||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2e03524a1de0..27921a8ce1a9 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -64,7 +64,7 @@ static struct perf_counter_attr default_attrs[] = { | |||
64 | 64 | ||
65 | static int system_wide = 0; | 65 | static int system_wide = 0; |
66 | static int verbose = 0; | 66 | static int verbose = 0; |
67 | static int nr_cpus = 0; | 67 | static unsigned int nr_cpus = 0; |
68 | static int run_idx = 0; | 68 | static int run_idx = 0; |
69 | 69 | ||
70 | static int run_count = 1; | 70 | static int run_count = 1; |
@@ -96,6 +96,10 @@ static u64 walltime_nsecs_noise; | |||
96 | static u64 runtime_cycles_avg; | 96 | static u64 runtime_cycles_avg; |
97 | static u64 runtime_cycles_noise; | 97 | static u64 runtime_cycles_noise; |
98 | 98 | ||
99 | #define MATCH_EVENT(t, c, counter) \ | ||
100 | (attrs[counter].type == PERF_TYPE_##t && \ | ||
101 | attrs[counter].config == PERF_COUNT_##c) | ||
102 | |||
99 | #define ERR_PERF_OPEN \ | 103 | #define ERR_PERF_OPEN \ |
100 | "Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n" | 104 | "Error: counter %d, sys_perf_counter_open() syscall returned with %d (%s)\n" |
101 | 105 | ||
@@ -108,7 +112,8 @@ static void create_perf_stat_counter(int counter, int pid) | |||
108 | PERF_FORMAT_TOTAL_TIME_RUNNING; | 112 | PERF_FORMAT_TOTAL_TIME_RUNNING; |
109 | 113 | ||
110 | if (system_wide) { | 114 | if (system_wide) { |
111 | int cpu; | 115 | unsigned int cpu; |
116 | |||
112 | for (cpu = 0; cpu < nr_cpus; cpu++) { | 117 | for (cpu = 0; cpu < nr_cpus; cpu++) { |
113 | fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0); | 118 | fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0); |
114 | if (fd[cpu][counter] < 0 && verbose) | 119 | if (fd[cpu][counter] < 0 && verbose) |
@@ -132,13 +137,8 @@ static void create_perf_stat_counter(int counter, int pid) | |||
132 | */ | 137 | */ |
133 | static inline int nsec_counter(int counter) | 138 | static inline int nsec_counter(int counter) |
134 | { | 139 | { |
135 | if (attrs[counter].type != PERF_TYPE_SOFTWARE) | 140 | if (MATCH_EVENT(SOFTWARE, SW_CPU_CLOCK, counter) || |
136 | return 0; | 141 | MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) |
137 | |||
138 | if (attrs[counter].config == PERF_COUNT_SW_CPU_CLOCK) | ||
139 | return 1; | ||
140 | |||
141 | if (attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK) | ||
142 | return 1; | 142 | return 1; |
143 | 143 | ||
144 | return 0; | 144 | return 0; |
@@ -150,8 +150,8 @@ static inline int nsec_counter(int counter) | |||
150 | static void read_counter(int counter) | 150 | static void read_counter(int counter) |
151 | { | 151 | { |
152 | u64 *count, single_count[3]; | 152 | u64 *count, single_count[3]; |
153 | ssize_t res; | 153 | unsigned int cpu; |
154 | int cpu, nv; | 154 | size_t res, nv; |
155 | int scaled; | 155 | int scaled; |
156 | 156 | ||
157 | count = event_res[run_idx][counter]; | 157 | count = event_res[run_idx][counter]; |
@@ -165,6 +165,7 @@ static void read_counter(int counter) | |||
165 | 165 | ||
166 | res = read(fd[cpu][counter], single_count, nv * sizeof(u64)); | 166 | res = read(fd[cpu][counter], single_count, nv * sizeof(u64)); |
167 | assert(res == nv * sizeof(u64)); | 167 | assert(res == nv * sizeof(u64)); |
168 | |||
168 | close(fd[cpu][counter]); | 169 | close(fd[cpu][counter]); |
169 | fd[cpu][counter] = -1; | 170 | fd[cpu][counter] = -1; |
170 | 171 | ||
@@ -192,15 +193,13 @@ static void read_counter(int counter) | |||
192 | /* | 193 | /* |
193 | * Save the full runtime - to allow normalization during printout: | 194 | * Save the full runtime - to allow normalization during printout: |
194 | */ | 195 | */ |
195 | if (attrs[counter].type == PERF_TYPE_SOFTWARE && | 196 | if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) |
196 | attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK) | ||
197 | runtime_nsecs[run_idx] = count[0]; | 197 | runtime_nsecs[run_idx] = count[0]; |
198 | if (attrs[counter].type == PERF_TYPE_HARDWARE && | 198 | if (MATCH_EVENT(HARDWARE, HW_CPU_CYCLES, counter)) |
199 | attrs[counter].config == PERF_COUNT_HW_CPU_CYCLES) | ||
200 | runtime_cycles[run_idx] = count[0]; | 199 | runtime_cycles[run_idx] = count[0]; |
201 | } | 200 | } |
202 | 201 | ||
203 | static int run_perf_stat(int argc, const char **argv) | 202 | static int run_perf_stat(int argc __used, const char **argv) |
204 | { | 203 | { |
205 | unsigned long long t0, t1; | 204 | unsigned long long t0, t1; |
206 | int status = 0; | 205 | int status = 0; |
@@ -240,7 +239,8 @@ static int run_perf_stat(int argc, const char **argv) | |||
240 | /* | 239 | /* |
241 | * Wait until the parent tells us to go. | 240 | * Wait until the parent tells us to go. |
242 | */ | 241 | */ |
243 | read(go_pipe[0], &buf, 1); | 242 | if (read(go_pipe[0], &buf, 1) == -1) |
243 | perror("unable to read pipe"); | ||
244 | 244 | ||
245 | execvp(argv[0], (char **)argv); | 245 | execvp(argv[0], (char **)argv); |
246 | 246 | ||
@@ -253,7 +253,8 @@ static int run_perf_stat(int argc, const char **argv) | |||
253 | */ | 253 | */ |
254 | close(child_ready_pipe[1]); | 254 | close(child_ready_pipe[1]); |
255 | close(go_pipe[0]); | 255 | close(go_pipe[0]); |
256 | read(child_ready_pipe[0], &buf, 1); | 256 | if (read(child_ready_pipe[0], &buf, 1) == -1) |
257 | perror("unable to read pipe"); | ||
257 | close(child_ready_pipe[0]); | 258 | close(child_ready_pipe[0]); |
258 | 259 | ||
259 | for (counter = 0; counter < nr_counters; counter++) | 260 | for (counter = 0; counter < nr_counters; counter++) |
@@ -290,9 +291,7 @@ static void nsec_printout(int counter, u64 *count, u64 *noise) | |||
290 | 291 | ||
291 | fprintf(stderr, " %14.6f %-24s", msecs, event_name(counter)); | 292 | fprintf(stderr, " %14.6f %-24s", msecs, event_name(counter)); |
292 | 293 | ||
293 | if (attrs[counter].type == PERF_TYPE_SOFTWARE && | 294 | if (MATCH_EVENT(SOFTWARE, SW_TASK_CLOCK, counter)) { |
294 | attrs[counter].config == PERF_COUNT_SW_TASK_CLOCK) { | ||
295 | |||
296 | if (walltime_nsecs_avg) | 295 | if (walltime_nsecs_avg) |
297 | fprintf(stderr, " # %10.3f CPUs ", | 296 | fprintf(stderr, " # %10.3f CPUs ", |
298 | (double)count[0] / (double)walltime_nsecs_avg); | 297 | (double)count[0] / (double)walltime_nsecs_avg); |
@@ -305,9 +304,7 @@ static void abs_printout(int counter, u64 *count, u64 *noise) | |||
305 | fprintf(stderr, " %14Ld %-24s", count[0], event_name(counter)); | 304 | fprintf(stderr, " %14Ld %-24s", count[0], event_name(counter)); |
306 | 305 | ||
307 | if (runtime_cycles_avg && | 306 | if (runtime_cycles_avg && |
308 | attrs[counter].type == PERF_TYPE_HARDWARE && | 307 | MATCH_EVENT(HARDWARE, HW_INSTRUCTIONS, counter)) { |
309 | attrs[counter].config == PERF_COUNT_HW_INSTRUCTIONS) { | ||
310 | |||
311 | fprintf(stderr, " # %10.3f IPC ", | 308 | fprintf(stderr, " # %10.3f IPC ", |
312 | (double)count[0] / (double)runtime_cycles_avg); | 309 | (double)count[0] / (double)runtime_cycles_avg); |
313 | } else { | 310 | } else { |
@@ -390,7 +387,7 @@ static void calc_avg(void) | |||
390 | event_res_avg[j]+1, event_res[i][j]+1); | 387 | event_res_avg[j]+1, event_res[i][j]+1); |
391 | update_avg("counter/2", j, | 388 | update_avg("counter/2", j, |
392 | event_res_avg[j]+2, event_res[i][j]+2); | 389 | event_res_avg[j]+2, event_res[i][j]+2); |
393 | if (event_scaled[i][j] != -1) | 390 | if (event_scaled[i][j] != (u64)-1) |
394 | update_avg("scaled", j, | 391 | update_avg("scaled", j, |
395 | event_scaled_avg + j, event_scaled[i]+j); | 392 | event_scaled_avg + j, event_scaled[i]+j); |
396 | else | 393 | else |
@@ -510,7 +507,7 @@ static const struct option options[] = { | |||
510 | OPT_END() | 507 | OPT_END() |
511 | }; | 508 | }; |
512 | 509 | ||
513 | int cmd_stat(int argc, const char **argv, const char *prefix) | 510 | int cmd_stat(int argc, const char **argv, const char *prefix __used) |
514 | { | 511 | { |
515 | int status; | 512 | int status; |
516 | 513 | ||
@@ -528,7 +525,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix) | |||
528 | 525 | ||
529 | nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); | 526 | nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); |
530 | assert(nr_cpus <= MAX_NR_CPUS); | 527 | assert(nr_cpus <= MAX_NR_CPUS); |
531 | assert(nr_cpus >= 0); | 528 | assert((int)nr_cpus >= 0); |
532 | 529 | ||
533 | /* | 530 | /* |
534 | * We dont want to block the signals - that would cause | 531 | * We dont want to block the signals - that would cause |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index cf0d21f1ae10..95d5c0ae375a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include "util/symbol.h" | 23 | #include "util/symbol.h" |
24 | #include "util/color.h" | 24 | #include "util/color.h" |
25 | #include "util/util.h" | 25 | #include "util/util.h" |
26 | #include "util/rbtree.h" | 26 | #include <linux/rbtree.h> |
27 | #include "util/parse-options.h" | 27 | #include "util/parse-options.h" |
28 | #include "util/parse-events.h" | 28 | #include "util/parse-events.h" |
29 | 29 | ||
@@ -66,6 +66,7 @@ static unsigned int page_size; | |||
66 | static unsigned int mmap_pages = 16; | 66 | static unsigned int mmap_pages = 16; |
67 | static int freq = 0; | 67 | static int freq = 0; |
68 | static int verbose = 0; | 68 | static int verbose = 0; |
69 | static char *vmlinux = NULL; | ||
69 | 70 | ||
70 | static char *sym_filter; | 71 | static char *sym_filter; |
71 | static unsigned long filter_start; | 72 | static unsigned long filter_start; |
@@ -238,7 +239,6 @@ static void print_sym_table(void) | |||
238 | for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) { | 239 | for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) { |
239 | struct sym_entry *syme = rb_entry(nd, struct sym_entry, rb_node); | 240 | struct sym_entry *syme = rb_entry(nd, struct sym_entry, rb_node); |
240 | struct symbol *sym = (struct symbol *)(syme + 1); | 241 | struct symbol *sym = (struct symbol *)(syme + 1); |
241 | char *color = PERF_COLOR_NORMAL; | ||
242 | double pcnt; | 242 | double pcnt; |
243 | 243 | ||
244 | if (++printed > print_entries || syme->snap_count < count_filter) | 244 | if (++printed > print_entries || syme->snap_count < count_filter) |
@@ -247,29 +247,20 @@ static void print_sym_table(void) | |||
247 | pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / | 247 | pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / |
248 | sum_ksamples)); | 248 | sum_ksamples)); |
249 | 249 | ||
250 | /* | ||
251 | * We color high-overhead entries in red, mid-overhead | ||
252 | * entries in green - and keep the low overhead places | ||
253 | * normal: | ||
254 | */ | ||
255 | if (pcnt >= 5.0) { | ||
256 | color = PERF_COLOR_RED; | ||
257 | } else { | ||
258 | if (pcnt >= 0.5) | ||
259 | color = PERF_COLOR_GREEN; | ||
260 | } | ||
261 | |||
262 | if (nr_counters == 1) | 250 | if (nr_counters == 1) |
263 | printf("%20.2f - ", syme->weight); | 251 | printf("%20.2f - ", syme->weight); |
264 | else | 252 | else |
265 | printf("%9.1f %10ld - ", syme->weight, syme->snap_count); | 253 | printf("%9.1f %10ld - ", syme->weight, syme->snap_count); |
266 | 254 | ||
267 | color_fprintf(stdout, color, "%4.1f%%", pcnt); | 255 | percent_color_fprintf(stdout, "%4.1f%%", pcnt); |
268 | printf(" - %016llx : %s\n", sym->start, sym->name); | 256 | printf(" - %016llx : %s", sym->start, sym->name); |
257 | if (sym->module) | ||
258 | printf("\t[%s]", sym->module->name); | ||
259 | printf("\n"); | ||
269 | } | 260 | } |
270 | } | 261 | } |
271 | 262 | ||
272 | static void *display_thread(void *arg) | 263 | static void *display_thread(void *arg __used) |
273 | { | 264 | { |
274 | struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; | 265 | struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; |
275 | int delay_msecs = delay_secs * 1000; | 266 | int delay_msecs = delay_secs * 1000; |
@@ -286,11 +277,31 @@ static void *display_thread(void *arg) | |||
286 | return NULL; | 277 | return NULL; |
287 | } | 278 | } |
288 | 279 | ||
280 | /* Tag samples to be skipped. */ | ||
281 | static const char *skip_symbols[] = { | ||
282 | "default_idle", | ||
283 | "cpu_idle", | ||
284 | "enter_idle", | ||
285 | "exit_idle", | ||
286 | "mwait_idle", | ||
287 | "ppc64_runlatch_off", | ||
288 | "pseries_dedicated_idle_sleep", | ||
289 | NULL | ||
290 | }; | ||
291 | |||
289 | static int symbol_filter(struct dso *self, struct symbol *sym) | 292 | static int symbol_filter(struct dso *self, struct symbol *sym) |
290 | { | 293 | { |
291 | static int filter_match; | 294 | static int filter_match; |
292 | struct sym_entry *syme; | 295 | struct sym_entry *syme; |
293 | const char *name = sym->name; | 296 | const char *name = sym->name; |
297 | int i; | ||
298 | |||
299 | /* | ||
300 | * ppc64 uses function descriptors and appends a '.' to the | ||
301 | * start of every instruction address. Remove it. | ||
302 | */ | ||
303 | if (name[0] == '.') | ||
304 | name++; | ||
294 | 305 | ||
295 | if (!strcmp(name, "_text") || | 306 | if (!strcmp(name, "_text") || |
296 | !strcmp(name, "_etext") || | 307 | !strcmp(name, "_etext") || |
@@ -302,13 +313,12 @@ static int symbol_filter(struct dso *self, struct symbol *sym) | |||
302 | return 1; | 313 | return 1; |
303 | 314 | ||
304 | syme = dso__sym_priv(self, sym); | 315 | syme = dso__sym_priv(self, sym); |
305 | /* Tag samples to be skipped. */ | 316 | for (i = 0; skip_symbols[i]; i++) { |
306 | if (!strcmp("default_idle", name) || | 317 | if (!strcmp(skip_symbols[i], name)) { |
307 | !strcmp("cpu_idle", name) || | 318 | syme->skip = 1; |
308 | !strcmp("enter_idle", name) || | 319 | break; |
309 | !strcmp("exit_idle", name) || | 320 | } |
310 | !strcmp("mwait_idle", name)) | 321 | } |
311 | syme->skip = 1; | ||
312 | 322 | ||
313 | if (filter_match == 1) { | 323 | if (filter_match == 1) { |
314 | filter_end = sym->start; | 324 | filter_end = sym->start; |
@@ -340,12 +350,13 @@ static int parse_symbols(void) | |||
340 | { | 350 | { |
341 | struct rb_node *node; | 351 | struct rb_node *node; |
342 | struct symbol *sym; | 352 | struct symbol *sym; |
353 | int modules = vmlinux ? 1 : 0; | ||
343 | 354 | ||
344 | kernel_dso = dso__new("[kernel]", sizeof(struct sym_entry)); | 355 | kernel_dso = dso__new("[kernel]", sizeof(struct sym_entry)); |
345 | if (kernel_dso == NULL) | 356 | if (kernel_dso == NULL) |
346 | return -1; | 357 | return -1; |
347 | 358 | ||
348 | if (dso__load_kernel(kernel_dso, NULL, symbol_filter, 1) != 0) | 359 | if (dso__load_kernel(kernel_dso, vmlinux, symbol_filter, verbose, modules) <= 0) |
349 | goto out_delete_dso; | 360 | goto out_delete_dso; |
350 | 361 | ||
351 | node = rb_first(&kernel_dso->syms); | 362 | node = rb_first(&kernel_dso->syms); |
@@ -407,7 +418,7 @@ static void process_event(u64 ip, int counter, int user) | |||
407 | struct mmap_data { | 418 | struct mmap_data { |
408 | int counter; | 419 | int counter; |
409 | void *base; | 420 | void *base; |
410 | unsigned int mask; | 421 | int mask; |
411 | unsigned int prev; | 422 | unsigned int prev; |
412 | }; | 423 | }; |
413 | 424 | ||
@@ -661,6 +672,7 @@ static const struct option options[] = { | |||
661 | "system-wide collection from all CPUs"), | 672 | "system-wide collection from all CPUs"), |
662 | OPT_INTEGER('C', "CPU", &profile_cpu, | 673 | OPT_INTEGER('C', "CPU", &profile_cpu, |
663 | "CPU to profile on"), | 674 | "CPU to profile on"), |
675 | OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), | ||
664 | OPT_INTEGER('m', "mmap-pages", &mmap_pages, | 676 | OPT_INTEGER('m', "mmap-pages", &mmap_pages, |
665 | "number of mmap data pages"), | 677 | "number of mmap data pages"), |
666 | OPT_INTEGER('r', "realtime", &realtime_prio, | 678 | OPT_INTEGER('r', "realtime", &realtime_prio, |
@@ -675,7 +687,7 @@ static const struct option options[] = { | |||
675 | "put the counters into a counter group"), | 687 | "put the counters into a counter group"), |
676 | OPT_STRING('s', "sym-filter", &sym_filter, "pattern", | 688 | OPT_STRING('s', "sym-filter", &sym_filter, "pattern", |
677 | "only display symbols matchig this pattern"), | 689 | "only display symbols matchig this pattern"), |
678 | OPT_BOOLEAN('z', "zero", &group, | 690 | OPT_BOOLEAN('z', "zero", &zero, |
679 | "zero history across updates"), | 691 | "zero history across updates"), |
680 | OPT_INTEGER('F', "freq", &freq, | 692 | OPT_INTEGER('F', "freq", &freq, |
681 | "profile at this frequency"), | 693 | "profile at this frequency"), |
@@ -686,10 +698,12 @@ static const struct option options[] = { | |||
686 | OPT_END() | 698 | OPT_END() |
687 | }; | 699 | }; |
688 | 700 | ||
689 | int cmd_top(int argc, const char **argv, const char *prefix) | 701 | int cmd_top(int argc, const char **argv, const char *prefix __used) |
690 | { | 702 | { |
691 | int counter; | 703 | int counter; |
692 | 704 | ||
705 | symbol__init(); | ||
706 | |||
693 | page_size = sysconf(_SC_PAGE_SIZE); | 707 | page_size = sysconf(_SC_PAGE_SIZE); |
694 | 708 | ||
695 | argc = parse_options(argc, argv, options, top_usage, 0); | 709 | argc = parse_options(argc, argv, options, top_usage, 0); |
diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 4eb725933703..c5656784c61d 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c | |||
@@ -229,9 +229,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) | |||
229 | use_pager = 1; | 229 | use_pager = 1; |
230 | commit_pager_choice(); | 230 | commit_pager_choice(); |
231 | 231 | ||
232 | if (p->option & NEED_WORK_TREE) | ||
233 | /* setup_work_tree() */; | ||
234 | |||
235 | status = p->fn(argc, argv, prefix); | 232 | status = p->fn(argc, argv, prefix); |
236 | if (status) | 233 | if (status) |
237 | return status & 0xff; | 234 | return status & 0xff; |
@@ -266,7 +263,7 @@ static void handle_internal_command(int argc, const char **argv) | |||
266 | { "annotate", cmd_annotate, 0 }, | 263 | { "annotate", cmd_annotate, 0 }, |
267 | { "version", cmd_version, 0 }, | 264 | { "version", cmd_version, 0 }, |
268 | }; | 265 | }; |
269 | int i; | 266 | unsigned int i; |
270 | static const char ext[] = STRIP_EXTENSION; | 267 | static const char ext[] = STRIP_EXTENSION; |
271 | 268 | ||
272 | if (sizeof(ext) > 1) { | 269 | if (sizeof(ext) > 1) { |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index d3042a6ba03d..63e67cc5487b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -68,6 +68,8 @@ static inline unsigned long long rdclock(void) | |||
68 | #define __user | 68 | #define __user |
69 | #define asmlinkage | 69 | #define asmlinkage |
70 | 70 | ||
71 | #define __used __attribute__((__unused__)) | ||
72 | |||
71 | #define unlikely(x) __builtin_expect(!!(x), 0) | 73 | #define unlikely(x) __builtin_expect(!!(x), 0) |
72 | #define min(x, y) ({ \ | 74 | #define min(x, y) ({ \ |
73 | typeof(x) _min1 = (x); \ | 75 | typeof(x) _min1 = (x); \ |
diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c index 9b3dd2b428df..b8144e80bb1e 100644 --- a/tools/perf/util/alias.c +++ b/tools/perf/util/alias.c | |||
@@ -3,7 +3,7 @@ | |||
3 | static const char *alias_key; | 3 | static const char *alias_key; |
4 | static char *alias_val; | 4 | static char *alias_val; |
5 | 5 | ||
6 | static int alias_lookup_cb(const char *k, const char *v, void *cb) | 6 | static int alias_lookup_cb(const char *k, const char *v, void *cb __used) |
7 | { | 7 | { |
8 | if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) { | 8 | if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) { |
9 | if (!v) | 9 | if (!v) |
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 393d6146d13b..161d5f413e28 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include "util.h" | 4 | #include "util.h" |
5 | #include "strbuf.h" | 5 | #include "strbuf.h" |
6 | #include "../perf.h" | ||
6 | 7 | ||
7 | #define PERF_DIR_ENVIRONMENT "PERF_DIR" | 8 | #define PERF_DIR_ENVIRONMENT "PERF_DIR" |
8 | #define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE" | 9 | #define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE" |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index ad3c28578961..9d3c8141b8c1 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -4,6 +4,9 @@ | |||
4 | * Handle the callchains from the stream in an ad-hoc radix tree and then | 4 | * Handle the callchains from the stream in an ad-hoc radix tree and then |
5 | * sort them in an rbtree. | 5 | * sort them in an rbtree. |
6 | * | 6 | * |
7 | * Using a radix for code path provides a fast retrieval and factorizes | ||
8 | * memory use. Also that lets us use the paths in a hierarchical graph view. | ||
9 | * | ||
7 | */ | 10 | */ |
8 | 11 | ||
9 | #include <stdlib.h> | 12 | #include <stdlib.h> |
@@ -13,8 +16,12 @@ | |||
13 | 16 | ||
14 | #include "callchain.h" | 17 | #include "callchain.h" |
15 | 18 | ||
19 | #define chain_for_each_child(child, parent) \ | ||
20 | list_for_each_entry(child, &parent->children, brothers) | ||
16 | 21 | ||
17 | static void rb_insert_callchain(struct rb_root *root, struct callchain_node *chain) | 22 | static void |
23 | rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | ||
24 | enum chain_mode mode) | ||
18 | { | 25 | { |
19 | struct rb_node **p = &root->rb_node; | 26 | struct rb_node **p = &root->rb_node; |
20 | struct rb_node *parent = NULL; | 27 | struct rb_node *parent = NULL; |
@@ -24,32 +31,125 @@ static void rb_insert_callchain(struct rb_root *root, struct callchain_node *cha | |||
24 | parent = *p; | 31 | parent = *p; |
25 | rnode = rb_entry(parent, struct callchain_node, rb_node); | 32 | rnode = rb_entry(parent, struct callchain_node, rb_node); |
26 | 33 | ||
27 | if (rnode->hit < chain->hit) | 34 | switch (mode) { |
28 | p = &(*p)->rb_left; | 35 | case CHAIN_FLAT: |
29 | else | 36 | if (rnode->hit < chain->hit) |
30 | p = &(*p)->rb_right; | 37 | p = &(*p)->rb_left; |
38 | else | ||
39 | p = &(*p)->rb_right; | ||
40 | break; | ||
41 | case CHAIN_GRAPH_ABS: /* Falldown */ | ||
42 | case CHAIN_GRAPH_REL: | ||
43 | if (rnode->cumul_hit < chain->cumul_hit) | ||
44 | p = &(*p)->rb_left; | ||
45 | else | ||
46 | p = &(*p)->rb_right; | ||
47 | break; | ||
48 | default: | ||
49 | break; | ||
50 | } | ||
31 | } | 51 | } |
32 | 52 | ||
33 | rb_link_node(&chain->rb_node, parent, p); | 53 | rb_link_node(&chain->rb_node, parent, p); |
34 | rb_insert_color(&chain->rb_node, root); | 54 | rb_insert_color(&chain->rb_node, root); |
35 | } | 55 | } |
36 | 56 | ||
57 | static void | ||
58 | __sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node, | ||
59 | u64 min_hit) | ||
60 | { | ||
61 | struct callchain_node *child; | ||
62 | |||
63 | chain_for_each_child(child, node) | ||
64 | __sort_chain_flat(rb_root, child, min_hit); | ||
65 | |||
66 | if (node->hit && node->hit >= min_hit) | ||
67 | rb_insert_callchain(rb_root, node, CHAIN_FLAT); | ||
68 | } | ||
69 | |||
37 | /* | 70 | /* |
38 | * Once we get every callchains from the stream, we can now | 71 | * Once we get every callchains from the stream, we can now |
39 | * sort them by hit | 72 | * sort them by hit |
40 | */ | 73 | */ |
41 | void sort_chain_to_rbtree(struct rb_root *rb_root, struct callchain_node *node) | 74 | static void |
75 | sort_chain_flat(struct rb_root *rb_root, struct callchain_node *node, | ||
76 | u64 min_hit, struct callchain_param *param __used) | ||
77 | { | ||
78 | __sort_chain_flat(rb_root, node, min_hit); | ||
79 | } | ||
80 | |||
81 | static void __sort_chain_graph_abs(struct callchain_node *node, | ||
82 | u64 min_hit) | ||
83 | { | ||
84 | struct callchain_node *child; | ||
85 | |||
86 | node->rb_root = RB_ROOT; | ||
87 | |||
88 | chain_for_each_child(child, node) { | ||
89 | __sort_chain_graph_abs(child, min_hit); | ||
90 | if (child->cumul_hit >= min_hit) | ||
91 | rb_insert_callchain(&node->rb_root, child, | ||
92 | CHAIN_GRAPH_ABS); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | static void | ||
97 | sort_chain_graph_abs(struct rb_root *rb_root, struct callchain_node *chain_root, | ||
98 | u64 min_hit, struct callchain_param *param __used) | ||
99 | { | ||
100 | __sort_chain_graph_abs(chain_root, min_hit); | ||
101 | rb_root->rb_node = chain_root->rb_root.rb_node; | ||
102 | } | ||
103 | |||
104 | static void __sort_chain_graph_rel(struct callchain_node *node, | ||
105 | double min_percent) | ||
42 | { | 106 | { |
43 | struct callchain_node *child; | 107 | struct callchain_node *child; |
108 | u64 min_hit; | ||
44 | 109 | ||
45 | list_for_each_entry(child, &node->children, brothers) | 110 | node->rb_root = RB_ROOT; |
46 | sort_chain_to_rbtree(rb_root, child); | 111 | min_hit = node->cumul_hit * min_percent / 100.0; |
47 | 112 | ||
48 | if (node->hit) | 113 | chain_for_each_child(child, node) { |
49 | rb_insert_callchain(rb_root, node); | 114 | __sort_chain_graph_rel(child, min_percent); |
115 | if (child->cumul_hit >= min_hit) | ||
116 | rb_insert_callchain(&node->rb_root, child, | ||
117 | CHAIN_GRAPH_REL); | ||
118 | } | ||
50 | } | 119 | } |
51 | 120 | ||
52 | static struct callchain_node *create_child(struct callchain_node *parent) | 121 | static void |
122 | sort_chain_graph_rel(struct rb_root *rb_root, struct callchain_node *chain_root, | ||
123 | u64 min_hit __used, struct callchain_param *param) | ||
124 | { | ||
125 | __sort_chain_graph_rel(chain_root, param->min_percent); | ||
126 | rb_root->rb_node = chain_root->rb_root.rb_node; | ||
127 | } | ||
128 | |||
129 | int register_callchain_param(struct callchain_param *param) | ||
130 | { | ||
131 | switch (param->mode) { | ||
132 | case CHAIN_GRAPH_ABS: | ||
133 | param->sort = sort_chain_graph_abs; | ||
134 | break; | ||
135 | case CHAIN_GRAPH_REL: | ||
136 | param->sort = sort_chain_graph_rel; | ||
137 | break; | ||
138 | case CHAIN_FLAT: | ||
139 | param->sort = sort_chain_flat; | ||
140 | break; | ||
141 | default: | ||
142 | return -1; | ||
143 | } | ||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | /* | ||
148 | * Create a child for a parent. If inherit_children, then the new child | ||
149 | * will become the new parent of it's parent children | ||
150 | */ | ||
151 | static struct callchain_node * | ||
152 | create_child(struct callchain_node *parent, bool inherit_children) | ||
53 | { | 153 | { |
54 | struct callchain_node *new; | 154 | struct callchain_node *new; |
55 | 155 | ||
@@ -61,91 +161,147 @@ static struct callchain_node *create_child(struct callchain_node *parent) | |||
61 | new->parent = parent; | 161 | new->parent = parent; |
62 | INIT_LIST_HEAD(&new->children); | 162 | INIT_LIST_HEAD(&new->children); |
63 | INIT_LIST_HEAD(&new->val); | 163 | INIT_LIST_HEAD(&new->val); |
164 | |||
165 | if (inherit_children) { | ||
166 | struct callchain_node *next; | ||
167 | |||
168 | list_splice(&parent->children, &new->children); | ||
169 | INIT_LIST_HEAD(&parent->children); | ||
170 | |||
171 | chain_for_each_child(next, new) | ||
172 | next->parent = new; | ||
173 | } | ||
64 | list_add_tail(&new->brothers, &parent->children); | 174 | list_add_tail(&new->brothers, &parent->children); |
65 | 175 | ||
66 | return new; | 176 | return new; |
67 | } | 177 | } |
68 | 178 | ||
179 | /* | ||
180 | * Fill the node with callchain values | ||
181 | */ | ||
69 | static void | 182 | static void |
70 | fill_node(struct callchain_node *node, struct ip_callchain *chain, int start) | 183 | fill_node(struct callchain_node *node, struct ip_callchain *chain, |
184 | int start, struct symbol **syms) | ||
71 | { | 185 | { |
72 | int i; | 186 | unsigned int i; |
73 | 187 | ||
74 | for (i = start; i < chain->nr; i++) { | 188 | for (i = start; i < chain->nr; i++) { |
75 | struct callchain_list *call; | 189 | struct callchain_list *call; |
76 | 190 | ||
77 | call = malloc(sizeof(*chain)); | 191 | call = malloc(sizeof(*call)); |
78 | if (!call) { | 192 | if (!call) { |
79 | perror("not enough memory for the code path tree"); | 193 | perror("not enough memory for the code path tree"); |
80 | return; | 194 | return; |
81 | } | 195 | } |
82 | call->ip = chain->ips[i]; | 196 | call->ip = chain->ips[i]; |
197 | call->sym = syms[i]; | ||
83 | list_add_tail(&call->list, &node->val); | 198 | list_add_tail(&call->list, &node->val); |
84 | } | 199 | } |
85 | node->val_nr = i - start; | 200 | node->val_nr = chain->nr - start; |
201 | if (!node->val_nr) | ||
202 | printf("Warning: empty node in callchain tree\n"); | ||
86 | } | 203 | } |
87 | 204 | ||
88 | static void add_child(struct callchain_node *parent, struct ip_callchain *chain) | 205 | static void |
206 | add_child(struct callchain_node *parent, struct ip_callchain *chain, | ||
207 | int start, struct symbol **syms) | ||
89 | { | 208 | { |
90 | struct callchain_node *new; | 209 | struct callchain_node *new; |
91 | 210 | ||
92 | new = create_child(parent); | 211 | new = create_child(parent, false); |
93 | fill_node(new, chain, parent->val_nr); | 212 | fill_node(new, chain, start, syms); |
94 | 213 | ||
95 | new->hit = 1; | 214 | new->cumul_hit = new->hit = 1; |
96 | } | 215 | } |
97 | 216 | ||
217 | /* | ||
218 | * Split the parent in two parts (a new child is created) and | ||
219 | * give a part of its callchain to the created child. | ||
220 | * Then create another child to host the given callchain of new branch | ||
221 | */ | ||
98 | static void | 222 | static void |
99 | split_add_child(struct callchain_node *parent, struct ip_callchain *chain, | 223 | split_add_child(struct callchain_node *parent, struct ip_callchain *chain, |
100 | struct callchain_list *to_split, int idx) | 224 | struct callchain_list *to_split, int idx_parents, int idx_local, |
225 | struct symbol **syms) | ||
101 | { | 226 | { |
102 | struct callchain_node *new; | 227 | struct callchain_node *new; |
228 | struct list_head *old_tail; | ||
229 | unsigned int idx_total = idx_parents + idx_local; | ||
103 | 230 | ||
104 | /* split */ | 231 | /* split */ |
105 | new = create_child(parent); | 232 | new = create_child(parent, true); |
106 | list_move_tail(&to_split->list, &new->val); | ||
107 | new->hit = parent->hit; | ||
108 | parent->hit = 0; | ||
109 | parent->val_nr = idx; | ||
110 | 233 | ||
111 | /* create the new one */ | 234 | /* split the callchain and move a part to the new child */ |
112 | add_child(parent, chain); | 235 | old_tail = parent->val.prev; |
236 | list_del_range(&to_split->list, old_tail); | ||
237 | new->val.next = &to_split->list; | ||
238 | new->val.prev = old_tail; | ||
239 | to_split->list.prev = &new->val; | ||
240 | old_tail->next = &new->val; | ||
241 | |||
242 | /* split the hits */ | ||
243 | new->hit = parent->hit; | ||
244 | new->cumul_hit = parent->cumul_hit; | ||
245 | new->val_nr = parent->val_nr - idx_local; | ||
246 | parent->val_nr = idx_local; | ||
247 | |||
248 | /* create a new child for the new branch if any */ | ||
249 | if (idx_total < chain->nr) { | ||
250 | parent->hit = 0; | ||
251 | add_child(parent, chain, idx_total, syms); | ||
252 | } else { | ||
253 | parent->hit = 1; | ||
254 | } | ||
113 | } | 255 | } |
114 | 256 | ||
115 | static int | 257 | static int |
116 | __append_chain(struct callchain_node *root, struct ip_callchain *chain, | 258 | __append_chain(struct callchain_node *root, struct ip_callchain *chain, |
117 | int start); | 259 | unsigned int start, struct symbol **syms); |
118 | 260 | ||
119 | static int | 261 | static void |
120 | __append_chain_children(struct callchain_node *root, struct ip_callchain *chain) | 262 | __append_chain_children(struct callchain_node *root, struct ip_callchain *chain, |
263 | struct symbol **syms, unsigned int start) | ||
121 | { | 264 | { |
122 | struct callchain_node *rnode; | 265 | struct callchain_node *rnode; |
123 | 266 | ||
124 | /* lookup in childrens */ | 267 | /* lookup in childrens */ |
125 | list_for_each_entry(rnode, &root->children, brothers) { | 268 | chain_for_each_child(rnode, root) { |
126 | int ret = __append_chain(rnode, chain, root->val_nr); | 269 | unsigned int ret = __append_chain(rnode, chain, start, syms); |
270 | |||
127 | if (!ret) | 271 | if (!ret) |
128 | return 0; | 272 | goto cumul; |
129 | } | 273 | } |
130 | return -1; | 274 | /* nothing in children, add to the current node */ |
275 | add_child(root, chain, start, syms); | ||
276 | |||
277 | cumul: | ||
278 | root->cumul_hit++; | ||
131 | } | 279 | } |
132 | 280 | ||
133 | static int | 281 | static int |
134 | __append_chain(struct callchain_node *root, struct ip_callchain *chain, | 282 | __append_chain(struct callchain_node *root, struct ip_callchain *chain, |
135 | int start) | 283 | unsigned int start, struct symbol **syms) |
136 | { | 284 | { |
137 | struct callchain_list *cnode; | 285 | struct callchain_list *cnode; |
138 | int i = start; | 286 | unsigned int i = start; |
139 | bool found = false; | 287 | bool found = false; |
140 | 288 | ||
141 | /* lookup in the current node */ | 289 | /* |
290 | * Lookup in the current node | ||
291 | * If we have a symbol, then compare the start to match | ||
292 | * anywhere inside a function. | ||
293 | */ | ||
142 | list_for_each_entry(cnode, &root->val, list) { | 294 | list_for_each_entry(cnode, &root->val, list) { |
143 | if (cnode->ip != chain->ips[i++]) | 295 | if (i == chain->nr) |
296 | break; | ||
297 | if (cnode->sym && syms[i]) { | ||
298 | if (cnode->sym->start != syms[i]->start) | ||
299 | break; | ||
300 | } else if (cnode->ip != chain->ips[i]) | ||
144 | break; | 301 | break; |
145 | if (!found) | 302 | if (!found) |
146 | found = true; | 303 | found = true; |
147 | if (i == chain->nr) | 304 | i++; |
148 | break; | ||
149 | } | 305 | } |
150 | 306 | ||
151 | /* matches not, relay on the parent */ | 307 | /* matches not, relay on the parent */ |
@@ -153,22 +309,27 @@ __append_chain(struct callchain_node *root, struct ip_callchain *chain, | |||
153 | return -1; | 309 | return -1; |
154 | 310 | ||
155 | /* we match only a part of the node. Split it and add the new chain */ | 311 | /* we match only a part of the node. Split it and add the new chain */ |
156 | if (i < root->val_nr) { | 312 | if (i - start < root->val_nr) { |
157 | split_add_child(root, chain, cnode, i); | 313 | split_add_child(root, chain, cnode, start, i - start, syms); |
158 | return 0; | 314 | return 0; |
159 | } | 315 | } |
160 | 316 | ||
161 | /* we match 100% of the path, increment the hit */ | 317 | /* we match 100% of the path, increment the hit */ |
162 | if (i == root->val_nr) { | 318 | if (i - start == root->val_nr && i == chain->nr) { |
163 | root->hit++; | 319 | root->hit++; |
320 | root->cumul_hit++; | ||
321 | |||
164 | return 0; | 322 | return 0; |
165 | } | 323 | } |
166 | 324 | ||
167 | return __append_chain_children(root, chain); | 325 | /* We match the node and still have a part remaining */ |
326 | __append_chain_children(root, chain, syms, i); | ||
327 | |||
328 | return 0; | ||
168 | } | 329 | } |
169 | 330 | ||
170 | void append_chain(struct callchain_node *root, struct ip_callchain *chain) | 331 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, |
332 | struct symbol **syms) | ||
171 | { | 333 | { |
172 | if (__append_chain_children(root, chain) == -1) | 334 | __append_chain_children(root, chain, syms, 0); |
173 | add_child(root, chain); | ||
174 | } | 335 | } |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index fa1cd2f71fd3..7812122bea1d 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -2,22 +2,42 @@ | |||
2 | #define __PERF_CALLCHAIN_H | 2 | #define __PERF_CALLCHAIN_H |
3 | 3 | ||
4 | #include "../perf.h" | 4 | #include "../perf.h" |
5 | #include "list.h" | 5 | #include <linux/list.h> |
6 | #include "rbtree.h" | 6 | #include <linux/rbtree.h> |
7 | #include "symbol.h" | ||
7 | 8 | ||
9 | enum chain_mode { | ||
10 | CHAIN_FLAT, | ||
11 | CHAIN_GRAPH_ABS, | ||
12 | CHAIN_GRAPH_REL | ||
13 | }; | ||
8 | 14 | ||
9 | struct callchain_node { | 15 | struct callchain_node { |
10 | struct callchain_node *parent; | 16 | struct callchain_node *parent; |
11 | struct list_head brothers; | 17 | struct list_head brothers; |
12 | struct list_head children; | 18 | struct list_head children; |
13 | struct list_head val; | 19 | struct list_head val; |
14 | struct rb_node rb_node; | 20 | struct rb_node rb_node; /* to sort nodes in an rbtree */ |
15 | int val_nr; | 21 | struct rb_root rb_root; /* sorted tree of children */ |
16 | int hit; | 22 | unsigned int val_nr; |
23 | u64 hit; | ||
24 | u64 cumul_hit; /* hit + hits of children */ | ||
25 | }; | ||
26 | |||
27 | struct callchain_param; | ||
28 | |||
29 | typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *, | ||
30 | u64, struct callchain_param *); | ||
31 | |||
32 | struct callchain_param { | ||
33 | enum chain_mode mode; | ||
34 | double min_percent; | ||
35 | sort_chain_func_t sort; | ||
17 | }; | 36 | }; |
18 | 37 | ||
19 | struct callchain_list { | 38 | struct callchain_list { |
20 | unsigned long ip; | 39 | u64 ip; |
40 | struct symbol *sym; | ||
21 | struct list_head list; | 41 | struct list_head list; |
22 | }; | 42 | }; |
23 | 43 | ||
@@ -28,6 +48,7 @@ static inline void callchain_init(struct callchain_node *node) | |||
28 | INIT_LIST_HEAD(&node->val); | 48 | INIT_LIST_HEAD(&node->val); |
29 | } | 49 | } |
30 | 50 | ||
31 | void append_chain(struct callchain_node *root, struct ip_callchain *chain); | 51 | int register_callchain_param(struct callchain_param *param); |
32 | void sort_chain_to_rbtree(struct rb_root *rb_root, struct callchain_node *node); | 52 | void append_chain(struct callchain_node *root, struct ip_callchain *chain, |
53 | struct symbol **syms); | ||
33 | #endif | 54 | #endif |
diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 9a8c20ccc53e..90a044d1fe7d 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c | |||
@@ -11,7 +11,8 @@ static int parse_color(const char *name, int len) | |||
11 | }; | 11 | }; |
12 | char *end; | 12 | char *end; |
13 | int i; | 13 | int i; |
14 | for (i = 0; i < ARRAY_SIZE(color_names); i++) { | 14 | |
15 | for (i = 0; i < (int)ARRAY_SIZE(color_names); i++) { | ||
15 | const char *str = color_names[i]; | 16 | const char *str = color_names[i]; |
16 | if (!strncasecmp(name, str, len) && !str[len]) | 17 | if (!strncasecmp(name, str, len) && !str[len]) |
17 | return i - 1; | 18 | return i - 1; |
@@ -28,7 +29,8 @@ static int parse_attr(const char *name, int len) | |||
28 | static const char * const attr_names[] = { | 29 | static const char * const attr_names[] = { |
29 | "bold", "dim", "ul", "blink", "reverse" | 30 | "bold", "dim", "ul", "blink", "reverse" |
30 | }; | 31 | }; |
31 | int i; | 32 | unsigned int i; |
33 | |||
32 | for (i = 0; i < ARRAY_SIZE(attr_names); i++) { | 34 | for (i = 0; i < ARRAY_SIZE(attr_names); i++) { |
33 | const char *str = attr_names[i]; | 35 | const char *str = attr_names[i]; |
34 | if (!strncasecmp(name, str, len) && !str[len]) | 36 | if (!strncasecmp(name, str, len) && !str[len]) |
@@ -222,10 +224,12 @@ int color_fwrite_lines(FILE *fp, const char *color, | |||
222 | { | 224 | { |
223 | if (!*color) | 225 | if (!*color) |
224 | return fwrite(buf, count, 1, fp) != 1; | 226 | return fwrite(buf, count, 1, fp) != 1; |
227 | |||
225 | while (count) { | 228 | while (count) { |
226 | char *p = memchr(buf, '\n', count); | 229 | char *p = memchr(buf, '\n', count); |
230 | |||
227 | if (p != buf && (fputs(color, fp) < 0 || | 231 | if (p != buf && (fputs(color, fp) < 0 || |
228 | fwrite(buf, p ? p - buf : count, 1, fp) != 1 || | 232 | fwrite(buf, p ? (size_t)(p - buf) : count, 1, fp) != 1 || |
229 | fputs(PERF_COLOR_RESET, fp) < 0)) | 233 | fputs(PERF_COLOR_RESET, fp) < 0)) |
230 | return -1; | 234 | return -1; |
231 | if (!p) | 235 | if (!p) |
@@ -238,4 +242,31 @@ int color_fwrite_lines(FILE *fp, const char *color, | |||
238 | return 0; | 242 | return 0; |
239 | } | 243 | } |
240 | 244 | ||
245 | char *get_percent_color(double percent) | ||
246 | { | ||
247 | char *color = PERF_COLOR_NORMAL; | ||
241 | 248 | ||
249 | /* | ||
250 | * We color high-overhead entries in red, mid-overhead | ||
251 | * entries in green - and keep the low overhead places | ||
252 | * normal: | ||
253 | */ | ||
254 | if (percent >= MIN_RED) | ||
255 | color = PERF_COLOR_RED; | ||
256 | else { | ||
257 | if (percent > MIN_GREEN) | ||
258 | color = PERF_COLOR_GREEN; | ||
259 | } | ||
260 | return color; | ||
261 | } | ||
262 | |||
263 | int percent_color_fprintf(FILE *fp, const char *fmt, double percent) | ||
264 | { | ||
265 | int r; | ||
266 | char *color; | ||
267 | |||
268 | color = get_percent_color(percent); | ||
269 | r = color_fprintf(fp, color, fmt, percent); | ||
270 | |||
271 | return r; | ||
272 | } | ||
diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h index 5abfd379582b..706cec50bd25 100644 --- a/tools/perf/util/color.h +++ b/tools/perf/util/color.h | |||
@@ -15,6 +15,9 @@ | |||
15 | #define PERF_COLOR_CYAN "\033[36m" | 15 | #define PERF_COLOR_CYAN "\033[36m" |
16 | #define PERF_COLOR_BG_RED "\033[41m" | 16 | #define PERF_COLOR_BG_RED "\033[41m" |
17 | 17 | ||
18 | #define MIN_GREEN 0.5 | ||
19 | #define MIN_RED 5.0 | ||
20 | |||
18 | /* | 21 | /* |
19 | * This variable stores the value of color.ui | 22 | * This variable stores the value of color.ui |
20 | */ | 23 | */ |
@@ -32,5 +35,7 @@ void color_parse_mem(const char *value, int len, const char *var, char *dst); | |||
32 | int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); | 35 | int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); |
33 | int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); | 36 | int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); |
34 | int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); | 37 | int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); |
38 | int percent_color_fprintf(FILE *fp, const char *fmt, double percent); | ||
39 | char *get_percent_color(double percent); | ||
35 | 40 | ||
36 | #endif /* COLOR_H */ | 41 | #endif /* COLOR_H */ |
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 3dd13faa6a27..780df541006d 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
@@ -47,10 +47,12 @@ static int get_next_char(void) | |||
47 | static char *parse_value(void) | 47 | static char *parse_value(void) |
48 | { | 48 | { |
49 | static char value[1024]; | 49 | static char value[1024]; |
50 | int quote = 0, comment = 0, len = 0, space = 0; | 50 | int quote = 0, comment = 0, space = 0; |
51 | size_t len = 0; | ||
51 | 52 | ||
52 | for (;;) { | 53 | for (;;) { |
53 | int c = get_next_char(); | 54 | int c = get_next_char(); |
55 | |||
54 | if (len >= sizeof(value) - 1) | 56 | if (len >= sizeof(value) - 1) |
55 | return NULL; | 57 | return NULL; |
56 | if (c == '\n') { | 58 | if (c == '\n') { |
@@ -353,13 +355,13 @@ int perf_config_string(const char **dest, const char *var, const char *value) | |||
353 | return 0; | 355 | return 0; |
354 | } | 356 | } |
355 | 357 | ||
356 | static int perf_default_core_config(const char *var, const char *value) | 358 | static int perf_default_core_config(const char *var __used, const char *value __used) |
357 | { | 359 | { |
358 | /* Add other config variables here and to Documentation/config.txt. */ | 360 | /* Add other config variables here and to Documentation/config.txt. */ |
359 | return 0; | 361 | return 0; |
360 | } | 362 | } |
361 | 363 | ||
362 | int perf_default_config(const char *var, const char *value, void *dummy) | 364 | int perf_default_config(const char *var, const char *value, void *dummy __used) |
363 | { | 365 | { |
364 | if (!prefixcmp(var, "core.")) | 366 | if (!prefixcmp(var, "core.")) |
365 | return perf_default_core_config(var, value); | 367 | return perf_default_core_config(var, value); |
@@ -471,10 +473,10 @@ static int matches(const char* key, const char* value) | |||
471 | !regexec(store.value_regex, value, 0, NULL, 0))); | 473 | !regexec(store.value_regex, value, 0, NULL, 0))); |
472 | } | 474 | } |
473 | 475 | ||
474 | static int store_aux(const char* key, const char* value, void *cb) | 476 | static int store_aux(const char* key, const char* value, void *cb __used) |
475 | { | 477 | { |
478 | int section_len; | ||
476 | const char *ep; | 479 | const char *ep; |
477 | size_t section_len; | ||
478 | 480 | ||
479 | switch (store.state) { | 481 | switch (store.state) { |
480 | case KEY_SEEN: | 482 | case KEY_SEEN: |
@@ -551,7 +553,7 @@ static int store_write_section(int fd, const char* key) | |||
551 | strbuf_addf(&sb, "[%.*s]\n", store.baselen, key); | 553 | strbuf_addf(&sb, "[%.*s]\n", store.baselen, key); |
552 | } | 554 | } |
553 | 555 | ||
554 | success = write_in_full(fd, sb.buf, sb.len) == sb.len; | 556 | success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len); |
555 | strbuf_release(&sb); | 557 | strbuf_release(&sb); |
556 | 558 | ||
557 | return success; | 559 | return success; |
@@ -599,7 +601,7 @@ static int store_write_pair(int fd, const char* key, const char* value) | |||
599 | } | 601 | } |
600 | strbuf_addf(&sb, "%s\n", quote); | 602 | strbuf_addf(&sb, "%s\n", quote); |
601 | 603 | ||
602 | success = write_in_full(fd, sb.buf, sb.len) == sb.len; | 604 | success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len); |
603 | strbuf_release(&sb); | 605 | strbuf_release(&sb); |
604 | 606 | ||
605 | return success; | 607 | return success; |
@@ -741,7 +743,7 @@ int perf_config_set_multivar(const char* key, const char* value, | |||
741 | } else { | 743 | } else { |
742 | struct stat st; | 744 | struct stat st; |
743 | char* contents; | 745 | char* contents; |
744 | size_t contents_sz, copy_begin, copy_end; | 746 | ssize_t contents_sz, copy_begin, copy_end; |
745 | int i, new_line = 0; | 747 | int i, new_line = 0; |
746 | 748 | ||
747 | if (value_regex == NULL) | 749 | if (value_regex == NULL) |
diff --git a/tools/perf/util/exec_cmd.c b/tools/perf/util/exec_cmd.c index d39292263153..34a352867382 100644 --- a/tools/perf/util/exec_cmd.c +++ b/tools/perf/util/exec_cmd.c | |||
@@ -1,6 +1,9 @@ | |||
1 | #include "cache.h" | 1 | #include "cache.h" |
2 | #include "exec_cmd.h" | 2 | #include "exec_cmd.h" |
3 | #include "quote.h" | 3 | #include "quote.h" |
4 | |||
5 | #include <string.h> | ||
6 | |||
4 | #define MAX_ARGS 32 | 7 | #define MAX_ARGS 32 |
5 | 8 | ||
6 | extern char **environ; | 9 | extern char **environ; |
@@ -51,7 +54,7 @@ const char *perf_extract_argv0_path(const char *argv0) | |||
51 | slash--; | 54 | slash--; |
52 | 55 | ||
53 | if (slash >= argv0) { | 56 | if (slash >= argv0) { |
54 | argv0_path = strndup(argv0, slash - argv0); | 57 | argv0_path = xstrndup(argv0, slash - argv0); |
55 | return slash + 1; | 58 | return slash + 1; |
56 | } | 59 | } |
57 | 60 | ||
diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c index 17a00e0df2c4..fbb00978b2e2 100644 --- a/tools/perf/util/help.c +++ b/tools/perf/util/help.c | |||
@@ -26,7 +26,7 @@ static int term_columns(void) | |||
26 | return 80; | 26 | return 80; |
27 | } | 27 | } |
28 | 28 | ||
29 | void add_cmdname(struct cmdnames *cmds, const char *name, int len) | 29 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) |
30 | { | 30 | { |
31 | struct cmdname *ent = malloc(sizeof(*ent) + len + 1); | 31 | struct cmdname *ent = malloc(sizeof(*ent) + len + 1); |
32 | 32 | ||
@@ -40,7 +40,8 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len) | |||
40 | 40 | ||
41 | static void clean_cmdnames(struct cmdnames *cmds) | 41 | static void clean_cmdnames(struct cmdnames *cmds) |
42 | { | 42 | { |
43 | int i; | 43 | unsigned int i; |
44 | |||
44 | for (i = 0; i < cmds->cnt; ++i) | 45 | for (i = 0; i < cmds->cnt; ++i) |
45 | free(cmds->names[i]); | 46 | free(cmds->names[i]); |
46 | free(cmds->names); | 47 | free(cmds->names); |
@@ -57,7 +58,7 @@ static int cmdname_compare(const void *a_, const void *b_) | |||
57 | 58 | ||
58 | static void uniq(struct cmdnames *cmds) | 59 | static void uniq(struct cmdnames *cmds) |
59 | { | 60 | { |
60 | int i, j; | 61 | unsigned int i, j; |
61 | 62 | ||
62 | if (!cmds->cnt) | 63 | if (!cmds->cnt) |
63 | return; | 64 | return; |
@@ -71,7 +72,7 @@ static void uniq(struct cmdnames *cmds) | |||
71 | 72 | ||
72 | void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) | 73 | void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) |
73 | { | 74 | { |
74 | int ci, cj, ei; | 75 | size_t ci, cj, ei; |
75 | int cmp; | 76 | int cmp; |
76 | 77 | ||
77 | ci = cj = ei = 0; | 78 | ci = cj = ei = 0; |
@@ -106,8 +107,9 @@ static void pretty_print_string_list(struct cmdnames *cmds, int longest) | |||
106 | printf(" "); | 107 | printf(" "); |
107 | 108 | ||
108 | for (j = 0; j < cols; j++) { | 109 | for (j = 0; j < cols; j++) { |
109 | int n = j * rows + i; | 110 | unsigned int n = j * rows + i; |
110 | int size = space; | 111 | unsigned int size = space; |
112 | |||
111 | if (n >= cmds->cnt) | 113 | if (n >= cmds->cnt) |
112 | break; | 114 | break; |
113 | if (j == cols-1 || n + rows >= cmds->cnt) | 115 | if (j == cols-1 || n + rows >= cmds->cnt) |
@@ -208,7 +210,7 @@ void load_command_list(const char *prefix, | |||
208 | void list_commands(const char *title, struct cmdnames *main_cmds, | 210 | void list_commands(const char *title, struct cmdnames *main_cmds, |
209 | struct cmdnames *other_cmds) | 211 | struct cmdnames *other_cmds) |
210 | { | 212 | { |
211 | int i, longest = 0; | 213 | unsigned int i, longest = 0; |
212 | 214 | ||
213 | for (i = 0; i < main_cmds->cnt; i++) | 215 | for (i = 0; i < main_cmds->cnt; i++) |
214 | if (longest < main_cmds->names[i]->len) | 216 | if (longest < main_cmds->names[i]->len) |
@@ -239,7 +241,8 @@ void list_commands(const char *title, struct cmdnames *main_cmds, | |||
239 | 241 | ||
240 | int is_in_cmdlist(struct cmdnames *c, const char *s) | 242 | int is_in_cmdlist(struct cmdnames *c, const char *s) |
241 | { | 243 | { |
242 | int i; | 244 | unsigned int i; |
245 | |||
243 | for (i = 0; i < c->cnt; i++) | 246 | for (i = 0; i < c->cnt; i++) |
244 | if (!strcmp(s, c->names[i]->name)) | 247 | if (!strcmp(s, c->names[i]->name)) |
245 | return 1; | 248 | return 1; |
@@ -271,7 +274,8 @@ static int levenshtein_compare(const void *p1, const void *p2) | |||
271 | 274 | ||
272 | static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) | 275 | static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) |
273 | { | 276 | { |
274 | int i; | 277 | unsigned int i; |
278 | |||
275 | ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); | 279 | ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); |
276 | 280 | ||
277 | for (i = 0; i < old->cnt; i++) | 281 | for (i = 0; i < old->cnt; i++) |
@@ -283,7 +287,7 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) | |||
283 | 287 | ||
284 | const char *help_unknown_cmd(const char *cmd) | 288 | const char *help_unknown_cmd(const char *cmd) |
285 | { | 289 | { |
286 | int i, n = 0, best_similarity = 0; | 290 | unsigned int i, n = 0, best_similarity = 0; |
287 | struct cmdnames main_cmds, other_cmds; | 291 | struct cmdnames main_cmds, other_cmds; |
288 | 292 | ||
289 | memset(&main_cmds, 0, sizeof(main_cmds)); | 293 | memset(&main_cmds, 0, sizeof(main_cmds)); |
@@ -345,7 +349,7 @@ const char *help_unknown_cmd(const char *cmd) | |||
345 | exit(1); | 349 | exit(1); |
346 | } | 350 | } |
347 | 351 | ||
348 | int cmd_version(int argc, const char **argv, const char *prefix) | 352 | int cmd_version(int argc __used, const char **argv __used, const char *prefix __used) |
349 | { | 353 | { |
350 | printf("perf version %s\n", perf_version_string); | 354 | printf("perf version %s\n", perf_version_string); |
351 | return 0; | 355 | return 0; |
diff --git a/tools/perf/util/help.h b/tools/perf/util/help.h index 56bc15406ffc..7128783637b4 100644 --- a/tools/perf/util/help.h +++ b/tools/perf/util/help.h | |||
@@ -2,8 +2,8 @@ | |||
2 | #define HELP_H | 2 | #define HELP_H |
3 | 3 | ||
4 | struct cmdnames { | 4 | struct cmdnames { |
5 | int alloc; | 5 | size_t alloc; |
6 | int cnt; | 6 | size_t cnt; |
7 | struct cmdname { | 7 | struct cmdname { |
8 | size_t len; /* also used for similarity index in help.c */ | 8 | size_t len; /* also used for similarity index in help.c */ |
9 | char name[FLEX_ARRAY]; | 9 | char name[FLEX_ARRAY]; |
@@ -19,7 +19,7 @@ static inline void mput_char(char c, unsigned int num) | |||
19 | void load_command_list(const char *prefix, | 19 | void load_command_list(const char *prefix, |
20 | struct cmdnames *main_cmds, | 20 | struct cmdnames *main_cmds, |
21 | struct cmdnames *other_cmds); | 21 | struct cmdnames *other_cmds); |
22 | void add_cmdname(struct cmdnames *cmds, const char *name, int len); | 22 | void add_cmdname(struct cmdnames *cmds, const char *name, size_t len); |
23 | /* Here we require that excludes is a sorted list. */ | 23 | /* Here we require that excludes is a sorted list. */ |
24 | void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); | 24 | void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); |
25 | int is_in_cmdlist(struct cmdnames *c, const char *s); | 25 | int is_in_cmdlist(struct cmdnames *c, const char *s); |
diff --git a/tools/perf/util/include/asm/system.h b/tools/perf/util/include/asm/system.h new file mode 100644 index 000000000000..710cecca972d --- /dev/null +++ b/tools/perf/util/include/asm/system.h | |||
@@ -0,0 +1 @@ | |||
/* Empty */ | |||
diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h new file mode 100644 index 000000000000..99c1b3d1edd9 --- /dev/null +++ b/tools/perf/util/include/linux/kernel.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef PERF_LINUX_KERNEL_H_ | ||
2 | #define PERF_LINUX_KERNEL_H_ | ||
3 | |||
4 | #ifndef offsetof | ||
5 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | ||
6 | #endif | ||
7 | |||
8 | #ifndef container_of | ||
9 | /** | ||
10 | * container_of - cast a member of a structure out to the containing structure | ||
11 | * @ptr: the pointer to the member. | ||
12 | * @type: the type of the container struct this is embedded in. | ||
13 | * @member: the name of the member within the struct. | ||
14 | * | ||
15 | */ | ||
16 | #define container_of(ptr, type, member) ({ \ | ||
17 | const typeof(((type *)0)->member) * __mptr = (ptr); \ | ||
18 | (type *)((char *)__mptr - offsetof(type, member)); }) | ||
19 | #endif | ||
20 | |||
21 | #endif | ||
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h new file mode 100644 index 000000000000..dbe4b814382a --- /dev/null +++ b/tools/perf/util/include/linux/list.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #include "../../../../include/linux/list.h" | ||
2 | |||
3 | #ifndef PERF_LIST_H | ||
4 | #define PERF_LIST_H | ||
5 | /** | ||
6 | * list_del_range - deletes range of entries from list. | ||
7 | * @begin: first element in the range to delete from the list. | ||
8 | * @end: last element in the range to delete from the list. | ||
9 | * Note: list_empty on the range of entries does not return true after this, | ||
10 | * the entries is in an undefined state. | ||
11 | */ | ||
12 | static inline void list_del_range(struct list_head *begin, | ||
13 | struct list_head *end) | ||
14 | { | ||
15 | begin->prev->next = end->next; | ||
16 | end->next->prev = begin->prev; | ||
17 | } | ||
18 | #endif | ||
diff --git a/tools/perf/util/include/linux/module.h b/tools/perf/util/include/linux/module.h new file mode 100644 index 000000000000..b43e2dc21e04 --- /dev/null +++ b/tools/perf/util/include/linux/module.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef PERF_LINUX_MODULE_H | ||
2 | #define PERF_LINUX_MODULE_H | ||
3 | |||
4 | #define EXPORT_SYMBOL(name) | ||
5 | |||
6 | #endif | ||
diff --git a/tools/perf/util/include/linux/poison.h b/tools/perf/util/include/linux/poison.h new file mode 100644 index 000000000000..fef6dbc9ce13 --- /dev/null +++ b/tools/perf/util/include/linux/poison.h | |||
@@ -0,0 +1 @@ | |||
#include "../../../../include/linux/poison.h" | |||
diff --git a/tools/perf/util/include/linux/prefetch.h b/tools/perf/util/include/linux/prefetch.h new file mode 100644 index 000000000000..7841e485d8c3 --- /dev/null +++ b/tools/perf/util/include/linux/prefetch.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef PERF_LINUX_PREFETCH_H | ||
2 | #define PERF_LINUX_PREFETCH_H | ||
3 | |||
4 | static inline void prefetch(void *a __attribute__((unused))) { } | ||
5 | |||
6 | #endif | ||
diff --git a/tools/perf/util/include/linux/rbtree.h b/tools/perf/util/include/linux/rbtree.h new file mode 100644 index 000000000000..7a243a143037 --- /dev/null +++ b/tools/perf/util/include/linux/rbtree.h | |||
@@ -0,0 +1 @@ | |||
#include "../../../../include/linux/rbtree.h" | |||
diff --git a/tools/perf/util/list.h b/tools/perf/util/list.h deleted file mode 100644 index e2548e8072cf..000000000000 --- a/tools/perf/util/list.h +++ /dev/null | |||
@@ -1,603 +0,0 @@ | |||
1 | #ifndef _LINUX_LIST_H | ||
2 | #define _LINUX_LIST_H | ||
3 | /* | ||
4 | Copyright (C) Cast of dozens, comes from the Linux kernel | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms of version 2 of the GNU General Public License as | ||
8 | published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <stddef.h> | ||
12 | |||
13 | /* | ||
14 | * These are non-NULL pointers that will result in page faults | ||
15 | * under normal circumstances, used to verify that nobody uses | ||
16 | * non-initialized list entries. | ||
17 | */ | ||
18 | #define LIST_POISON1 ((void *)0x00100100) | ||
19 | #define LIST_POISON2 ((void *)0x00200200) | ||
20 | |||
21 | /** | ||
22 | * container_of - cast a member of a structure out to the containing structure | ||
23 | * @ptr: the pointer to the member. | ||
24 | * @type: the type of the container struct this is embedded in. | ||
25 | * @member: the name of the member within the struct. | ||
26 | * | ||
27 | */ | ||
28 | #define container_of(ptr, type, member) ({ \ | ||
29 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | ||
30 | (type *)( (char *)__mptr - offsetof(type,member) );}) | ||
31 | |||
32 | /* | ||
33 | * Simple doubly linked list implementation. | ||
34 | * | ||
35 | * Some of the internal functions ("__xxx") are useful when | ||
36 | * manipulating whole lists rather than single entries, as | ||
37 | * sometimes we already know the next/prev entries and we can | ||
38 | * generate better code by using them directly rather than | ||
39 | * using the generic single-entry routines. | ||
40 | */ | ||
41 | |||
42 | struct list_head { | ||
43 | struct list_head *next, *prev; | ||
44 | }; | ||
45 | |||
46 | #define LIST_HEAD_INIT(name) { &(name), &(name) } | ||
47 | |||
48 | #define LIST_HEAD(name) \ | ||
49 | struct list_head name = LIST_HEAD_INIT(name) | ||
50 | |||
51 | static inline void INIT_LIST_HEAD(struct list_head *list) | ||
52 | { | ||
53 | list->next = list; | ||
54 | list->prev = list; | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * Insert a new entry between two known consecutive entries. | ||
59 | * | ||
60 | * This is only for internal list manipulation where we know | ||
61 | * the prev/next entries already! | ||
62 | */ | ||
63 | static inline void __list_add(struct list_head *new, | ||
64 | struct list_head *prev, | ||
65 | struct list_head *next) | ||
66 | { | ||
67 | next->prev = new; | ||
68 | new->next = next; | ||
69 | new->prev = prev; | ||
70 | prev->next = new; | ||
71 | } | ||
72 | |||
73 | /** | ||
74 | * list_add - add a new entry | ||
75 | * @new: new entry to be added | ||
76 | * @head: list head to add it after | ||
77 | * | ||
78 | * Insert a new entry after the specified head. | ||
79 | * This is good for implementing stacks. | ||
80 | */ | ||
81 | static inline void list_add(struct list_head *new, struct list_head *head) | ||
82 | { | ||
83 | __list_add(new, head, head->next); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * list_add_tail - add a new entry | ||
88 | * @new: new entry to be added | ||
89 | * @head: list head to add it before | ||
90 | * | ||
91 | * Insert a new entry before the specified head. | ||
92 | * This is useful for implementing queues. | ||
93 | */ | ||
94 | static inline void list_add_tail(struct list_head *new, struct list_head *head) | ||
95 | { | ||
96 | __list_add(new, head->prev, head); | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Delete a list entry by making the prev/next entries | ||
101 | * point to each other. | ||
102 | * | ||
103 | * This is only for internal list manipulation where we know | ||
104 | * the prev/next entries already! | ||
105 | */ | ||
106 | static inline void __list_del(struct list_head * prev, struct list_head * next) | ||
107 | { | ||
108 | next->prev = prev; | ||
109 | prev->next = next; | ||
110 | } | ||
111 | |||
112 | /** | ||
113 | * list_del - deletes entry from list. | ||
114 | * @entry: the element to delete from the list. | ||
115 | * Note: list_empty on entry does not return true after this, the entry is | ||
116 | * in an undefined state. | ||
117 | */ | ||
118 | static inline void list_del(struct list_head *entry) | ||
119 | { | ||
120 | __list_del(entry->prev, entry->next); | ||
121 | entry->next = LIST_POISON1; | ||
122 | entry->prev = LIST_POISON2; | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * list_del_range - deletes range of entries from list. | ||
127 | * @beging: first element in the range to delete from the list. | ||
128 | * @beging: first element in the range to delete from the list. | ||
129 | * Note: list_empty on the range of entries does not return true after this, | ||
130 | * the entries is in an undefined state. | ||
131 | */ | ||
132 | static inline void list_del_range(struct list_head *begin, | ||
133 | struct list_head *end) | ||
134 | { | ||
135 | begin->prev->next = end->next; | ||
136 | end->next->prev = begin->prev; | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * list_replace - replace old entry by new one | ||
141 | * @old : the element to be replaced | ||
142 | * @new : the new element to insert | ||
143 | * Note: if 'old' was empty, it will be overwritten. | ||
144 | */ | ||
145 | static inline void list_replace(struct list_head *old, | ||
146 | struct list_head *new) | ||
147 | { | ||
148 | new->next = old->next; | ||
149 | new->next->prev = new; | ||
150 | new->prev = old->prev; | ||
151 | new->prev->next = new; | ||
152 | } | ||
153 | |||
154 | static inline void list_replace_init(struct list_head *old, | ||
155 | struct list_head *new) | ||
156 | { | ||
157 | list_replace(old, new); | ||
158 | INIT_LIST_HEAD(old); | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * list_del_init - deletes entry from list and reinitialize it. | ||
163 | * @entry: the element to delete from the list. | ||
164 | */ | ||
165 | static inline void list_del_init(struct list_head *entry) | ||
166 | { | ||
167 | __list_del(entry->prev, entry->next); | ||
168 | INIT_LIST_HEAD(entry); | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * list_move - delete from one list and add as another's head | ||
173 | * @list: the entry to move | ||
174 | * @head: the head that will precede our entry | ||
175 | */ | ||
176 | static inline void list_move(struct list_head *list, struct list_head *head) | ||
177 | { | ||
178 | __list_del(list->prev, list->next); | ||
179 | list_add(list, head); | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * list_move_tail - delete from one list and add as another's tail | ||
184 | * @list: the entry to move | ||
185 | * @head: the head that will follow our entry | ||
186 | */ | ||
187 | static inline void list_move_tail(struct list_head *list, | ||
188 | struct list_head *head) | ||
189 | { | ||
190 | __list_del(list->prev, list->next); | ||
191 | list_add_tail(list, head); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * list_is_last - tests whether @list is the last entry in list @head | ||
196 | * @list: the entry to test | ||
197 | * @head: the head of the list | ||
198 | */ | ||
199 | static inline int list_is_last(const struct list_head *list, | ||
200 | const struct list_head *head) | ||
201 | { | ||
202 | return list->next == head; | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * list_empty - tests whether a list is empty | ||
207 | * @head: the list to test. | ||
208 | */ | ||
209 | static inline int list_empty(const struct list_head *head) | ||
210 | { | ||
211 | return head->next == head; | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * list_empty_careful - tests whether a list is empty and not being modified | ||
216 | * @head: the list to test | ||
217 | * | ||
218 | * Description: | ||
219 | * tests whether a list is empty _and_ checks that no other CPU might be | ||
220 | * in the process of modifying either member (next or prev) | ||
221 | * | ||
222 | * NOTE: using list_empty_careful() without synchronization | ||
223 | * can only be safe if the only activity that can happen | ||
224 | * to the list entry is list_del_init(). Eg. it cannot be used | ||
225 | * if another CPU could re-list_add() it. | ||
226 | */ | ||
227 | static inline int list_empty_careful(const struct list_head *head) | ||
228 | { | ||
229 | struct list_head *next = head->next; | ||
230 | return (next == head) && (next == head->prev); | ||
231 | } | ||
232 | |||
233 | static inline void __list_splice(struct list_head *list, | ||
234 | struct list_head *head) | ||
235 | { | ||
236 | struct list_head *first = list->next; | ||
237 | struct list_head *last = list->prev; | ||
238 | struct list_head *at = head->next; | ||
239 | |||
240 | first->prev = head; | ||
241 | head->next = first; | ||
242 | |||
243 | last->next = at; | ||
244 | at->prev = last; | ||
245 | } | ||
246 | |||
247 | /** | ||
248 | * list_splice - join two lists | ||
249 | * @list: the new list to add. | ||
250 | * @head: the place to add it in the first list. | ||
251 | */ | ||
252 | static inline void list_splice(struct list_head *list, struct list_head *head) | ||
253 | { | ||
254 | if (!list_empty(list)) | ||
255 | __list_splice(list, head); | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * list_splice_init - join two lists and reinitialise the emptied list. | ||
260 | * @list: the new list to add. | ||
261 | * @head: the place to add it in the first list. | ||
262 | * | ||
263 | * The list at @list is reinitialised | ||
264 | */ | ||
265 | static inline void list_splice_init(struct list_head *list, | ||
266 | struct list_head *head) | ||
267 | { | ||
268 | if (!list_empty(list)) { | ||
269 | __list_splice(list, head); | ||
270 | INIT_LIST_HEAD(list); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * list_entry - get the struct for this entry | ||
276 | * @ptr: the &struct list_head pointer. | ||
277 | * @type: the type of the struct this is embedded in. | ||
278 | * @member: the name of the list_struct within the struct. | ||
279 | */ | ||
280 | #define list_entry(ptr, type, member) \ | ||
281 | container_of(ptr, type, member) | ||
282 | |||
283 | /** | ||
284 | * list_first_entry - get the first element from a list | ||
285 | * @ptr: the list head to take the element from. | ||
286 | * @type: the type of the struct this is embedded in. | ||
287 | * @member: the name of the list_struct within the struct. | ||
288 | * | ||
289 | * Note, that list is expected to be not empty. | ||
290 | */ | ||
291 | #define list_first_entry(ptr, type, member) \ | ||
292 | list_entry((ptr)->next, type, member) | ||
293 | |||
294 | /** | ||
295 | * list_for_each - iterate over a list | ||
296 | * @pos: the &struct list_head to use as a loop cursor. | ||
297 | * @head: the head for your list. | ||
298 | */ | ||
299 | #define list_for_each(pos, head) \ | ||
300 | for (pos = (head)->next; pos != (head); \ | ||
301 | pos = pos->next) | ||
302 | |||
303 | /** | ||
304 | * __list_for_each - iterate over a list | ||
305 | * @pos: the &struct list_head to use as a loop cursor. | ||
306 | * @head: the head for your list. | ||
307 | * | ||
308 | * This variant differs from list_for_each() in that it's the | ||
309 | * simplest possible list iteration code, no prefetching is done. | ||
310 | * Use this for code that knows the list to be very short (empty | ||
311 | * or 1 entry) most of the time. | ||
312 | */ | ||
313 | #define __list_for_each(pos, head) \ | ||
314 | for (pos = (head)->next; pos != (head); pos = pos->next) | ||
315 | |||
316 | /** | ||
317 | * list_for_each_prev - iterate over a list backwards | ||
318 | * @pos: the &struct list_head to use as a loop cursor. | ||
319 | * @head: the head for your list. | ||
320 | */ | ||
321 | #define list_for_each_prev(pos, head) \ | ||
322 | for (pos = (head)->prev; pos != (head); \ | ||
323 | pos = pos->prev) | ||
324 | |||
325 | /** | ||
326 | * list_for_each_safe - iterate over a list safe against removal of list entry | ||
327 | * @pos: the &struct list_head to use as a loop cursor. | ||
328 | * @n: another &struct list_head to use as temporary storage | ||
329 | * @head: the head for your list. | ||
330 | */ | ||
331 | #define list_for_each_safe(pos, n, head) \ | ||
332 | for (pos = (head)->next, n = pos->next; pos != (head); \ | ||
333 | pos = n, n = pos->next) | ||
334 | |||
335 | /** | ||
336 | * list_for_each_entry - iterate over list of given type | ||
337 | * @pos: the type * to use as a loop cursor. | ||
338 | * @head: the head for your list. | ||
339 | * @member: the name of the list_struct within the struct. | ||
340 | */ | ||
341 | #define list_for_each_entry(pos, head, member) \ | ||
342 | for (pos = list_entry((head)->next, typeof(*pos), member); \ | ||
343 | &pos->member != (head); \ | ||
344 | pos = list_entry(pos->member.next, typeof(*pos), member)) | ||
345 | |||
346 | /** | ||
347 | * list_for_each_entry_reverse - iterate backwards over list of given type. | ||
348 | * @pos: the type * to use as a loop cursor. | ||
349 | * @head: the head for your list. | ||
350 | * @member: the name of the list_struct within the struct. | ||
351 | */ | ||
352 | #define list_for_each_entry_reverse(pos, head, member) \ | ||
353 | for (pos = list_entry((head)->prev, typeof(*pos), member); \ | ||
354 | &pos->member != (head); \ | ||
355 | pos = list_entry(pos->member.prev, typeof(*pos), member)) | ||
356 | |||
357 | /** | ||
358 | * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue | ||
359 | * @pos: the type * to use as a start point | ||
360 | * @head: the head of the list | ||
361 | * @member: the name of the list_struct within the struct. | ||
362 | * | ||
363 | * Prepares a pos entry for use as a start point in list_for_each_entry_continue. | ||
364 | */ | ||
365 | #define list_prepare_entry(pos, head, member) \ | ||
366 | ((pos) ? : list_entry(head, typeof(*pos), member)) | ||
367 | |||
368 | /** | ||
369 | * list_for_each_entry_continue - continue iteration over list of given type | ||
370 | * @pos: the type * to use as a loop cursor. | ||
371 | * @head: the head for your list. | ||
372 | * @member: the name of the list_struct within the struct. | ||
373 | * | ||
374 | * Continue to iterate over list of given type, continuing after | ||
375 | * the current position. | ||
376 | */ | ||
377 | #define list_for_each_entry_continue(pos, head, member) \ | ||
378 | for (pos = list_entry(pos->member.next, typeof(*pos), member); \ | ||
379 | &pos->member != (head); \ | ||
380 | pos = list_entry(pos->member.next, typeof(*pos), member)) | ||
381 | |||
382 | /** | ||
383 | * list_for_each_entry_from - iterate over list of given type from the current point | ||
384 | * @pos: the type * to use as a loop cursor. | ||
385 | * @head: the head for your list. | ||
386 | * @member: the name of the list_struct within the struct. | ||
387 | * | ||
388 | * Iterate over list of given type, continuing from current position. | ||
389 | */ | ||
390 | #define list_for_each_entry_from(pos, head, member) \ | ||
391 | for (; &pos->member != (head); \ | ||
392 | pos = list_entry(pos->member.next, typeof(*pos), member)) | ||
393 | |||
394 | /** | ||
395 | * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry | ||
396 | * @pos: the type * to use as a loop cursor. | ||
397 | * @n: another type * to use as temporary storage | ||
398 | * @head: the head for your list. | ||
399 | * @member: the name of the list_struct within the struct. | ||
400 | */ | ||
401 | #define list_for_each_entry_safe(pos, n, head, member) \ | ||
402 | for (pos = list_entry((head)->next, typeof(*pos), member), \ | ||
403 | n = list_entry(pos->member.next, typeof(*pos), member); \ | ||
404 | &pos->member != (head); \ | ||
405 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) | ||
406 | |||
407 | /** | ||
408 | * list_for_each_entry_safe_continue | ||
409 | * @pos: the type * to use as a loop cursor. | ||
410 | * @n: another type * to use as temporary storage | ||
411 | * @head: the head for your list. | ||
412 | * @member: the name of the list_struct within the struct. | ||
413 | * | ||
414 | * Iterate over list of given type, continuing after current point, | ||
415 | * safe against removal of list entry. | ||
416 | */ | ||
417 | #define list_for_each_entry_safe_continue(pos, n, head, member) \ | ||
418 | for (pos = list_entry(pos->member.next, typeof(*pos), member), \ | ||
419 | n = list_entry(pos->member.next, typeof(*pos), member); \ | ||
420 | &pos->member != (head); \ | ||
421 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) | ||
422 | |||
423 | /** | ||
424 | * list_for_each_entry_safe_from | ||
425 | * @pos: the type * to use as a loop cursor. | ||
426 | * @n: another type * to use as temporary storage | ||
427 | * @head: the head for your list. | ||
428 | * @member: the name of the list_struct within the struct. | ||
429 | * | ||
430 | * Iterate over list of given type from current point, safe against | ||
431 | * removal of list entry. | ||
432 | */ | ||
433 | #define list_for_each_entry_safe_from(pos, n, head, member) \ | ||
434 | for (n = list_entry(pos->member.next, typeof(*pos), member); \ | ||
435 | &pos->member != (head); \ | ||
436 | pos = n, n = list_entry(n->member.next, typeof(*n), member)) | ||
437 | |||
438 | /** | ||
439 | * list_for_each_entry_safe_reverse | ||
440 | * @pos: the type * to use as a loop cursor. | ||
441 | * @n: another type * to use as temporary storage | ||
442 | * @head: the head for your list. | ||
443 | * @member: the name of the list_struct within the struct. | ||
444 | * | ||
445 | * Iterate backwards over list of given type, safe against removal | ||
446 | * of list entry. | ||
447 | */ | ||
448 | #define list_for_each_entry_safe_reverse(pos, n, head, member) \ | ||
449 | for (pos = list_entry((head)->prev, typeof(*pos), member), \ | ||
450 | n = list_entry(pos->member.prev, typeof(*pos), member); \ | ||
451 | &pos->member != (head); \ | ||
452 | pos = n, n = list_entry(n->member.prev, typeof(*n), member)) | ||
453 | |||
454 | /* | ||
455 | * Double linked lists with a single pointer list head. | ||
456 | * Mostly useful for hash tables where the two pointer list head is | ||
457 | * too wasteful. | ||
458 | * You lose the ability to access the tail in O(1). | ||
459 | */ | ||
460 | |||
461 | struct hlist_head { | ||
462 | struct hlist_node *first; | ||
463 | }; | ||
464 | |||
465 | struct hlist_node { | ||
466 | struct hlist_node *next, **pprev; | ||
467 | }; | ||
468 | |||
469 | #define HLIST_HEAD_INIT { .first = NULL } | ||
470 | #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } | ||
471 | #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) | ||
472 | static inline void INIT_HLIST_NODE(struct hlist_node *h) | ||
473 | { | ||
474 | h->next = NULL; | ||
475 | h->pprev = NULL; | ||
476 | } | ||
477 | |||
478 | static inline int hlist_unhashed(const struct hlist_node *h) | ||
479 | { | ||
480 | return !h->pprev; | ||
481 | } | ||
482 | |||
483 | static inline int hlist_empty(const struct hlist_head *h) | ||
484 | { | ||
485 | return !h->first; | ||
486 | } | ||
487 | |||
488 | static inline void __hlist_del(struct hlist_node *n) | ||
489 | { | ||
490 | struct hlist_node *next = n->next; | ||
491 | struct hlist_node **pprev = n->pprev; | ||
492 | *pprev = next; | ||
493 | if (next) | ||
494 | next->pprev = pprev; | ||
495 | } | ||
496 | |||
497 | static inline void hlist_del(struct hlist_node *n) | ||
498 | { | ||
499 | __hlist_del(n); | ||
500 | n->next = LIST_POISON1; | ||
501 | n->pprev = LIST_POISON2; | ||
502 | } | ||
503 | |||
504 | static inline void hlist_del_init(struct hlist_node *n) | ||
505 | { | ||
506 | if (!hlist_unhashed(n)) { | ||
507 | __hlist_del(n); | ||
508 | INIT_HLIST_NODE(n); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) | ||
513 | { | ||
514 | struct hlist_node *first = h->first; | ||
515 | n->next = first; | ||
516 | if (first) | ||
517 | first->pprev = &n->next; | ||
518 | h->first = n; | ||
519 | n->pprev = &h->first; | ||
520 | } | ||
521 | |||
522 | /* next must be != NULL */ | ||
523 | static inline void hlist_add_before(struct hlist_node *n, | ||
524 | struct hlist_node *next) | ||
525 | { | ||
526 | n->pprev = next->pprev; | ||
527 | n->next = next; | ||
528 | next->pprev = &n->next; | ||
529 | *(n->pprev) = n; | ||
530 | } | ||
531 | |||
532 | static inline void hlist_add_after(struct hlist_node *n, | ||
533 | struct hlist_node *next) | ||
534 | { | ||
535 | next->next = n->next; | ||
536 | n->next = next; | ||
537 | next->pprev = &n->next; | ||
538 | |||
539 | if(next->next) | ||
540 | next->next->pprev = &next->next; | ||
541 | } | ||
542 | |||
543 | #define hlist_entry(ptr, type, member) container_of(ptr,type,member) | ||
544 | |||
545 | #define hlist_for_each(pos, head) \ | ||
546 | for (pos = (head)->first; pos; \ | ||
547 | pos = pos->next) | ||
548 | |||
549 | #define hlist_for_each_safe(pos, n, head) \ | ||
550 | for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ | ||
551 | pos = n) | ||
552 | |||
553 | /** | ||
554 | * hlist_for_each_entry - iterate over list of given type | ||
555 | * @tpos: the type * to use as a loop cursor. | ||
556 | * @pos: the &struct hlist_node to use as a loop cursor. | ||
557 | * @head: the head for your list. | ||
558 | * @member: the name of the hlist_node within the struct. | ||
559 | */ | ||
560 | #define hlist_for_each_entry(tpos, pos, head, member) \ | ||
561 | for (pos = (head)->first; \ | ||
562 | pos && \ | ||
563 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ | ||
564 | pos = pos->next) | ||
565 | |||
566 | /** | ||
567 | * hlist_for_each_entry_continue - iterate over a hlist continuing after current point | ||
568 | * @tpos: the type * to use as a loop cursor. | ||
569 | * @pos: the &struct hlist_node to use as a loop cursor. | ||
570 | * @member: the name of the hlist_node within the struct. | ||
571 | */ | ||
572 | #define hlist_for_each_entry_continue(tpos, pos, member) \ | ||
573 | for (pos = (pos)->next; \ | ||
574 | pos && \ | ||
575 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ | ||
576 | pos = pos->next) | ||
577 | |||
578 | /** | ||
579 | * hlist_for_each_entry_from - iterate over a hlist continuing from current point | ||
580 | * @tpos: the type * to use as a loop cursor. | ||
581 | * @pos: the &struct hlist_node to use as a loop cursor. | ||
582 | * @member: the name of the hlist_node within the struct. | ||
583 | */ | ||
584 | #define hlist_for_each_entry_from(tpos, pos, member) \ | ||
585 | for (; pos && \ | ||
586 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ | ||
587 | pos = pos->next) | ||
588 | |||
589 | /** | ||
590 | * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry | ||
591 | * @tpos: the type * to use as a loop cursor. | ||
592 | * @pos: the &struct hlist_node to use as a loop cursor. | ||
593 | * @n: another &struct hlist_node to use as temporary storage | ||
594 | * @head: the head for your list. | ||
595 | * @member: the name of the hlist_node within the struct. | ||
596 | */ | ||
597 | #define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ | ||
598 | for (pos = (head)->first; \ | ||
599 | pos && ({ n = pos->next; 1; }) && \ | ||
600 | ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ | ||
601 | pos = n) | ||
602 | |||
603 | #endif | ||
diff --git a/tools/perf/util/module.c b/tools/perf/util/module.c new file mode 100644 index 000000000000..ddabe925d65d --- /dev/null +++ b/tools/perf/util/module.c | |||
@@ -0,0 +1,509 @@ | |||
1 | #include "util.h" | ||
2 | #include "../perf.h" | ||
3 | #include "string.h" | ||
4 | #include "module.h" | ||
5 | |||
6 | #include <libelf.h> | ||
7 | #include <gelf.h> | ||
8 | #include <elf.h> | ||
9 | #include <dirent.h> | ||
10 | #include <sys/utsname.h> | ||
11 | |||
12 | static unsigned int crc32(const char *p, unsigned int len) | ||
13 | { | ||
14 | int i; | ||
15 | unsigned int crc = 0; | ||
16 | |||
17 | while (len--) { | ||
18 | crc ^= *p++; | ||
19 | for (i = 0; i < 8; i++) | ||
20 | crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); | ||
21 | } | ||
22 | return crc; | ||
23 | } | ||
24 | |||
25 | /* module section methods */ | ||
26 | |||
27 | struct sec_dso *sec_dso__new_dso(const char *name) | ||
28 | { | ||
29 | struct sec_dso *self = malloc(sizeof(*self) + strlen(name) + 1); | ||
30 | |||
31 | if (self != NULL) { | ||
32 | strcpy(self->name, name); | ||
33 | self->secs = RB_ROOT; | ||
34 | self->find_section = sec_dso__find_section; | ||
35 | } | ||
36 | |||
37 | return self; | ||
38 | } | ||
39 | |||
40 | static void sec_dso__delete_section(struct section *self) | ||
41 | { | ||
42 | free(((void *)self)); | ||
43 | } | ||
44 | |||
45 | void sec_dso__delete_sections(struct sec_dso *self) | ||
46 | { | ||
47 | struct section *pos; | ||
48 | struct rb_node *next = rb_first(&self->secs); | ||
49 | |||
50 | while (next) { | ||
51 | pos = rb_entry(next, struct section, rb_node); | ||
52 | next = rb_next(&pos->rb_node); | ||
53 | rb_erase(&pos->rb_node, &self->secs); | ||
54 | sec_dso__delete_section(pos); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | void sec_dso__delete_self(struct sec_dso *self) | ||
59 | { | ||
60 | sec_dso__delete_sections(self); | ||
61 | free(self); | ||
62 | } | ||
63 | |||
64 | static void sec_dso__insert_section(struct sec_dso *self, struct section *sec) | ||
65 | { | ||
66 | struct rb_node **p = &self->secs.rb_node; | ||
67 | struct rb_node *parent = NULL; | ||
68 | const u64 hash = sec->hash; | ||
69 | struct section *s; | ||
70 | |||
71 | while (*p != NULL) { | ||
72 | parent = *p; | ||
73 | s = rb_entry(parent, struct section, rb_node); | ||
74 | if (hash < s->hash) | ||
75 | p = &(*p)->rb_left; | ||
76 | else | ||
77 | p = &(*p)->rb_right; | ||
78 | } | ||
79 | rb_link_node(&sec->rb_node, parent, p); | ||
80 | rb_insert_color(&sec->rb_node, &self->secs); | ||
81 | } | ||
82 | |||
83 | struct section *sec_dso__find_section(struct sec_dso *self, const char *name) | ||
84 | { | ||
85 | struct rb_node *n; | ||
86 | u64 hash; | ||
87 | int len; | ||
88 | |||
89 | if (self == NULL) | ||
90 | return NULL; | ||
91 | |||
92 | len = strlen(name); | ||
93 | hash = crc32(name, len); | ||
94 | |||
95 | n = self->secs.rb_node; | ||
96 | |||
97 | while (n) { | ||
98 | struct section *s = rb_entry(n, struct section, rb_node); | ||
99 | |||
100 | if (hash < s->hash) | ||
101 | n = n->rb_left; | ||
102 | else if (hash > s->hash) | ||
103 | n = n->rb_right; | ||
104 | else { | ||
105 | if (!strcmp(name, s->name)) | ||
106 | return s; | ||
107 | else | ||
108 | n = rb_next(&s->rb_node); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | return NULL; | ||
113 | } | ||
114 | |||
115 | static size_t sec_dso__fprintf_section(struct section *self, FILE *fp) | ||
116 | { | ||
117 | return fprintf(fp, "name:%s vma:%llx path:%s\n", | ||
118 | self->name, self->vma, self->path); | ||
119 | } | ||
120 | |||
121 | size_t sec_dso__fprintf(struct sec_dso *self, FILE *fp) | ||
122 | { | ||
123 | size_t ret = fprintf(fp, "dso: %s\n", self->name); | ||
124 | |||
125 | struct rb_node *nd; | ||
126 | for (nd = rb_first(&self->secs); nd; nd = rb_next(nd)) { | ||
127 | struct section *pos = rb_entry(nd, struct section, rb_node); | ||
128 | ret += sec_dso__fprintf_section(pos, fp); | ||
129 | } | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static struct section *section__new(const char *name, const char *path) | ||
135 | { | ||
136 | struct section *self = calloc(1, sizeof(*self)); | ||
137 | |||
138 | if (!self) | ||
139 | goto out_failure; | ||
140 | |||
141 | self->name = calloc(1, strlen(name) + 1); | ||
142 | if (!self->name) | ||
143 | goto out_failure; | ||
144 | |||
145 | self->path = calloc(1, strlen(path) + 1); | ||
146 | if (!self->path) | ||
147 | goto out_failure; | ||
148 | |||
149 | strcpy(self->name, name); | ||
150 | strcpy(self->path, path); | ||
151 | self->hash = crc32(self->name, strlen(name)); | ||
152 | |||
153 | return self; | ||
154 | |||
155 | out_failure: | ||
156 | if (self) { | ||
157 | if (self->name) | ||
158 | free(self->name); | ||
159 | if (self->path) | ||
160 | free(self->path); | ||
161 | free(self); | ||
162 | } | ||
163 | |||
164 | return NULL; | ||
165 | } | ||
166 | |||
167 | /* module methods */ | ||
168 | |||
169 | struct mod_dso *mod_dso__new_dso(const char *name) | ||
170 | { | ||
171 | struct mod_dso *self = malloc(sizeof(*self) + strlen(name) + 1); | ||
172 | |||
173 | if (self != NULL) { | ||
174 | strcpy(self->name, name); | ||
175 | self->mods = RB_ROOT; | ||
176 | self->find_module = mod_dso__find_module; | ||
177 | } | ||
178 | |||
179 | return self; | ||
180 | } | ||
181 | |||
182 | static void mod_dso__delete_module(struct module *self) | ||
183 | { | ||
184 | free(((void *)self)); | ||
185 | } | ||
186 | |||
187 | void mod_dso__delete_modules(struct mod_dso *self) | ||
188 | { | ||
189 | struct module *pos; | ||
190 | struct rb_node *next = rb_first(&self->mods); | ||
191 | |||
192 | while (next) { | ||
193 | pos = rb_entry(next, struct module, rb_node); | ||
194 | next = rb_next(&pos->rb_node); | ||
195 | rb_erase(&pos->rb_node, &self->mods); | ||
196 | mod_dso__delete_module(pos); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | void mod_dso__delete_self(struct mod_dso *self) | ||
201 | { | ||
202 | mod_dso__delete_modules(self); | ||
203 | free(self); | ||
204 | } | ||
205 | |||
206 | static void mod_dso__insert_module(struct mod_dso *self, struct module *mod) | ||
207 | { | ||
208 | struct rb_node **p = &self->mods.rb_node; | ||
209 | struct rb_node *parent = NULL; | ||
210 | const u64 hash = mod->hash; | ||
211 | struct module *m; | ||
212 | |||
213 | while (*p != NULL) { | ||
214 | parent = *p; | ||
215 | m = rb_entry(parent, struct module, rb_node); | ||
216 | if (hash < m->hash) | ||
217 | p = &(*p)->rb_left; | ||
218 | else | ||
219 | p = &(*p)->rb_right; | ||
220 | } | ||
221 | rb_link_node(&mod->rb_node, parent, p); | ||
222 | rb_insert_color(&mod->rb_node, &self->mods); | ||
223 | } | ||
224 | |||
225 | struct module *mod_dso__find_module(struct mod_dso *self, const char *name) | ||
226 | { | ||
227 | struct rb_node *n; | ||
228 | u64 hash; | ||
229 | int len; | ||
230 | |||
231 | if (self == NULL) | ||
232 | return NULL; | ||
233 | |||
234 | len = strlen(name); | ||
235 | hash = crc32(name, len); | ||
236 | |||
237 | n = self->mods.rb_node; | ||
238 | |||
239 | while (n) { | ||
240 | struct module *m = rb_entry(n, struct module, rb_node); | ||
241 | |||
242 | if (hash < m->hash) | ||
243 | n = n->rb_left; | ||
244 | else if (hash > m->hash) | ||
245 | n = n->rb_right; | ||
246 | else { | ||
247 | if (!strcmp(name, m->name)) | ||
248 | return m; | ||
249 | else | ||
250 | n = rb_next(&m->rb_node); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | return NULL; | ||
255 | } | ||
256 | |||
257 | static size_t mod_dso__fprintf_module(struct module *self, FILE *fp) | ||
258 | { | ||
259 | return fprintf(fp, "name:%s path:%s\n", self->name, self->path); | ||
260 | } | ||
261 | |||
262 | size_t mod_dso__fprintf(struct mod_dso *self, FILE *fp) | ||
263 | { | ||
264 | struct rb_node *nd; | ||
265 | size_t ret; | ||
266 | |||
267 | ret = fprintf(fp, "dso: %s\n", self->name); | ||
268 | |||
269 | for (nd = rb_first(&self->mods); nd; nd = rb_next(nd)) { | ||
270 | struct module *pos = rb_entry(nd, struct module, rb_node); | ||
271 | |||
272 | ret += mod_dso__fprintf_module(pos, fp); | ||
273 | } | ||
274 | |||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | static struct module *module__new(const char *name, const char *path) | ||
279 | { | ||
280 | struct module *self = calloc(1, sizeof(*self)); | ||
281 | |||
282 | if (!self) | ||
283 | goto out_failure; | ||
284 | |||
285 | self->name = calloc(1, strlen(name) + 1); | ||
286 | if (!self->name) | ||
287 | goto out_failure; | ||
288 | |||
289 | self->path = calloc(1, strlen(path) + 1); | ||
290 | if (!self->path) | ||
291 | goto out_failure; | ||
292 | |||
293 | strcpy(self->name, name); | ||
294 | strcpy(self->path, path); | ||
295 | self->hash = crc32(self->name, strlen(name)); | ||
296 | |||
297 | return self; | ||
298 | |||
299 | out_failure: | ||
300 | if (self) { | ||
301 | if (self->name) | ||
302 | free(self->name); | ||
303 | if (self->path) | ||
304 | free(self->path); | ||
305 | free(self); | ||
306 | } | ||
307 | |||
308 | return NULL; | ||
309 | } | ||
310 | |||
311 | static int mod_dso__load_sections(struct module *mod) | ||
312 | { | ||
313 | int count = 0, path_len; | ||
314 | struct dirent *entry; | ||
315 | char *line = NULL; | ||
316 | char *dir_path; | ||
317 | DIR *dir; | ||
318 | size_t n; | ||
319 | |||
320 | path_len = strlen("/sys/module/"); | ||
321 | path_len += strlen(mod->name); | ||
322 | path_len += strlen("/sections/"); | ||
323 | |||
324 | dir_path = calloc(1, path_len + 1); | ||
325 | if (dir_path == NULL) | ||
326 | goto out_failure; | ||
327 | |||
328 | strcat(dir_path, "/sys/module/"); | ||
329 | strcat(dir_path, mod->name); | ||
330 | strcat(dir_path, "/sections/"); | ||
331 | |||
332 | dir = opendir(dir_path); | ||
333 | if (dir == NULL) | ||
334 | goto out_free; | ||
335 | |||
336 | while ((entry = readdir(dir))) { | ||
337 | struct section *section; | ||
338 | char *path, *vma; | ||
339 | int line_len; | ||
340 | FILE *file; | ||
341 | |||
342 | if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name)) | ||
343 | continue; | ||
344 | |||
345 | path = calloc(1, path_len + strlen(entry->d_name) + 1); | ||
346 | if (path == NULL) | ||
347 | break; | ||
348 | strcat(path, dir_path); | ||
349 | strcat(path, entry->d_name); | ||
350 | |||
351 | file = fopen(path, "r"); | ||
352 | if (file == NULL) { | ||
353 | free(path); | ||
354 | break; | ||
355 | } | ||
356 | |||
357 | line_len = getline(&line, &n, file); | ||
358 | if (line_len < 0) { | ||
359 | free(path); | ||
360 | fclose(file); | ||
361 | break; | ||
362 | } | ||
363 | |||
364 | if (!line) { | ||
365 | free(path); | ||
366 | fclose(file); | ||
367 | break; | ||
368 | } | ||
369 | |||
370 | line[--line_len] = '\0'; /* \n */ | ||
371 | |||
372 | vma = strstr(line, "0x"); | ||
373 | if (!vma) { | ||
374 | free(path); | ||
375 | fclose(file); | ||
376 | break; | ||
377 | } | ||
378 | vma += 2; | ||
379 | |||
380 | section = section__new(entry->d_name, path); | ||
381 | if (!section) { | ||
382 | fprintf(stderr, "load_sections: allocation error\n"); | ||
383 | free(path); | ||
384 | fclose(file); | ||
385 | break; | ||
386 | } | ||
387 | |||
388 | hex2u64(vma, §ion->vma); | ||
389 | sec_dso__insert_section(mod->sections, section); | ||
390 | |||
391 | free(path); | ||
392 | fclose(file); | ||
393 | count++; | ||
394 | } | ||
395 | |||
396 | closedir(dir); | ||
397 | free(line); | ||
398 | free(dir_path); | ||
399 | |||
400 | return count; | ||
401 | |||
402 | out_free: | ||
403 | free(dir_path); | ||
404 | |||
405 | out_failure: | ||
406 | return count; | ||
407 | } | ||
408 | |||
409 | static int mod_dso__load_module_paths(struct mod_dso *self) | ||
410 | { | ||
411 | struct utsname uts; | ||
412 | int count = 0, len; | ||
413 | char *line = NULL; | ||
414 | FILE *file; | ||
415 | char *path; | ||
416 | size_t n; | ||
417 | |||
418 | if (uname(&uts) < 0) | ||
419 | goto out_failure; | ||
420 | |||
421 | len = strlen("/lib/modules/"); | ||
422 | len += strlen(uts.release); | ||
423 | len += strlen("/modules.dep"); | ||
424 | |||
425 | path = calloc(1, len); | ||
426 | if (path == NULL) | ||
427 | goto out_failure; | ||
428 | |||
429 | strcat(path, "/lib/modules/"); | ||
430 | strcat(path, uts.release); | ||
431 | strcat(path, "/modules.dep"); | ||
432 | |||
433 | file = fopen(path, "r"); | ||
434 | free(path); | ||
435 | if (file == NULL) | ||
436 | goto out_failure; | ||
437 | |||
438 | while (!feof(file)) { | ||
439 | char *path, *name, *tmp; | ||
440 | struct module *module; | ||
441 | int line_len, len; | ||
442 | |||
443 | line_len = getline(&line, &n, file); | ||
444 | if (line_len < 0) | ||
445 | break; | ||
446 | |||
447 | if (!line) | ||
448 | goto out_failure; | ||
449 | |||
450 | line[--line_len] = '\0'; /* \n */ | ||
451 | |||
452 | path = strtok(line, ":"); | ||
453 | if (!path) | ||
454 | goto out_failure; | ||
455 | |||
456 | name = strdup(path); | ||
457 | name = strtok(name, "/"); | ||
458 | |||
459 | tmp = name; | ||
460 | |||
461 | while (tmp) { | ||
462 | tmp = strtok(NULL, "/"); | ||
463 | if (tmp) | ||
464 | name = tmp; | ||
465 | } | ||
466 | name = strsep(&name, "."); | ||
467 | |||
468 | /* Quirk: replace '-' with '_' in sound modules */ | ||
469 | for (len = strlen(name); len; len--) { | ||
470 | if (*(name+len) == '-') | ||
471 | *(name+len) = '_'; | ||
472 | } | ||
473 | |||
474 | module = module__new(name, path); | ||
475 | if (!module) { | ||
476 | fprintf(stderr, "load_module_paths: allocation error\n"); | ||
477 | goto out_failure; | ||
478 | } | ||
479 | mod_dso__insert_module(self, module); | ||
480 | |||
481 | module->sections = sec_dso__new_dso("sections"); | ||
482 | if (!module->sections) { | ||
483 | fprintf(stderr, "load_module_paths: allocation error\n"); | ||
484 | goto out_failure; | ||
485 | } | ||
486 | |||
487 | module->active = mod_dso__load_sections(module); | ||
488 | |||
489 | if (module->active > 0) | ||
490 | count++; | ||
491 | } | ||
492 | |||
493 | free(line); | ||
494 | fclose(file); | ||
495 | |||
496 | return count; | ||
497 | |||
498 | out_failure: | ||
499 | return -1; | ||
500 | } | ||
501 | |||
502 | int mod_dso__load_modules(struct mod_dso *dso) | ||
503 | { | ||
504 | int err; | ||
505 | |||
506 | err = mod_dso__load_module_paths(dso); | ||
507 | |||
508 | return err; | ||
509 | } | ||
diff --git a/tools/perf/util/module.h b/tools/perf/util/module.h new file mode 100644 index 000000000000..8a592ef641ca --- /dev/null +++ b/tools/perf/util/module.h | |||
@@ -0,0 +1,53 @@ | |||
1 | #ifndef _PERF_MODULE_ | ||
2 | #define _PERF_MODULE_ 1 | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | #include "../types.h" | ||
6 | #include <linux/list.h> | ||
7 | #include <linux/rbtree.h> | ||
8 | |||
9 | struct section { | ||
10 | struct rb_node rb_node; | ||
11 | u64 hash; | ||
12 | u64 vma; | ||
13 | char *name; | ||
14 | char *path; | ||
15 | }; | ||
16 | |||
17 | struct sec_dso { | ||
18 | struct list_head node; | ||
19 | struct rb_root secs; | ||
20 | struct section *(*find_section)(struct sec_dso *, const char *name); | ||
21 | char name[0]; | ||
22 | }; | ||
23 | |||
24 | struct module { | ||
25 | struct rb_node rb_node; | ||
26 | u64 hash; | ||
27 | char *name; | ||
28 | char *path; | ||
29 | struct sec_dso *sections; | ||
30 | int active; | ||
31 | }; | ||
32 | |||
33 | struct mod_dso { | ||
34 | struct list_head node; | ||
35 | struct rb_root mods; | ||
36 | struct module *(*find_module)(struct mod_dso *, const char *name); | ||
37 | char name[0]; | ||
38 | }; | ||
39 | |||
40 | struct sec_dso *sec_dso__new_dso(const char *name); | ||
41 | void sec_dso__delete_sections(struct sec_dso *self); | ||
42 | void sec_dso__delete_self(struct sec_dso *self); | ||
43 | size_t sec_dso__fprintf(struct sec_dso *self, FILE *fp); | ||
44 | struct section *sec_dso__find_section(struct sec_dso *self, const char *name); | ||
45 | |||
46 | struct mod_dso *mod_dso__new_dso(const char *name); | ||
47 | void mod_dso__delete_modules(struct mod_dso *self); | ||
48 | void mod_dso__delete_self(struct mod_dso *self); | ||
49 | size_t mod_dso__fprintf(struct mod_dso *self, FILE *fp); | ||
50 | struct module *mod_dso__find_module(struct mod_dso *self, const char *name); | ||
51 | int mod_dso__load_modules(struct mod_dso *dso); | ||
52 | |||
53 | #endif /* _PERF_MODULE_ */ | ||
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 4d042f104cdc..5184959e0615 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -184,16 +184,20 @@ char *event_name(int counter) | |||
184 | return "unknown"; | 184 | return "unknown"; |
185 | } | 185 | } |
186 | 186 | ||
187 | static int parse_aliases(const char *str, char *names[][MAX_ALIASES], int size) | 187 | static int parse_aliases(const char **str, char *names[][MAX_ALIASES], int size) |
188 | { | 188 | { |
189 | int i, j; | 189 | int i, j; |
190 | int n, longest = -1; | ||
190 | 191 | ||
191 | for (i = 0; i < size; i++) { | 192 | for (i = 0; i < size; i++) { |
192 | for (j = 0; j < MAX_ALIASES; j++) { | 193 | for (j = 0; j < MAX_ALIASES && names[i][j]; j++) { |
193 | if (!names[i][j]) | 194 | n = strlen(names[i][j]); |
194 | break; | 195 | if (n > longest && !strncasecmp(*str, names[i][j], n)) |
195 | if (strcasestr(str, names[i][j])) | 196 | longest = n; |
196 | return i; | 197 | } |
198 | if (longest > 0) { | ||
199 | *str += longest; | ||
200 | return i; | ||
197 | } | 201 | } |
198 | } | 202 | } |
199 | 203 | ||
@@ -201,30 +205,53 @@ static int parse_aliases(const char *str, char *names[][MAX_ALIASES], int size) | |||
201 | } | 205 | } |
202 | 206 | ||
203 | static int | 207 | static int |
204 | parse_generic_hw_symbols(const char *str, struct perf_counter_attr *attr) | 208 | parse_generic_hw_event(const char **str, struct perf_counter_attr *attr) |
205 | { | 209 | { |
206 | int cache_type = -1, cache_op = 0, cache_result = 0; | 210 | const char *s = *str; |
211 | int cache_type = -1, cache_op = -1, cache_result = -1; | ||
207 | 212 | ||
208 | cache_type = parse_aliases(str, hw_cache, PERF_COUNT_HW_CACHE_MAX); | 213 | cache_type = parse_aliases(&s, hw_cache, PERF_COUNT_HW_CACHE_MAX); |
209 | /* | 214 | /* |
210 | * No fallback - if we cannot get a clear cache type | 215 | * No fallback - if we cannot get a clear cache type |
211 | * then bail out: | 216 | * then bail out: |
212 | */ | 217 | */ |
213 | if (cache_type == -1) | 218 | if (cache_type == -1) |
214 | return -EINVAL; | 219 | return 0; |
220 | |||
221 | while ((cache_op == -1 || cache_result == -1) && *s == '-') { | ||
222 | ++s; | ||
223 | |||
224 | if (cache_op == -1) { | ||
225 | cache_op = parse_aliases(&s, hw_cache_op, | ||
226 | PERF_COUNT_HW_CACHE_OP_MAX); | ||
227 | if (cache_op >= 0) { | ||
228 | if (!is_cache_op_valid(cache_type, cache_op)) | ||
229 | return 0; | ||
230 | continue; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | if (cache_result == -1) { | ||
235 | cache_result = parse_aliases(&s, hw_cache_result, | ||
236 | PERF_COUNT_HW_CACHE_RESULT_MAX); | ||
237 | if (cache_result >= 0) | ||
238 | continue; | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Can't parse this as a cache op or result, so back up | ||
243 | * to the '-'. | ||
244 | */ | ||
245 | --s; | ||
246 | break; | ||
247 | } | ||
215 | 248 | ||
216 | cache_op = parse_aliases(str, hw_cache_op, PERF_COUNT_HW_CACHE_OP_MAX); | ||
217 | /* | 249 | /* |
218 | * Fall back to reads: | 250 | * Fall back to reads: |
219 | */ | 251 | */ |
220 | if (cache_op == -1) | 252 | if (cache_op == -1) |
221 | cache_op = PERF_COUNT_HW_CACHE_OP_READ; | 253 | cache_op = PERF_COUNT_HW_CACHE_OP_READ; |
222 | 254 | ||
223 | if (!is_cache_op_valid(cache_type, cache_op)) | ||
224 | return -EINVAL; | ||
225 | |||
226 | cache_result = parse_aliases(str, hw_cache_result, | ||
227 | PERF_COUNT_HW_CACHE_RESULT_MAX); | ||
228 | /* | 255 | /* |
229 | * Fall back to accesses: | 256 | * Fall back to accesses: |
230 | */ | 257 | */ |
@@ -234,93 +261,154 @@ parse_generic_hw_symbols(const char *str, struct perf_counter_attr *attr) | |||
234 | attr->config = cache_type | (cache_op << 8) | (cache_result << 16); | 261 | attr->config = cache_type | (cache_op << 8) | (cache_result << 16); |
235 | attr->type = PERF_TYPE_HW_CACHE; | 262 | attr->type = PERF_TYPE_HW_CACHE; |
236 | 263 | ||
237 | return 0; | 264 | *str = s; |
265 | return 1; | ||
238 | } | 266 | } |
239 | 267 | ||
240 | static int check_events(const char *str, unsigned int i) | 268 | static int check_events(const char *str, unsigned int i) |
241 | { | 269 | { |
242 | if (!strncmp(str, event_symbols[i].symbol, | 270 | int n; |
243 | strlen(event_symbols[i].symbol))) | ||
244 | return 1; | ||
245 | 271 | ||
246 | if (strlen(event_symbols[i].alias)) | 272 | n = strlen(event_symbols[i].symbol); |
247 | if (!strncmp(str, event_symbols[i].alias, | 273 | if (!strncmp(str, event_symbols[i].symbol, n)) |
248 | strlen(event_symbols[i].alias))) | 274 | return n; |
249 | return 1; | 275 | |
276 | n = strlen(event_symbols[i].alias); | ||
277 | if (n) | ||
278 | if (!strncmp(str, event_symbols[i].alias, n)) | ||
279 | return n; | ||
250 | return 0; | 280 | return 0; |
251 | } | 281 | } |
252 | 282 | ||
253 | /* | 283 | static int |
254 | * Each event can have multiple symbolic names. | 284 | parse_symbolic_event(const char **strp, struct perf_counter_attr *attr) |
255 | * Symbolic names are (almost) exactly matched. | ||
256 | */ | ||
257 | static int parse_event_symbols(const char *str, struct perf_counter_attr *attr) | ||
258 | { | 285 | { |
259 | u64 config, id; | 286 | const char *str = *strp; |
260 | int type; | ||
261 | unsigned int i; | 287 | unsigned int i; |
262 | const char *sep, *pstr; | 288 | int n; |
263 | 289 | ||
264 | if (str[0] == 'r' && hex2u64(str + 1, &config) > 0) { | 290 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { |
265 | attr->type = PERF_TYPE_RAW; | 291 | n = check_events(str, i); |
266 | attr->config = config; | 292 | if (n > 0) { |
293 | attr->type = event_symbols[i].type; | ||
294 | attr->config = event_symbols[i].config; | ||
295 | *strp = str + n; | ||
296 | return 1; | ||
297 | } | ||
298 | } | ||
299 | return 0; | ||
300 | } | ||
267 | 301 | ||
302 | static int parse_raw_event(const char **strp, struct perf_counter_attr *attr) | ||
303 | { | ||
304 | const char *str = *strp; | ||
305 | u64 config; | ||
306 | int n; | ||
307 | |||
308 | if (*str != 'r') | ||
268 | return 0; | 309 | return 0; |
310 | n = hex2u64(str + 1, &config); | ||
311 | if (n > 0) { | ||
312 | *strp = str + n + 1; | ||
313 | attr->type = PERF_TYPE_RAW; | ||
314 | attr->config = config; | ||
315 | return 1; | ||
269 | } | 316 | } |
317 | return 0; | ||
318 | } | ||
270 | 319 | ||
271 | pstr = str; | 320 | static int |
272 | sep = strchr(pstr, ':'); | 321 | parse_numeric_event(const char **strp, struct perf_counter_attr *attr) |
273 | if (sep) { | 322 | { |
274 | type = atoi(pstr); | 323 | const char *str = *strp; |
275 | pstr = sep + 1; | 324 | char *endp; |
276 | id = atoi(pstr); | 325 | unsigned long type; |
277 | sep = strchr(pstr, ':'); | 326 | u64 config; |
278 | if (sep) { | 327 | |
279 | pstr = sep + 1; | 328 | type = strtoul(str, &endp, 0); |
280 | if (strchr(pstr, 'k')) | 329 | if (endp > str && type < PERF_TYPE_MAX && *endp == ':') { |
281 | attr->exclude_user = 1; | 330 | str = endp + 1; |
282 | if (strchr(pstr, 'u')) | 331 | config = strtoul(str, &endp, 0); |
283 | attr->exclude_kernel = 1; | 332 | if (endp > str) { |
333 | attr->type = type; | ||
334 | attr->config = config; | ||
335 | *strp = endp; | ||
336 | return 1; | ||
284 | } | 337 | } |
285 | attr->type = type; | 338 | } |
286 | attr->config = id; | 339 | return 0; |
340 | } | ||
287 | 341 | ||
342 | static int | ||
343 | parse_event_modifier(const char **strp, struct perf_counter_attr *attr) | ||
344 | { | ||
345 | const char *str = *strp; | ||
346 | int eu = 1, ek = 1, eh = 1; | ||
347 | |||
348 | if (*str++ != ':') | ||
288 | return 0; | 349 | return 0; |
350 | while (*str) { | ||
351 | if (*str == 'u') | ||
352 | eu = 0; | ||
353 | else if (*str == 'k') | ||
354 | ek = 0; | ||
355 | else if (*str == 'h') | ||
356 | eh = 0; | ||
357 | else | ||
358 | break; | ||
359 | ++str; | ||
289 | } | 360 | } |
361 | if (str >= *strp + 2) { | ||
362 | *strp = str; | ||
363 | attr->exclude_user = eu; | ||
364 | attr->exclude_kernel = ek; | ||
365 | attr->exclude_hv = eh; | ||
366 | return 1; | ||
367 | } | ||
368 | return 0; | ||
369 | } | ||
290 | 370 | ||
291 | for (i = 0; i < ARRAY_SIZE(event_symbols); i++) { | 371 | /* |
292 | if (check_events(str, i)) { | 372 | * Each event can have multiple symbolic names. |
293 | attr->type = event_symbols[i].type; | 373 | * Symbolic names are (almost) exactly matched. |
294 | attr->config = event_symbols[i].config; | 374 | */ |
375 | static int parse_event_symbols(const char **str, struct perf_counter_attr *attr) | ||
376 | { | ||
377 | if (!(parse_raw_event(str, attr) || | ||
378 | parse_numeric_event(str, attr) || | ||
379 | parse_symbolic_event(str, attr) || | ||
380 | parse_generic_hw_event(str, attr))) | ||
381 | return 0; | ||
295 | 382 | ||
296 | return 0; | 383 | parse_event_modifier(str, attr); |
297 | } | ||
298 | } | ||
299 | 384 | ||
300 | return parse_generic_hw_symbols(str, attr); | 385 | return 1; |
301 | } | 386 | } |
302 | 387 | ||
303 | int parse_events(const struct option *opt, const char *str, int unset) | 388 | int parse_events(const struct option *opt __used, const char *str, int unset __used) |
304 | { | 389 | { |
305 | struct perf_counter_attr attr; | 390 | struct perf_counter_attr attr; |
306 | int ret; | ||
307 | 391 | ||
308 | memset(&attr, 0, sizeof(attr)); | 392 | for (;;) { |
309 | again: | 393 | if (nr_counters == MAX_COUNTERS) |
310 | if (nr_counters == MAX_COUNTERS) | 394 | return -1; |
311 | return -1; | 395 | |
396 | memset(&attr, 0, sizeof(attr)); | ||
397 | if (!parse_event_symbols(&str, &attr)) | ||
398 | return -1; | ||
312 | 399 | ||
313 | ret = parse_event_symbols(str, &attr); | 400 | if (!(*str == 0 || *str == ',' || isspace(*str))) |
314 | if (ret < 0) | 401 | return -1; |
315 | return ret; | ||
316 | 402 | ||
317 | attrs[nr_counters] = attr; | 403 | attrs[nr_counters] = attr; |
318 | nr_counters++; | 404 | nr_counters++; |
319 | 405 | ||
320 | str = strstr(str, ","); | 406 | if (*str == 0) |
321 | if (str) { | 407 | break; |
322 | str++; | 408 | if (*str == ',') |
323 | goto again; | 409 | ++str; |
410 | while (isspace(*str)) | ||
411 | ++str; | ||
324 | } | 412 | } |
325 | 413 | ||
326 | return 0; | 414 | return 0; |
@@ -340,7 +428,7 @@ static const char * const event_type_descriptors[] = { | |||
340 | void print_events(void) | 428 | void print_events(void) |
341 | { | 429 | { |
342 | struct event_symbol *syms = event_symbols; | 430 | struct event_symbol *syms = event_symbols; |
343 | unsigned int i, type, prev_type = -1; | 431 | unsigned int i, type, op, prev_type = -1; |
344 | char name[40]; | 432 | char name[40]; |
345 | 433 | ||
346 | fprintf(stderr, "\n"); | 434 | fprintf(stderr, "\n"); |
@@ -365,6 +453,21 @@ void print_events(void) | |||
365 | } | 453 | } |
366 | 454 | ||
367 | fprintf(stderr, "\n"); | 455 | fprintf(stderr, "\n"); |
456 | for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { | ||
457 | for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { | ||
458 | /* skip invalid cache type */ | ||
459 | if (!is_cache_op_valid(type, op)) | ||
460 | continue; | ||
461 | |||
462 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { | ||
463 | fprintf(stderr, " %-40s [%s]\n", | ||
464 | event_cache_name(type, op, i), | ||
465 | event_type_descriptors[4]); | ||
466 | } | ||
467 | } | ||
468 | } | ||
469 | |||
470 | fprintf(stderr, "\n"); | ||
368 | fprintf(stderr, " %-40s [raw hardware event descriptor]\n", | 471 | fprintf(stderr, " %-40s [raw hardware event descriptor]\n", |
369 | "rNNN"); | 472 | "rNNN"); |
370 | fprintf(stderr, "\n"); | 473 | fprintf(stderr, "\n"); |
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index b3affb1658d2..1bf67190c820 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c | |||
@@ -20,7 +20,8 @@ static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, | |||
20 | if (p->opt) { | 20 | if (p->opt) { |
21 | *arg = p->opt; | 21 | *arg = p->opt; |
22 | p->opt = NULL; | 22 | p->opt = NULL; |
23 | } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) { | 23 | } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 || |
24 | **(p->argv + 1) == '-')) { | ||
24 | *arg = (const char *)opt->defval; | 25 | *arg = (const char *)opt->defval; |
25 | } else if (p->argc > 1) { | 26 | } else if (p->argc > 1) { |
26 | p->argc--; | 27 | p->argc--; |
@@ -485,7 +486,7 @@ int parse_options_usage(const char * const *usagestr, | |||
485 | } | 486 | } |
486 | 487 | ||
487 | 488 | ||
488 | int parse_opt_verbosity_cb(const struct option *opt, const char *arg, | 489 | int parse_opt_verbosity_cb(const struct option *opt, const char *arg __used, |
489 | int unset) | 490 | int unset) |
490 | { | 491 | { |
491 | int *target = opt->value; | 492 | int *target = opt->value; |
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h index a1039a6ce0eb..8aa3464c7090 100644 --- a/tools/perf/util/parse-options.h +++ b/tools/perf/util/parse-options.h | |||
@@ -90,21 +90,22 @@ struct option { | |||
90 | intptr_t defval; | 90 | intptr_t defval; |
91 | }; | 91 | }; |
92 | 92 | ||
93 | #define OPT_END() { OPTION_END } | 93 | #define OPT_END() { .type = OPTION_END } |
94 | #define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) } | 94 | #define OPT_ARGUMENT(l, h) { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) } |
95 | #define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } | 95 | #define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) } |
96 | #define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) } | 96 | #define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (b) } |
97 | #define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) } | 97 | #define OPT_BOOLEAN(s, l, v, h) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = (v), .help = (h) } |
98 | #define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) } | 98 | #define OPT_SET_INT(s, l, v, h, i) { .type = OPTION_SET_INT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (i) } |
99 | #define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) } | 99 | #define OPT_SET_PTR(s, l, v, h, p) { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) } |
100 | #define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) } | 100 | #define OPT_INTEGER(s, l, v, h) { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = (v), .help = (h) } |
101 | #define OPT_LONG(s, l, v, h) { OPTION_LONG, (s), (l), (v), NULL, (h) } | 101 | #define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = (v), .help = (h) } |
102 | #define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) } | 102 | #define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h) } |
103 | #define OPT_DATE(s, l, v, h) \ | 103 | #define OPT_DATE(s, l, v, h) \ |
104 | { OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \ | 104 | { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb } |
105 | parse_opt_approxidate_cb } | ||
106 | #define OPT_CALLBACK(s, l, v, a, h, f) \ | 105 | #define OPT_CALLBACK(s, l, v, a, h, f) \ |
107 | { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) } | 106 | { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f) } |
107 | #define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \ | ||
108 | { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f), .defval = (intptr_t)d, .flags = PARSE_OPT_LASTARG_DEFAULT } | ||
108 | 109 | ||
109 | /* parse_options() will filter out the processed options and leave the | 110 | /* parse_options() will filter out the processed options and leave the |
110 | * non-option argments in argv[]. | 111 | * non-option argments in argv[]. |
diff --git a/tools/perf/util/quote.c b/tools/perf/util/quote.c index f18c5212bc92..c6e5dc0dc82f 100644 --- a/tools/perf/util/quote.c +++ b/tools/perf/util/quote.c | |||
@@ -162,12 +162,16 @@ static inline int sq_must_quote(char c) | |||
162 | return sq_lookup[(unsigned char)c] + quote_path_fully > 0; | 162 | return sq_lookup[(unsigned char)c] + quote_path_fully > 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | /* returns the longest prefix not needing a quote up to maxlen if positive. | 165 | /* |
166 | This stops at the first \0 because it's marked as a character needing an | 166 | * Returns the longest prefix not needing a quote up to maxlen if |
167 | escape */ | 167 | * positive. |
168 | static size_t next_quote_pos(const char *s, ssize_t maxlen) | 168 | * This stops at the first \0 because it's marked as a character |
169 | * needing an escape. | ||
170 | */ | ||
171 | static ssize_t next_quote_pos(const char *s, ssize_t maxlen) | ||
169 | { | 172 | { |
170 | size_t len; | 173 | ssize_t len; |
174 | |||
171 | if (maxlen < 0) { | 175 | if (maxlen < 0) { |
172 | for (len = 0; !sq_must_quote(s[len]); len++); | 176 | for (len = 0; !sq_must_quote(s[len]); len++); |
173 | } else { | 177 | } else { |
@@ -192,22 +196,22 @@ static size_t next_quote_pos(const char *s, ssize_t maxlen) | |||
192 | static size_t quote_c_style_counted(const char *name, ssize_t maxlen, | 196 | static size_t quote_c_style_counted(const char *name, ssize_t maxlen, |
193 | struct strbuf *sb, FILE *fp, int no_dq) | 197 | struct strbuf *sb, FILE *fp, int no_dq) |
194 | { | 198 | { |
195 | #undef EMIT | 199 | #define EMIT(c) \ |
196 | #define EMIT(c) \ | 200 | do { \ |
197 | do { \ | 201 | if (sb) strbuf_addch(sb, (c)); \ |
198 | if (sb) strbuf_addch(sb, (c)); \ | 202 | if (fp) fputc((c), fp); \ |
199 | if (fp) fputc((c), fp); \ | 203 | count++; \ |
200 | count++; \ | ||
201 | } while (0) | 204 | } while (0) |
202 | #define EMITBUF(s, l) \ | 205 | |
203 | do { \ | 206 | #define EMITBUF(s, l) \ |
204 | int __ret; \ | 207 | do { \ |
205 | if (sb) strbuf_add(sb, (s), (l)); \ | 208 | int __ret; \ |
206 | if (fp) __ret = fwrite((s), (l), 1, fp); \ | 209 | if (sb) strbuf_add(sb, (s), (l)); \ |
207 | count += (l); \ | 210 | if (fp) __ret = fwrite((s), (l), 1, fp); \ |
211 | count += (l); \ | ||
208 | } while (0) | 212 | } while (0) |
209 | 213 | ||
210 | size_t len, count = 0; | 214 | ssize_t len, count = 0; |
211 | const char *p = name; | 215 | const char *p = name; |
212 | 216 | ||
213 | for (;;) { | 217 | for (;;) { |
@@ -273,8 +277,8 @@ void write_name_quoted(const char *name, FILE *fp, int terminator) | |||
273 | fputc(terminator, fp); | 277 | fputc(terminator, fp); |
274 | } | 278 | } |
275 | 279 | ||
276 | extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, | 280 | void write_name_quotedpfx(const char *pfx, ssize_t pfxlen, |
277 | const char *name, FILE *fp, int terminator) | 281 | const char *name, FILE *fp, int terminator) |
278 | { | 282 | { |
279 | int needquote = 0; | 283 | int needquote = 0; |
280 | 284 | ||
@@ -306,7 +310,7 @@ char *quote_path_relative(const char *in, int len, | |||
306 | len = strlen(in); | 310 | len = strlen(in); |
307 | 311 | ||
308 | /* "../" prefix itself does not need quoting, but "in" might. */ | 312 | /* "../" prefix itself does not need quoting, but "in" might. */ |
309 | needquote = next_quote_pos(in, len) < len; | 313 | needquote = (next_quote_pos(in, len) < len); |
310 | strbuf_setlen(out, 0); | 314 | strbuf_setlen(out, 0); |
311 | strbuf_grow(out, len); | 315 | strbuf_grow(out, len); |
312 | 316 | ||
diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h index 5dfad89816db..a5454a1d1c13 100644 --- a/tools/perf/util/quote.h +++ b/tools/perf/util/quote.h | |||
@@ -53,7 +53,7 @@ extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq | |||
53 | extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); | 53 | extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); |
54 | 54 | ||
55 | extern void write_name_quoted(const char *name, FILE *, int terminator); | 55 | extern void write_name_quoted(const char *name, FILE *, int terminator); |
56 | extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, | 56 | extern void write_name_quotedpfx(const char *pfx, ssize_t pfxlen, |
57 | const char *name, FILE *, int terminator); | 57 | const char *name, FILE *, int terminator); |
58 | 58 | ||
59 | /* quote path as relative to the given prefix */ | 59 | /* quote path as relative to the given prefix */ |
diff --git a/tools/perf/util/rbtree.c b/tools/perf/util/rbtree.c deleted file mode 100644 index b15ba9c7cb3f..000000000000 --- a/tools/perf/util/rbtree.c +++ /dev/null | |||
@@ -1,383 +0,0 @@ | |||
1 | /* | ||
2 | Red Black Trees | ||
3 | (C) 1999 Andrea Arcangeli <andrea@suse.de> | ||
4 | (C) 2002 David Woodhouse <dwmw2@infradead.org> | ||
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 as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | |||
20 | linux/lib/rbtree.c | ||
21 | */ | ||
22 | |||
23 | #include "rbtree.h" | ||
24 | |||
25 | static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) | ||
26 | { | ||
27 | struct rb_node *right = node->rb_right; | ||
28 | struct rb_node *parent = rb_parent(node); | ||
29 | |||
30 | if ((node->rb_right = right->rb_left)) | ||
31 | rb_set_parent(right->rb_left, node); | ||
32 | right->rb_left = node; | ||
33 | |||
34 | rb_set_parent(right, parent); | ||
35 | |||
36 | if (parent) | ||
37 | { | ||
38 | if (node == parent->rb_left) | ||
39 | parent->rb_left = right; | ||
40 | else | ||
41 | parent->rb_right = right; | ||
42 | } | ||
43 | else | ||
44 | root->rb_node = right; | ||
45 | rb_set_parent(node, right); | ||
46 | } | ||
47 | |||
48 | static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) | ||
49 | { | ||
50 | struct rb_node *left = node->rb_left; | ||
51 | struct rb_node *parent = rb_parent(node); | ||
52 | |||
53 | if ((node->rb_left = left->rb_right)) | ||
54 | rb_set_parent(left->rb_right, node); | ||
55 | left->rb_right = node; | ||
56 | |||
57 | rb_set_parent(left, parent); | ||
58 | |||
59 | if (parent) | ||
60 | { | ||
61 | if (node == parent->rb_right) | ||
62 | parent->rb_right = left; | ||
63 | else | ||
64 | parent->rb_left = left; | ||
65 | } | ||
66 | else | ||
67 | root->rb_node = left; | ||
68 | rb_set_parent(node, left); | ||
69 | } | ||
70 | |||
71 | void rb_insert_color(struct rb_node *node, struct rb_root *root) | ||
72 | { | ||
73 | struct rb_node *parent, *gparent; | ||
74 | |||
75 | while ((parent = rb_parent(node)) && rb_is_red(parent)) | ||
76 | { | ||
77 | gparent = rb_parent(parent); | ||
78 | |||
79 | if (parent == gparent->rb_left) | ||
80 | { | ||
81 | { | ||
82 | register struct rb_node *uncle = gparent->rb_right; | ||
83 | if (uncle && rb_is_red(uncle)) | ||
84 | { | ||
85 | rb_set_black(uncle); | ||
86 | rb_set_black(parent); | ||
87 | rb_set_red(gparent); | ||
88 | node = gparent; | ||
89 | continue; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | if (parent->rb_right == node) | ||
94 | { | ||
95 | register struct rb_node *tmp; | ||
96 | __rb_rotate_left(parent, root); | ||
97 | tmp = parent; | ||
98 | parent = node; | ||
99 | node = tmp; | ||
100 | } | ||
101 | |||
102 | rb_set_black(parent); | ||
103 | rb_set_red(gparent); | ||
104 | __rb_rotate_right(gparent, root); | ||
105 | } else { | ||
106 | { | ||
107 | register struct rb_node *uncle = gparent->rb_left; | ||
108 | if (uncle && rb_is_red(uncle)) | ||
109 | { | ||
110 | rb_set_black(uncle); | ||
111 | rb_set_black(parent); | ||
112 | rb_set_red(gparent); | ||
113 | node = gparent; | ||
114 | continue; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | if (parent->rb_left == node) | ||
119 | { | ||
120 | register struct rb_node *tmp; | ||
121 | __rb_rotate_right(parent, root); | ||
122 | tmp = parent; | ||
123 | parent = node; | ||
124 | node = tmp; | ||
125 | } | ||
126 | |||
127 | rb_set_black(parent); | ||
128 | rb_set_red(gparent); | ||
129 | __rb_rotate_left(gparent, root); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | rb_set_black(root->rb_node); | ||
134 | } | ||
135 | |||
136 | static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, | ||
137 | struct rb_root *root) | ||
138 | { | ||
139 | struct rb_node *other; | ||
140 | |||
141 | while ((!node || rb_is_black(node)) && node != root->rb_node) | ||
142 | { | ||
143 | if (parent->rb_left == node) | ||
144 | { | ||
145 | other = parent->rb_right; | ||
146 | if (rb_is_red(other)) | ||
147 | { | ||
148 | rb_set_black(other); | ||
149 | rb_set_red(parent); | ||
150 | __rb_rotate_left(parent, root); | ||
151 | other = parent->rb_right; | ||
152 | } | ||
153 | if ((!other->rb_left || rb_is_black(other->rb_left)) && | ||
154 | (!other->rb_right || rb_is_black(other->rb_right))) | ||
155 | { | ||
156 | rb_set_red(other); | ||
157 | node = parent; | ||
158 | parent = rb_parent(node); | ||
159 | } | ||
160 | else | ||
161 | { | ||
162 | if (!other->rb_right || rb_is_black(other->rb_right)) | ||
163 | { | ||
164 | rb_set_black(other->rb_left); | ||
165 | rb_set_red(other); | ||
166 | __rb_rotate_right(other, root); | ||
167 | other = parent->rb_right; | ||
168 | } | ||
169 | rb_set_color(other, rb_color(parent)); | ||
170 | rb_set_black(parent); | ||
171 | rb_set_black(other->rb_right); | ||
172 | __rb_rotate_left(parent, root); | ||
173 | node = root->rb_node; | ||
174 | break; | ||
175 | } | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | other = parent->rb_left; | ||
180 | if (rb_is_red(other)) | ||
181 | { | ||
182 | rb_set_black(other); | ||
183 | rb_set_red(parent); | ||
184 | __rb_rotate_right(parent, root); | ||
185 | other = parent->rb_left; | ||
186 | } | ||
187 | if ((!other->rb_left || rb_is_black(other->rb_left)) && | ||
188 | (!other->rb_right || rb_is_black(other->rb_right))) | ||
189 | { | ||
190 | rb_set_red(other); | ||
191 | node = parent; | ||
192 | parent = rb_parent(node); | ||
193 | } | ||
194 | else | ||
195 | { | ||
196 | if (!other->rb_left || rb_is_black(other->rb_left)) | ||
197 | { | ||
198 | rb_set_black(other->rb_right); | ||
199 | rb_set_red(other); | ||
200 | __rb_rotate_left(other, root); | ||
201 | other = parent->rb_left; | ||
202 | } | ||
203 | rb_set_color(other, rb_color(parent)); | ||
204 | rb_set_black(parent); | ||
205 | rb_set_black(other->rb_left); | ||
206 | __rb_rotate_right(parent, root); | ||
207 | node = root->rb_node; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | if (node) | ||
213 | rb_set_black(node); | ||
214 | } | ||
215 | |||
216 | void rb_erase(struct rb_node *node, struct rb_root *root) | ||
217 | { | ||
218 | struct rb_node *child, *parent; | ||
219 | int color; | ||
220 | |||
221 | if (!node->rb_left) | ||
222 | child = node->rb_right; | ||
223 | else if (!node->rb_right) | ||
224 | child = node->rb_left; | ||
225 | else | ||
226 | { | ||
227 | struct rb_node *old = node, *left; | ||
228 | |||
229 | node = node->rb_right; | ||
230 | while ((left = node->rb_left) != NULL) | ||
231 | node = left; | ||
232 | child = node->rb_right; | ||
233 | parent = rb_parent(node); | ||
234 | color = rb_color(node); | ||
235 | |||
236 | if (child) | ||
237 | rb_set_parent(child, parent); | ||
238 | if (parent == old) { | ||
239 | parent->rb_right = child; | ||
240 | parent = node; | ||
241 | } else | ||
242 | parent->rb_left = child; | ||
243 | |||
244 | node->rb_parent_color = old->rb_parent_color; | ||
245 | node->rb_right = old->rb_right; | ||
246 | node->rb_left = old->rb_left; | ||
247 | |||
248 | if (rb_parent(old)) | ||
249 | { | ||
250 | if (rb_parent(old)->rb_left == old) | ||
251 | rb_parent(old)->rb_left = node; | ||
252 | else | ||
253 | rb_parent(old)->rb_right = node; | ||
254 | } else | ||
255 | root->rb_node = node; | ||
256 | |||
257 | rb_set_parent(old->rb_left, node); | ||
258 | if (old->rb_right) | ||
259 | rb_set_parent(old->rb_right, node); | ||
260 | goto color; | ||
261 | } | ||
262 | |||
263 | parent = rb_parent(node); | ||
264 | color = rb_color(node); | ||
265 | |||
266 | if (child) | ||
267 | rb_set_parent(child, parent); | ||
268 | if (parent) | ||
269 | { | ||
270 | if (parent->rb_left == node) | ||
271 | parent->rb_left = child; | ||
272 | else | ||
273 | parent->rb_right = child; | ||
274 | } | ||
275 | else | ||
276 | root->rb_node = child; | ||
277 | |||
278 | color: | ||
279 | if (color == RB_BLACK) | ||
280 | __rb_erase_color(child, parent, root); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * This function returns the first node (in sort order) of the tree. | ||
285 | */ | ||
286 | struct rb_node *rb_first(const struct rb_root *root) | ||
287 | { | ||
288 | struct rb_node *n; | ||
289 | |||
290 | n = root->rb_node; | ||
291 | if (!n) | ||
292 | return NULL; | ||
293 | while (n->rb_left) | ||
294 | n = n->rb_left; | ||
295 | return n; | ||
296 | } | ||
297 | |||
298 | struct rb_node *rb_last(const struct rb_root *root) | ||
299 | { | ||
300 | struct rb_node *n; | ||
301 | |||
302 | n = root->rb_node; | ||
303 | if (!n) | ||
304 | return NULL; | ||
305 | while (n->rb_right) | ||
306 | n = n->rb_right; | ||
307 | return n; | ||
308 | } | ||
309 | |||
310 | struct rb_node *rb_next(const struct rb_node *node) | ||
311 | { | ||
312 | struct rb_node *parent; | ||
313 | |||
314 | if (rb_parent(node) == node) | ||
315 | return NULL; | ||
316 | |||
317 | /* If we have a right-hand child, go down and then left as far | ||
318 | as we can. */ | ||
319 | if (node->rb_right) { | ||
320 | node = node->rb_right; | ||
321 | while (node->rb_left) | ||
322 | node=node->rb_left; | ||
323 | return (struct rb_node *)node; | ||
324 | } | ||
325 | |||
326 | /* No right-hand children. Everything down and left is | ||
327 | smaller than us, so any 'next' node must be in the general | ||
328 | direction of our parent. Go up the tree; any time the | ||
329 | ancestor is a right-hand child of its parent, keep going | ||
330 | up. First time it's a left-hand child of its parent, said | ||
331 | parent is our 'next' node. */ | ||
332 | while ((parent = rb_parent(node)) && node == parent->rb_right) | ||
333 | node = parent; | ||
334 | |||
335 | return parent; | ||
336 | } | ||
337 | |||
338 | struct rb_node *rb_prev(const struct rb_node *node) | ||
339 | { | ||
340 | struct rb_node *parent; | ||
341 | |||
342 | if (rb_parent(node) == node) | ||
343 | return NULL; | ||
344 | |||
345 | /* If we have a left-hand child, go down and then right as far | ||
346 | as we can. */ | ||
347 | if (node->rb_left) { | ||
348 | node = node->rb_left; | ||
349 | while (node->rb_right) | ||
350 | node=node->rb_right; | ||
351 | return (struct rb_node *)node; | ||
352 | } | ||
353 | |||
354 | /* No left-hand children. Go up till we find an ancestor which | ||
355 | is a right-hand child of its parent */ | ||
356 | while ((parent = rb_parent(node)) && node == parent->rb_left) | ||
357 | node = parent; | ||
358 | |||
359 | return parent; | ||
360 | } | ||
361 | |||
362 | void rb_replace_node(struct rb_node *victim, struct rb_node *new, | ||
363 | struct rb_root *root) | ||
364 | { | ||
365 | struct rb_node *parent = rb_parent(victim); | ||
366 | |||
367 | /* Set the surrounding nodes to point to the replacement */ | ||
368 | if (parent) { | ||
369 | if (victim == parent->rb_left) | ||
370 | parent->rb_left = new; | ||
371 | else | ||
372 | parent->rb_right = new; | ||
373 | } else { | ||
374 | root->rb_node = new; | ||
375 | } | ||
376 | if (victim->rb_left) | ||
377 | rb_set_parent(victim->rb_left, new); | ||
378 | if (victim->rb_right) | ||
379 | rb_set_parent(victim->rb_right, new); | ||
380 | |||
381 | /* Copy the pointers/colour from the victim to the replacement */ | ||
382 | *new = *victim; | ||
383 | } | ||
diff --git a/tools/perf/util/rbtree.h b/tools/perf/util/rbtree.h deleted file mode 100644 index 6bdc488a47fb..000000000000 --- a/tools/perf/util/rbtree.h +++ /dev/null | |||
@@ -1,171 +0,0 @@ | |||
1 | /* | ||
2 | Red Black Trees | ||
3 | (C) 1999 Andrea Arcangeli <andrea@suse.de> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | |||
19 | linux/include/linux/rbtree.h | ||
20 | |||
21 | To use rbtrees you'll have to implement your own insert and search cores. | ||
22 | This will avoid us to use callbacks and to drop drammatically performances. | ||
23 | I know it's not the cleaner way, but in C (not in C++) to get | ||
24 | performances and genericity... | ||
25 | |||
26 | Some example of insert and search follows here. The search is a plain | ||
27 | normal search over an ordered tree. The insert instead must be implemented | ||
28 | int two steps: as first thing the code must insert the element in | ||
29 | order as a red leaf in the tree, then the support library function | ||
30 | rb_insert_color() must be called. Such function will do the | ||
31 | not trivial work to rebalance the rbtree if necessary. | ||
32 | |||
33 | ----------------------------------------------------------------------- | ||
34 | static inline struct page * rb_search_page_cache(struct inode * inode, | ||
35 | unsigned long offset) | ||
36 | { | ||
37 | struct rb_node * n = inode->i_rb_page_cache.rb_node; | ||
38 | struct page * page; | ||
39 | |||
40 | while (n) | ||
41 | { | ||
42 | page = rb_entry(n, struct page, rb_page_cache); | ||
43 | |||
44 | if (offset < page->offset) | ||
45 | n = n->rb_left; | ||
46 | else if (offset > page->offset) | ||
47 | n = n->rb_right; | ||
48 | else | ||
49 | return page; | ||
50 | } | ||
51 | return NULL; | ||
52 | } | ||
53 | |||
54 | static inline struct page * __rb_insert_page_cache(struct inode * inode, | ||
55 | unsigned long offset, | ||
56 | struct rb_node * node) | ||
57 | { | ||
58 | struct rb_node ** p = &inode->i_rb_page_cache.rb_node; | ||
59 | struct rb_node * parent = NULL; | ||
60 | struct page * page; | ||
61 | |||
62 | while (*p) | ||
63 | { | ||
64 | parent = *p; | ||
65 | page = rb_entry(parent, struct page, rb_page_cache); | ||
66 | |||
67 | if (offset < page->offset) | ||
68 | p = &(*p)->rb_left; | ||
69 | else if (offset > page->offset) | ||
70 | p = &(*p)->rb_right; | ||
71 | else | ||
72 | return page; | ||
73 | } | ||
74 | |||
75 | rb_link_node(node, parent, p); | ||
76 | |||
77 | return NULL; | ||
78 | } | ||
79 | |||
80 | static inline struct page * rb_insert_page_cache(struct inode * inode, | ||
81 | unsigned long offset, | ||
82 | struct rb_node * node) | ||
83 | { | ||
84 | struct page * ret; | ||
85 | if ((ret = __rb_insert_page_cache(inode, offset, node))) | ||
86 | goto out; | ||
87 | rb_insert_color(node, &inode->i_rb_page_cache); | ||
88 | out: | ||
89 | return ret; | ||
90 | } | ||
91 | ----------------------------------------------------------------------- | ||
92 | */ | ||
93 | |||
94 | #ifndef _LINUX_RBTREE_H | ||
95 | #define _LINUX_RBTREE_H | ||
96 | |||
97 | #include <stddef.h> | ||
98 | |||
99 | /** | ||
100 | * container_of - cast a member of a structure out to the containing structure | ||
101 | * @ptr: the pointer to the member. | ||
102 | * @type: the type of the container struct this is embedded in. | ||
103 | * @member: the name of the member within the struct. | ||
104 | * | ||
105 | */ | ||
106 | #define container_of(ptr, type, member) ({ \ | ||
107 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | ||
108 | (type *)( (char *)__mptr - offsetof(type,member) );}) | ||
109 | |||
110 | struct rb_node | ||
111 | { | ||
112 | unsigned long rb_parent_color; | ||
113 | #define RB_RED 0 | ||
114 | #define RB_BLACK 1 | ||
115 | struct rb_node *rb_right; | ||
116 | struct rb_node *rb_left; | ||
117 | } __attribute__((aligned(sizeof(long)))); | ||
118 | /* The alignment might seem pointless, but allegedly CRIS needs it */ | ||
119 | |||
120 | struct rb_root | ||
121 | { | ||
122 | struct rb_node *rb_node; | ||
123 | }; | ||
124 | |||
125 | |||
126 | #define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3)) | ||
127 | #define rb_color(r) ((r)->rb_parent_color & 1) | ||
128 | #define rb_is_red(r) (!rb_color(r)) | ||
129 | #define rb_is_black(r) rb_color(r) | ||
130 | #define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0) | ||
131 | #define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0) | ||
132 | |||
133 | static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) | ||
134 | { | ||
135 | rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p; | ||
136 | } | ||
137 | static inline void rb_set_color(struct rb_node *rb, int color) | ||
138 | { | ||
139 | rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; | ||
140 | } | ||
141 | |||
142 | #define RB_ROOT (struct rb_root) { NULL, } | ||
143 | #define rb_entry(ptr, type, member) container_of(ptr, type, member) | ||
144 | |||
145 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) | ||
146 | #define RB_EMPTY_NODE(node) (rb_parent(node) == node) | ||
147 | #define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) | ||
148 | |||
149 | extern void rb_insert_color(struct rb_node *, struct rb_root *); | ||
150 | extern void rb_erase(struct rb_node *, struct rb_root *); | ||
151 | |||
152 | /* Find logical next and previous nodes in a tree */ | ||
153 | extern struct rb_node *rb_next(const struct rb_node *); | ||
154 | extern struct rb_node *rb_prev(const struct rb_node *); | ||
155 | extern struct rb_node *rb_first(const struct rb_root *); | ||
156 | extern struct rb_node *rb_last(const struct rb_root *); | ||
157 | |||
158 | /* Fast replacement of a single node without remove/rebalance/add/rebalance */ | ||
159 | extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, | ||
160 | struct rb_root *root); | ||
161 | |||
162 | static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, | ||
163 | struct rb_node ** rb_link) | ||
164 | { | ||
165 | node->rb_parent_color = (unsigned long )parent; | ||
166 | node->rb_left = node->rb_right = NULL; | ||
167 | |||
168 | *rb_link = node; | ||
169 | } | ||
170 | |||
171 | #endif /* _LINUX_RBTREE_H */ | ||
diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index 464e7ca898cf..5249d5a1b0c2 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c | |||
@@ -16,7 +16,7 @@ int prefixcmp(const char *str, const char *prefix) | |||
16 | */ | 16 | */ |
17 | char strbuf_slopbuf[1]; | 17 | char strbuf_slopbuf[1]; |
18 | 18 | ||
19 | void strbuf_init(struct strbuf *sb, size_t hint) | 19 | void strbuf_init(struct strbuf *sb, ssize_t hint) |
20 | { | 20 | { |
21 | sb->alloc = sb->len = 0; | 21 | sb->alloc = sb->len = 0; |
22 | sb->buf = strbuf_slopbuf; | 22 | sb->buf = strbuf_slopbuf; |
@@ -92,7 +92,8 @@ void strbuf_ltrim(struct strbuf *sb) | |||
92 | 92 | ||
93 | void strbuf_tolower(struct strbuf *sb) | 93 | void strbuf_tolower(struct strbuf *sb) |
94 | { | 94 | { |
95 | int i; | 95 | unsigned int i; |
96 | |||
96 | for (i = 0; i < sb->len; i++) | 97 | for (i = 0; i < sb->len; i++) |
97 | sb->buf[i] = tolower(sb->buf[i]); | 98 | sb->buf[i] = tolower(sb->buf[i]); |
98 | } | 99 | } |
@@ -264,7 +265,7 @@ size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) | |||
264 | return res; | 265 | return res; |
265 | } | 266 | } |
266 | 267 | ||
267 | ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) | 268 | ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) |
268 | { | 269 | { |
269 | size_t oldlen = sb->len; | 270 | size_t oldlen = sb->len; |
270 | size_t oldalloc = sb->alloc; | 271 | size_t oldalloc = sb->alloc; |
@@ -293,7 +294,7 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) | |||
293 | 294 | ||
294 | #define STRBUF_MAXLINK (2*PATH_MAX) | 295 | #define STRBUF_MAXLINK (2*PATH_MAX) |
295 | 296 | ||
296 | int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint) | 297 | int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint) |
297 | { | 298 | { |
298 | size_t oldalloc = sb->alloc; | 299 | size_t oldalloc = sb->alloc; |
299 | 300 | ||
@@ -301,7 +302,7 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint) | |||
301 | hint = 32; | 302 | hint = 32; |
302 | 303 | ||
303 | while (hint < STRBUF_MAXLINK) { | 304 | while (hint < STRBUF_MAXLINK) { |
304 | int len; | 305 | ssize_t len; |
305 | 306 | ||
306 | strbuf_grow(sb, hint); | 307 | strbuf_grow(sb, hint); |
307 | len = readlink(path, sb->buf, hint); | 308 | len = readlink(path, sb->buf, hint); |
@@ -343,7 +344,7 @@ int strbuf_getline(struct strbuf *sb, FILE *fp, int term) | |||
343 | return 0; | 344 | return 0; |
344 | } | 345 | } |
345 | 346 | ||
346 | int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint) | 347 | int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint) |
347 | { | 348 | { |
348 | int fd, len; | 349 | int fd, len; |
349 | 350 | ||
diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h index 9ee908a3ec5d..d2aa86c014c1 100644 --- a/tools/perf/util/strbuf.h +++ b/tools/perf/util/strbuf.h | |||
@@ -50,7 +50,7 @@ struct strbuf { | |||
50 | #define STRBUF_INIT { 0, 0, strbuf_slopbuf } | 50 | #define STRBUF_INIT { 0, 0, strbuf_slopbuf } |
51 | 51 | ||
52 | /*----- strbuf life cycle -----*/ | 52 | /*----- strbuf life cycle -----*/ |
53 | extern void strbuf_init(struct strbuf *, size_t); | 53 | extern void strbuf_init(struct strbuf *buf, ssize_t hint); |
54 | extern void strbuf_release(struct strbuf *); | 54 | extern void strbuf_release(struct strbuf *); |
55 | extern char *strbuf_detach(struct strbuf *, size_t *); | 55 | extern char *strbuf_detach(struct strbuf *, size_t *); |
56 | extern void strbuf_attach(struct strbuf *, void *, size_t, size_t); | 56 | extern void strbuf_attach(struct strbuf *, void *, size_t, size_t); |
@@ -61,7 +61,7 @@ static inline void strbuf_swap(struct strbuf *a, struct strbuf *b) { | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /*----- strbuf size related -----*/ | 63 | /*----- strbuf size related -----*/ |
64 | static inline size_t strbuf_avail(const struct strbuf *sb) { | 64 | static inline ssize_t strbuf_avail(const struct strbuf *sb) { |
65 | return sb->alloc ? sb->alloc - sb->len - 1 : 0; | 65 | return sb->alloc ? sb->alloc - sb->len - 1 : 0; |
66 | } | 66 | } |
67 | 67 | ||
@@ -122,9 +122,9 @@ extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); | |||
122 | 122 | ||
123 | extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); | 123 | extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); |
124 | /* XXX: if read fails, any partial read is undone */ | 124 | /* XXX: if read fails, any partial read is undone */ |
125 | extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint); | 125 | extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); |
126 | extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint); | 126 | extern int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint); |
127 | extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint); | 127 | extern int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint); |
128 | 128 | ||
129 | extern int strbuf_getline(struct strbuf *, FILE *, int); | 129 | extern int strbuf_getline(struct strbuf *, FILE *, int); |
130 | 130 | ||
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 2fb117fb4b67..2fdcfee87586 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef STRLIST_H_ | 1 | #ifndef STRLIST_H_ |
2 | #define STRLIST_H_ | 2 | #define STRLIST_H_ |
3 | 3 | ||
4 | #include "rbtree.h" | 4 | #include <linux/rbtree.h> |
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | 6 | ||
7 | struct str_node { | 7 | struct str_node { |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 78c2efde01b7..4683b67b5ee4 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -35,7 +35,7 @@ static struct symbol *symbol__new(u64 start, u64 len, | |||
35 | self = ((void *)self) + priv_size; | 35 | self = ((void *)self) + priv_size; |
36 | } | 36 | } |
37 | self->start = start; | 37 | self->start = start; |
38 | self->end = start + len - 1; | 38 | self->end = len ? start + len - 1 : start; |
39 | memcpy(self->name, name, namelen); | 39 | memcpy(self->name, name, namelen); |
40 | 40 | ||
41 | return self; | 41 | return self; |
@@ -48,8 +48,12 @@ static void symbol__delete(struct symbol *self, unsigned int priv_size) | |||
48 | 48 | ||
49 | static size_t symbol__fprintf(struct symbol *self, FILE *fp) | 49 | static size_t symbol__fprintf(struct symbol *self, FILE *fp) |
50 | { | 50 | { |
51 | return fprintf(fp, " %llx-%llx %s\n", | 51 | if (!self->module) |
52 | return fprintf(fp, " %llx-%llx %s\n", | ||
52 | self->start, self->end, self->name); | 53 | self->start, self->end, self->name); |
54 | else | ||
55 | return fprintf(fp, " %llx-%llx %s \t[%s]\n", | ||
56 | self->start, self->end, self->name, self->module->name); | ||
53 | } | 57 | } |
54 | 58 | ||
55 | struct dso *dso__new(const char *name, unsigned int sym_priv_size) | 59 | struct dso *dso__new(const char *name, unsigned int sym_priv_size) |
@@ -146,6 +150,7 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int verb | |||
146 | char *line = NULL; | 150 | char *line = NULL; |
147 | size_t n; | 151 | size_t n; |
148 | FILE *file = fopen("/proc/kallsyms", "r"); | 152 | FILE *file = fopen("/proc/kallsyms", "r"); |
153 | int count = 0; | ||
149 | 154 | ||
150 | if (file == NULL) | 155 | if (file == NULL) |
151 | goto out_failure; | 156 | goto out_failure; |
@@ -188,8 +193,10 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int verb | |||
188 | 193 | ||
189 | if (filter && filter(self, sym)) | 194 | if (filter && filter(self, sym)) |
190 | symbol__delete(sym, self->sym_priv_size); | 195 | symbol__delete(sym, self->sym_priv_size); |
191 | else | 196 | else { |
192 | dso__insert_symbol(self, sym); | 197 | dso__insert_symbol(self, sym); |
198 | count++; | ||
199 | } | ||
193 | } | 200 | } |
194 | 201 | ||
195 | /* | 202 | /* |
@@ -212,7 +219,7 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int verb | |||
212 | free(line); | 219 | free(line); |
213 | fclose(file); | 220 | fclose(file); |
214 | 221 | ||
215 | return 0; | 222 | return count; |
216 | 223 | ||
217 | out_delete_line: | 224 | out_delete_line: |
218 | free(line); | 225 | free(line); |
@@ -307,6 +314,26 @@ static inline int elf_sym__is_function(const GElf_Sym *sym) | |||
307 | sym->st_size != 0; | 314 | sym->st_size != 0; |
308 | } | 315 | } |
309 | 316 | ||
317 | static inline int elf_sym__is_label(const GElf_Sym *sym) | ||
318 | { | ||
319 | return elf_sym__type(sym) == STT_NOTYPE && | ||
320 | sym->st_name != 0 && | ||
321 | sym->st_shndx != SHN_UNDEF && | ||
322 | sym->st_shndx != SHN_ABS; | ||
323 | } | ||
324 | |||
325 | static inline const char *elf_sec__name(const GElf_Shdr *shdr, | ||
326 | const Elf_Data *secstrs) | ||
327 | { | ||
328 | return secstrs->d_buf + shdr->sh_name; | ||
329 | } | ||
330 | |||
331 | static inline int elf_sec__is_text(const GElf_Shdr *shdr, | ||
332 | const Elf_Data *secstrs) | ||
333 | { | ||
334 | return strstr(elf_sec__name(shdr, secstrs), "text") != NULL; | ||
335 | } | ||
336 | |||
310 | static inline const char *elf_sym__name(const GElf_Sym *sym, | 337 | static inline const char *elf_sym__name(const GElf_Sym *sym, |
311 | const Elf_Data *symstrs) | 338 | const Elf_Data *symstrs) |
312 | { | 339 | { |
@@ -448,9 +475,9 @@ static int dso__synthesize_plt_symbols(struct dso *self, Elf *elf, | |||
448 | } | 475 | } |
449 | 476 | ||
450 | static int dso__load_sym(struct dso *self, int fd, const char *name, | 477 | static int dso__load_sym(struct dso *self, int fd, const char *name, |
451 | symbol_filter_t filter, int verbose) | 478 | symbol_filter_t filter, int verbose, struct module *mod) |
452 | { | 479 | { |
453 | Elf_Data *symstrs; | 480 | Elf_Data *symstrs, *secstrs; |
454 | uint32_t nr_syms; | 481 | uint32_t nr_syms; |
455 | int err = -1; | 482 | int err = -1; |
456 | uint32_t index; | 483 | uint32_t index; |
@@ -458,7 +485,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, | |||
458 | GElf_Shdr shdr; | 485 | GElf_Shdr shdr; |
459 | Elf_Data *syms; | 486 | Elf_Data *syms; |
460 | GElf_Sym sym; | 487 | GElf_Sym sym; |
461 | Elf_Scn *sec, *sec_dynsym; | 488 | Elf_Scn *sec, *sec_dynsym, *sec_strndx; |
462 | Elf *elf; | 489 | Elf *elf; |
463 | size_t dynsym_idx; | 490 | size_t dynsym_idx; |
464 | int nr = 0; | 491 | int nr = 0; |
@@ -517,17 +544,29 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, | |||
517 | if (symstrs == NULL) | 544 | if (symstrs == NULL) |
518 | goto out_elf_end; | 545 | goto out_elf_end; |
519 | 546 | ||
547 | sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); | ||
548 | if (sec_strndx == NULL) | ||
549 | goto out_elf_end; | ||
550 | |||
551 | secstrs = elf_getdata(sec_strndx, NULL); | ||
552 | if (symstrs == NULL) | ||
553 | goto out_elf_end; | ||
554 | |||
520 | nr_syms = shdr.sh_size / shdr.sh_entsize; | 555 | nr_syms = shdr.sh_size / shdr.sh_entsize; |
521 | 556 | ||
522 | memset(&sym, 0, sizeof(sym)); | 557 | memset(&sym, 0, sizeof(sym)); |
523 | self->prelinked = elf_section_by_name(elf, &ehdr, &shdr, | 558 | self->adjust_symbols = (ehdr.e_type == ET_EXEC || |
524 | ".gnu.prelink_undo", | 559 | elf_section_by_name(elf, &ehdr, &shdr, |
525 | NULL) != NULL; | 560 | ".gnu.prelink_undo", |
561 | NULL) != NULL); | ||
526 | elf_symtab__for_each_symbol(syms, nr_syms, index, sym) { | 562 | elf_symtab__for_each_symbol(syms, nr_syms, index, sym) { |
527 | struct symbol *f; | 563 | struct symbol *f; |
528 | u64 obj_start; | 564 | u64 obj_start; |
565 | struct section *section = NULL; | ||
566 | int is_label = elf_sym__is_label(&sym); | ||
567 | const char *section_name; | ||
529 | 568 | ||
530 | if (!elf_sym__is_function(&sym)) | 569 | if (!is_label && !elf_sym__is_function(&sym)) |
531 | continue; | 570 | continue; |
532 | 571 | ||
533 | sec = elf_getscn(elf, sym.st_shndx); | 572 | sec = elf_getscn(elf, sym.st_shndx); |
@@ -535,9 +574,14 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, | |||
535 | goto out_elf_end; | 574 | goto out_elf_end; |
536 | 575 | ||
537 | gelf_getshdr(sec, &shdr); | 576 | gelf_getshdr(sec, &shdr); |
577 | |||
578 | if (is_label && !elf_sec__is_text(&shdr, secstrs)) | ||
579 | continue; | ||
580 | |||
581 | section_name = elf_sec__name(&shdr, secstrs); | ||
538 | obj_start = sym.st_value; | 582 | obj_start = sym.st_value; |
539 | 583 | ||
540 | if (self->prelinked) { | 584 | if (self->adjust_symbols) { |
541 | if (verbose >= 2) | 585 | if (verbose >= 2) |
542 | printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", | 586 | printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", |
543 | (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); | 587 | (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); |
@@ -545,6 +589,17 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, | |||
545 | sym.st_value -= shdr.sh_addr - shdr.sh_offset; | 589 | sym.st_value -= shdr.sh_addr - shdr.sh_offset; |
546 | } | 590 | } |
547 | 591 | ||
592 | if (mod) { | ||
593 | section = mod->sections->find_section(mod->sections, section_name); | ||
594 | if (section) | ||
595 | sym.st_value += section->vma; | ||
596 | else { | ||
597 | fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n", | ||
598 | mod->name, section_name); | ||
599 | goto out_elf_end; | ||
600 | } | ||
601 | } | ||
602 | |||
548 | f = symbol__new(sym.st_value, sym.st_size, | 603 | f = symbol__new(sym.st_value, sym.st_size, |
549 | elf_sym__name(&sym, symstrs), | 604 | elf_sym__name(&sym, symstrs), |
550 | self->sym_priv_size, obj_start, verbose); | 605 | self->sym_priv_size, obj_start, verbose); |
@@ -554,6 +609,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, | |||
554 | if (filter && filter(self, f)) | 609 | if (filter && filter(self, f)) |
555 | symbol__delete(f, self->sym_priv_size); | 610 | symbol__delete(f, self->sym_priv_size); |
556 | else { | 611 | else { |
612 | f->module = mod; | ||
557 | dso__insert_symbol(self, f); | 613 | dso__insert_symbol(self, f); |
558 | nr++; | 614 | nr++; |
559 | } | 615 | } |
@@ -577,7 +633,7 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose) | |||
577 | if (!name) | 633 | if (!name) |
578 | return -1; | 634 | return -1; |
579 | 635 | ||
580 | self->prelinked = 0; | 636 | self->adjust_symbols = 0; |
581 | 637 | ||
582 | if (strncmp(self->name, "/tmp/perf-", 10) == 0) | 638 | if (strncmp(self->name, "/tmp/perf-", 10) == 0) |
583 | return dso__load_perf_map(self, filter, verbose); | 639 | return dso__load_perf_map(self, filter, verbose); |
@@ -603,7 +659,7 @@ more: | |||
603 | fd = open(name, O_RDONLY); | 659 | fd = open(name, O_RDONLY); |
604 | } while (fd < 0); | 660 | } while (fd < 0); |
605 | 661 | ||
606 | ret = dso__load_sym(self, fd, name, filter, verbose); | 662 | ret = dso__load_sym(self, fd, name, filter, verbose, NULL); |
607 | close(fd); | 663 | close(fd); |
608 | 664 | ||
609 | /* | 665 | /* |
@@ -617,6 +673,86 @@ out: | |||
617 | return ret; | 673 | return ret; |
618 | } | 674 | } |
619 | 675 | ||
676 | static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name, | ||
677 | symbol_filter_t filter, int verbose) | ||
678 | { | ||
679 | struct module *mod = mod_dso__find_module(mods, name); | ||
680 | int err = 0, fd; | ||
681 | |||
682 | if (mod == NULL || !mod->active) | ||
683 | return err; | ||
684 | |||
685 | fd = open(mod->path, O_RDONLY); | ||
686 | |||
687 | if (fd < 0) | ||
688 | return err; | ||
689 | |||
690 | err = dso__load_sym(self, fd, name, filter, verbose, mod); | ||
691 | close(fd); | ||
692 | |||
693 | return err; | ||
694 | } | ||
695 | |||
696 | int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose) | ||
697 | { | ||
698 | struct mod_dso *mods = mod_dso__new_dso("modules"); | ||
699 | struct module *pos; | ||
700 | struct rb_node *next; | ||
701 | int err; | ||
702 | |||
703 | err = mod_dso__load_modules(mods); | ||
704 | |||
705 | if (err <= 0) | ||
706 | return err; | ||
707 | |||
708 | /* | ||
709 | * Iterate over modules, and load active symbols. | ||
710 | */ | ||
711 | next = rb_first(&mods->mods); | ||
712 | while (next) { | ||
713 | pos = rb_entry(next, struct module, rb_node); | ||
714 | err = dso__load_module(self, mods, pos->name, filter, verbose); | ||
715 | |||
716 | if (err < 0) | ||
717 | break; | ||
718 | |||
719 | next = rb_next(&pos->rb_node); | ||
720 | } | ||
721 | |||
722 | if (err < 0) { | ||
723 | mod_dso__delete_modules(mods); | ||
724 | mod_dso__delete_self(mods); | ||
725 | } | ||
726 | |||
727 | return err; | ||
728 | } | ||
729 | |||
730 | static inline void dso__fill_symbol_holes(struct dso *self) | ||
731 | { | ||
732 | struct symbol *prev = NULL; | ||
733 | struct rb_node *nd; | ||
734 | |||
735 | for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) { | ||
736 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); | ||
737 | |||
738 | if (prev) { | ||
739 | u64 hole = 0; | ||
740 | int alias = pos->start == prev->start; | ||
741 | |||
742 | if (!alias) | ||
743 | hole = prev->start - pos->end - 1; | ||
744 | |||
745 | if (hole || alias) { | ||
746 | if (alias) | ||
747 | pos->end = prev->end; | ||
748 | else if (hole) | ||
749 | pos->end = prev->start - 1; | ||
750 | } | ||
751 | } | ||
752 | prev = pos; | ||
753 | } | ||
754 | } | ||
755 | |||
620 | static int dso__load_vmlinux(struct dso *self, const char *vmlinux, | 756 | static int dso__load_vmlinux(struct dso *self, const char *vmlinux, |
621 | symbol_filter_t filter, int verbose) | 757 | symbol_filter_t filter, int verbose) |
622 | { | 758 | { |
@@ -625,21 +761,28 @@ static int dso__load_vmlinux(struct dso *self, const char *vmlinux, | |||
625 | if (fd < 0) | 761 | if (fd < 0) |
626 | return -1; | 762 | return -1; |
627 | 763 | ||
628 | err = dso__load_sym(self, fd, vmlinux, filter, verbose); | 764 | err = dso__load_sym(self, fd, vmlinux, filter, verbose, NULL); |
765 | |||
766 | if (err > 0) | ||
767 | dso__fill_symbol_holes(self); | ||
768 | |||
629 | close(fd); | 769 | close(fd); |
630 | 770 | ||
631 | return err; | 771 | return err; |
632 | } | 772 | } |
633 | 773 | ||
634 | int dso__load_kernel(struct dso *self, const char *vmlinux, | 774 | int dso__load_kernel(struct dso *self, const char *vmlinux, |
635 | symbol_filter_t filter, int verbose) | 775 | symbol_filter_t filter, int verbose, int modules) |
636 | { | 776 | { |
637 | int err = -1; | 777 | int err = -1; |
638 | 778 | ||
639 | if (vmlinux) | 779 | if (vmlinux) { |
640 | err = dso__load_vmlinux(self, vmlinux, filter, verbose); | 780 | err = dso__load_vmlinux(self, vmlinux, filter, verbose); |
781 | if (err > 0 && modules) | ||
782 | err = dso__load_modules(self, filter, verbose); | ||
783 | } | ||
641 | 784 | ||
642 | if (err < 0) | 785 | if (err <= 0) |
643 | err = dso__load_kallsyms(self, filter, verbose); | 786 | err = dso__load_kallsyms(self, filter, verbose); |
644 | 787 | ||
645 | return err; | 788 | return err; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2c48ace8203b..7918cffb23cd 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -3,8 +3,9 @@ | |||
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include "types.h" | 5 | #include "types.h" |
6 | #include "list.h" | 6 | #include <linux/list.h> |
7 | #include "rbtree.h" | 7 | #include <linux/rbtree.h> |
8 | #include "module.h" | ||
8 | 9 | ||
9 | struct symbol { | 10 | struct symbol { |
10 | struct rb_node rb_node; | 11 | struct rb_node rb_node; |
@@ -13,6 +14,7 @@ struct symbol { | |||
13 | u64 obj_start; | 14 | u64 obj_start; |
14 | u64 hist_sum; | 15 | u64 hist_sum; |
15 | u64 *hist; | 16 | u64 *hist; |
17 | struct module *module; | ||
16 | void *priv; | 18 | void *priv; |
17 | char name[0]; | 19 | char name[0]; |
18 | }; | 20 | }; |
@@ -22,7 +24,7 @@ struct dso { | |||
22 | struct rb_root syms; | 24 | struct rb_root syms; |
23 | struct symbol *(*find_symbol)(struct dso *, u64 ip); | 25 | struct symbol *(*find_symbol)(struct dso *, u64 ip); |
24 | unsigned int sym_priv_size; | 26 | unsigned int sym_priv_size; |
25 | unsigned char prelinked; | 27 | unsigned char adjust_symbols; |
26 | char name[0]; | 28 | char name[0]; |
27 | }; | 29 | }; |
28 | 30 | ||
@@ -41,7 +43,8 @@ static inline void *dso__sym_priv(struct dso *self, struct symbol *sym) | |||
41 | struct symbol *dso__find_symbol(struct dso *self, u64 ip); | 43 | struct symbol *dso__find_symbol(struct dso *self, u64 ip); |
42 | 44 | ||
43 | int dso__load_kernel(struct dso *self, const char *vmlinux, | 45 | int dso__load_kernel(struct dso *self, const char *vmlinux, |
44 | symbol_filter_t filter, int verbose); | 46 | symbol_filter_t filter, int verbose, int modules); |
47 | int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose); | ||
45 | int dso__load(struct dso *self, symbol_filter_t filter, int verbose); | 48 | int dso__load(struct dso *self, symbol_filter_t filter, int verbose); |
46 | 49 | ||
47 | size_t dso__fprintf(struct dso *self, FILE *fp); | 50 | size_t dso__fprintf(struct dso *self, FILE *fp); |
diff --git a/tools/perf/util/wrapper.c b/tools/perf/util/wrapper.c index 6350d65f6d9e..4574ac28396f 100644 --- a/tools/perf/util/wrapper.c +++ b/tools/perf/util/wrapper.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * There's no pack memory to release - but stay close to the Git | 7 | * There's no pack memory to release - but stay close to the Git |
8 | * version so wrap this away: | 8 | * version so wrap this away: |
9 | */ | 9 | */ |
10 | static inline void release_pack_memory(size_t size, int flag) | 10 | static inline void release_pack_memory(size_t size __used, int flag __used) |
11 | { | 11 | { |
12 | } | 12 | } |
13 | 13 | ||
@@ -59,7 +59,8 @@ void *xmemdupz(const void *data, size_t len) | |||
59 | char *xstrndup(const char *str, size_t len) | 59 | char *xstrndup(const char *str, size_t len) |
60 | { | 60 | { |
61 | char *p = memchr(str, '\0', len); | 61 | char *p = memchr(str, '\0', len); |
62 | return xmemdupz(str, p ? p - str : len); | 62 | |
63 | return xmemdupz(str, p ? (size_t)(p - str) : len); | ||
63 | } | 64 | } |
64 | 65 | ||
65 | void *xrealloc(void *ptr, size_t size) | 66 | void *xrealloc(void *ptr, size_t size) |